Skip to content

Implement "static" feature flag for FTD2XX static linking. #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ jobs:
with:
toolchain: stable
target: ${{ matrix.target }}
- run: cargo test --target ${{ matrix.target }}
- run: cargo test --features=static --target ${{ matrix.target }}

windows_test:
name: Windows Unit Tests
Expand Down
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,8 @@ bindgen = { version = "~0.57.0", optional = true }
[dev-dependencies]
version-sync = "~0.9.1"

[features]
static = []

[badges]
maintenance = { status = "passively-maintained" }
47 changes: 35 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ the unsafe C bindings.
## Usage
Simply add this crate as a dependency in your `Cargo.toml`.
The static library is distributed in this crate with permission from FTDI.
The default feature set will use dynamic linking.

```toml
[dependencies]
libftd2xx-ffi = "~0.6.0"
```

### Bindgen
The default feature set will use pre-generated bindings.
This is only available for Windows x86_64 and Linux x86_64 platforms.

Expand All @@ -33,28 +35,49 @@ libftd2xx-ffi = { version = "~0.6.0", features = ["bindgen"] }
Bindgen has additional dependencies that must be installed in order to
compile successfully, see the [bindgen requirements] page for more details.

### Static Linking
Static linking the FTD2XX library into this crate can be done by using
the ["static"] feature flag.
```toml
[dependencies]
libftd2xx-ffi = { version = "~0.6.0", features = ["static"] }
```
For GNU/Linux users, no further work is needed. Technically this may be preferred.
However there may be license incompatibilities (static linking with GPL code).
If in doubt, check the FTDI driver license terms.

On Windows, we rely on MSVC and a manually set the "LIBMSVC_PATH" environment variable.
For example a possible 2019 Community installation path may be:
```
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\lib\
```
This brings in legacy_stdio_definitions.lib and user32.lib. It seems to play nicely with rust,
but you may end up with multiple defined symbol errors if using this crate as a c/c++ dependency.

## Supported Targets

### Tested Targets

* `x86_64-pc-windows-msvc` (dynamic linking only)
* `x86_64-unknown-linux-gnu` (static linking only)
* `x86_64-unknown-linux-musl` (static linking only)
* `i686-pc-windows-msvc` (dynamic + static)
* `i686-unknown-linux-gnu` (dynamic + static)
* `i686-unknown-linux-musl` (static)
* `x86_64-pc-windows-msvc` (dynamic + static)
* `x86_64-unknown-linux-gnu` (dynamic + static)
* `x86_64-unknown-linux-musl` (static)

### Untested Targets

These targets are provided, but they are untested.
Use at your own risk.

* `aarch64-unknown-linux-gnu` (static linking only)
* `aarch64-unknown-linux-musl` (static linking only)
* `arm-unknown-linux-gnueabihf` (static linking only)
* `arm-unknown-linux-musleabihf` (static linking only)
* `armv7-unknown-linux-gnueabihf` (static linking only)
* `armv7-unknown-linux-musleabihf` (static linking only)
* `i686-pc-windows-msvc` (dynamic linking only)
* `i686-unknown-linux-gnu` (static linking only)
* `i686-unknown-linux-musl` (static linking only)
* `aarch64-unknown-linux-gnu` (dynamic + static)
* `aarch64-unknown-linux-musl` (dynamic + static)
* `arm-unknown-linux-gnueabihf` (dynamic + static)
* `arm-unknown-linux-musleabihf` (dynamic + static)
* `armv7-unknown-linux-gnueabihf` (dynamic + static)
* `armv7-unknown-linux-musleabihf` (dynamic + static)
* `i686-unknown-linux-musl` (dynamic)
* `x86_64-unknown-linux-musl` (dynamic)

## References

Expand Down
56 changes: 53 additions & 3 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,26 @@ use std::env;
fn search_path<'a>() -> &'a str {
match env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() {
"windows" => match env::var("CARGO_CFG_TARGET_ARCH").unwrap().as_str() {
"x86_64" => "vendor/windows/amd64",
"x86" => "vendor/windows/i386",
"x86_64" => {
#[cfg(not(feature = "static"))]
{
"vendor\\windows\\amd64"
}
#[cfg(feature = "static")]
{
"vendor\\windows\\Static\\amd64"
}
}
"x86" => {
#[cfg(not(feature = "static"))]
{
"vendor\\windows\\i386"
}
#[cfg(feature = "static")]
{
"vendor\\windows\\Static\\i386"
}
}
target_arch => panic!("Target architecture not supported: {}", target_arch),
},
"linux" => match env::var("CARGO_CFG_TARGET_ARCH").unwrap().as_str() {
Expand Down Expand Up @@ -66,6 +84,36 @@ fn clang_args() -> &'static [&'static str] {
}
}

#[cfg(not(feature = "static"))]
fn linker_options() {
println!("cargo:rustc-link-lib=dylib=ftd2xx");
}

#[cfg(feature = "static")]
fn linker_options() {
println!("cargo:rustc-link-lib=static=ftd2xx");

match env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() {
"windows" => {
let libmsvc_path = if let Some(libmsvc_path) = env::var_os("LIBMSVC_PATH") {
match env::var("CARGO_CFG_TARGET_ARCH").unwrap().as_str() {
"x86_64" => format!("{}{}", libmsvc_path.into_string().unwrap(), "\\x64"),
"x86" => format!("{}{}", libmsvc_path.into_string().unwrap(), "\\x64"),
target_arch => panic!("Target architecture not supported: {}", target_arch),
}
} else {
panic!("LIBMSVC_PATH environment variable not found.");
};

println!("cargo:rustc-link-search=native={}", libmsvc_path);
println!("cargo:rustc-link-lib=static=legacy_stdio_definitions");
println!("cargo:rustc-link-lib=user32");
}
"linux" => {}
target_os => panic!("Target OS not supported: {}", target_os),
}
}

fn main() {
let cwd = env::current_dir().unwrap();
let mut header = cwd.clone();
Expand All @@ -77,8 +125,10 @@ fn main() {
"cargo:rustc-link-search=native={}",
search.to_str().unwrap()
);
println!("cargo:rustc-link-lib=static=ftd2xx");
linker_options();

println!("cargo:rerun-if-changed={}", header.to_str().unwrap());
println!("cargo:rerun-if-env-changed=LIBMSVC_PATH");

#[cfg(feature = "bindgen")]
{
Expand Down
4 changes: 2 additions & 2 deletions tests/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use libftd2xx_ffi::FT_GetLibraryVersion;

#[test]
#[cfg(not(windows))]
fn version() {
use libftd2xx_ffi::FT_GetLibraryVersion;

let mut dw_library_ver = 0;

let ft_status = unsafe { FT_GetLibraryVersion(&mut dw_library_ver) };
Expand Down