Skip to content

Commit 152b1eb

Browse files
GrinkersnewAM
authored andcommitted
Implement "static" feature flag for FTD2XX static linking.
This sets the default configuration to dynamically link with FTD2XX on all platforms.
1 parent e16ef04 commit 152b1eb

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.6.0"
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.6.0", 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.6.0", 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)