Skip to content

Commit 45e99b6

Browse files
committed
Implement "static" feature flag for FTD2XX static linking.
This sets the default configuration to dynamically link with FTD2XX on all platforms.
1 parent dc87889 commit 45e99b6

File tree

5 files changed

+94
-18
lines changed

5 files changed

+94
-18
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ jobs:
8585
with:
8686
toolchain: stable
8787
target: ${{ matrix.target }}
88-
- run: cargo test --target ${{ matrix.target }}
88+
- run: cargo test --features=static --target ${{ matrix.target }}
8989

9090
windows_test:
9191
name: Windows Unit Tests

Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,8 @@ bindgen = { version = "~0.57.0", optional = true }
2828
[dev-dependencies]
2929
version-sync = "~0.9.1"
3030

31+
[features]
32+
static = []
33+
3134
[badges]
3235
maintenance = { status = "passively-maintained" }

README.md

+35-12
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ the unsafe C bindings.
1414
## Usage
1515
Simply add this crate as a dependency in your `Cargo.toml`.
1616
The static library is distributed in this crate with permission from FTDI.
17+
The default feature set will use dynamic linking.
1718

1819
```toml
1920
[dependencies]
2021
libftd2xx-ffi = "~0.5.1"
2122
```
2223

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

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

38+
### Static Linking
39+
Static linking the FTD2XX library into this crate can be done by using
40+
the ["static"] feature flag.
41+
```toml
42+
[dependencies]
43+
libftd2xx-ffi = { version = "~0.5.1", features = ["static"] }
44+
```
45+
For GNU/Linux users, no further work is needed. Technically this may be preferred.
46+
However there may be license incompatibilities (static linking with GPL code).
47+
If in doubt, check the FTDI driver license terms.
48+
49+
On Windows, we rely on MSVC and a manually set the "LIBMSVC_PATH" environment variable.
50+
For example a possible 2019 Community installation path may be:
51+
```
52+
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\lib\
53+
```
54+
This brings in legacy_stdio_definitions.lib and user32.lib. It seems to play nicely with rust,
55+
but you may end up with multiple defined symbol errors if using this crate as a c/c++ dependency.
56+
3657
## Supported Targets
3758

3859
### Tested Targets
3960

40-
* `x86_64-pc-windows-msvc` (dynamic linking only)
41-
* `x86_64-unknown-linux-gnu` (static linking only)
42-
* `x86_64-unknown-linux-musl` (static linking only)
61+
* `i686-pc-windows-msvc` (dynamic + static)
62+
* `i686-unknown-linux-gnu` (dynamic + static)
63+
* `i686-unknown-linux-musl` (static)
64+
* `x86_64-pc-windows-msvc` (dynamic + static)
65+
* `x86_64-unknown-linux-gnu` (dynamic + static)
66+
* `x86_64-unknown-linux-musl` (static)
4367

4468
### Untested Targets
4569

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

49-
* `aarch64-unknown-linux-gnu` (static linking only)
50-
* `aarch64-unknown-linux-musl` (static linking only)
51-
* `arm-unknown-linux-gnueabihf` (static linking only)
52-
* `arm-unknown-linux-musleabihf` (static linking only)
53-
* `armv7-unknown-linux-gnueabihf` (static linking only)
54-
* `armv7-unknown-linux-musleabihf` (static linking only)
55-
* `i686-pc-windows-msvc` (dynamic linking only)
56-
* `i686-unknown-linux-gnu` (static linking only)
57-
* `i686-unknown-linux-musl` (static linking only)
73+
* `aarch64-unknown-linux-gnu` (dynamic + static)
74+
* `aarch64-unknown-linux-musl` (dynamic + static)
75+
* `arm-unknown-linux-gnueabihf` (dynamic + static)
76+
* `arm-unknown-linux-musleabihf` (dynamic + static)
77+
* `armv7-unknown-linux-gnueabihf` (dynamic + static)
78+
* `armv7-unknown-linux-musleabihf` (dynamic + static)
79+
* `i686-unknown-linux-musl` (dynamic)
80+
* `x86_64-unknown-linux-musl` (dynamic)
5881

5982
## References
6083

build.rs

+53-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,26 @@ use std::env;
33
fn search_path<'a>() -> &'a str {
44
match env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() {
55
"windows" => match env::var("CARGO_CFG_TARGET_ARCH").unwrap().as_str() {
6-
"x86_64" => "vendor/windows/amd64",
7-
"x86" => "vendor/windows/i386",
6+
"x86_64" => {
7+
#[cfg(not(feature = "static"))]
8+
{
9+
"vendor\\windows\\amd64"
10+
}
11+
#[cfg(feature = "static")]
12+
{
13+
"vendor\\windows\\Static\\amd64"
14+
}
15+
}
16+
"x86" => {
17+
#[cfg(not(feature = "static"))]
18+
{
19+
"vendor\\windows\\i386"
20+
}
21+
#[cfg(feature = "static")]
22+
{
23+
"vendor\\windows\\Static\\i386"
24+
}
25+
}
826
target_arch => panic!("Target architecture not supported: {}", target_arch),
927
},
1028
"linux" => match env::var("CARGO_CFG_TARGET_ARCH").unwrap().as_str() {
@@ -66,6 +84,36 @@ fn clang_args() -> &'static [&'static str] {
6684
}
6785
}
6886

87+
#[cfg(not(feature = "static"))]
88+
fn linker_options() {
89+
println!("cargo:rustc-link-lib=dylib=ftd2xx");
90+
}
91+
92+
#[cfg(feature = "static")]
93+
fn linker_options() {
94+
println!("cargo:rustc-link-lib=static=ftd2xx");
95+
96+
match env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() {
97+
"windows" => {
98+
let libmsvc_path = if let Some(libmsvc_path) = env::var_os("LIBMSVC_PATH") {
99+
match env::var("CARGO_CFG_TARGET_ARCH").unwrap().as_str() {
100+
"x86_64" => format!("{}{}", libmsvc_path.into_string().unwrap(), "\\x64"),
101+
"x86" => format!("{}{}", libmsvc_path.into_string().unwrap(), "\\x64"),
102+
target_arch => panic!("Target architecture not supported: {}", target_arch),
103+
}
104+
} else {
105+
panic!("LIBMSVC_PATH environment variable not found.");
106+
};
107+
108+
println!("cargo:rustc-link-search=native={}", libmsvc_path);
109+
println!("cargo:rustc-link-lib=static=legacy_stdio_definitions");
110+
println!("cargo:rustc-link-lib=user32");
111+
}
112+
"linux" => {}
113+
target_os => panic!("Target OS not supported: {}", target_os),
114+
}
115+
}
116+
69117
fn main() {
70118
let cwd = env::current_dir().unwrap();
71119
let mut header = cwd.clone();
@@ -77,8 +125,10 @@ fn main() {
77125
"cargo:rustc-link-search=native={}",
78126
search.to_str().unwrap()
79127
);
80-
println!("cargo:rustc-link-lib=static=ftd2xx");
128+
linker_options();
129+
81130
println!("cargo:rerun-if-changed={}", header.to_str().unwrap());
131+
println!("cargo:rerun-if-env-changed=LIBMSVC_PATH");
82132

83133
#[cfg(feature = "bindgen")]
84134
{

tests/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use libftd2xx_ffi::FT_GetLibraryVersion;
2-
31
#[test]
42
#[cfg(not(windows))]
53
fn version() {
4+
use libftd2xx_ffi::FT_GetLibraryVersion;
5+
66
let mut dw_library_ver = 0;
77

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

0 commit comments

Comments
 (0)