-
Notifications
You must be signed in to change notification settings - Fork 124
feat: add linker args for VHF lib to wdk-build #653
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
base: main
Are you sure you want to change the base?
Changes from 10 commits
294c27e
b194380
cfae425
70305e3
4427c85
7fc834a
74ebe7c
6bdb8e3
8ff9e5b
0d8fe7f
18d42f3
55a63a1
d22d9db
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,7 @@ mod bindgen; | |
|
|
||
| use cargo_metadata::MetadataCommand; | ||
| use serde::{Deserialize, Serialize}; | ||
| use serde_json::{Value, from_value}; | ||
| use thiserror::Error; | ||
|
|
||
| use crate::utils::detect_windows_sdk_version; | ||
|
|
@@ -45,6 +46,9 @@ pub struct Config { | |
| cpu_architecture: CpuArchitecture, | ||
| /// Build configuration of driver | ||
| pub driver_config: DriverConfig, | ||
| /// List of features enabled for `wdk-sys` in resolved dependency graph | ||
|
|
||
| #[serde(default)] | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Drop
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good and done! I didn't think about what could be implied (the backwards-compat invariant) by adding that attribute. |
||
| enabled_api_subsets: Vec<ApiSubset>, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done! |
||
| } | ||
|
|
||
| /// The driver type with its associated configuration parameters | ||
|
|
@@ -316,7 +320,8 @@ rustflags = [\"-C\", \"target-feature=+crt-static\"] | |
| } | ||
|
|
||
| /// Subset of APIs in the Windows Driver Kit | ||
| #[derive(Debug, Copy, Clone, PartialEq, Eq)] | ||
| #[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] | ||
| #[serde(rename_all = "kebab-case")] | ||
| pub enum ApiSubset { | ||
| /// API subset typically required for all Windows drivers | ||
| Base, | ||
|
|
@@ -397,6 +402,7 @@ impl Default for Config { | |
| ), | ||
| driver_config: DriverConfig::Wdm, | ||
| cpu_architecture: utils::detect_cpu_architecture_in_build_script(), | ||
| enabled_api_subsets: Vec::new(), | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -447,6 +453,37 @@ impl Config { | |
| .exec()?; | ||
| let wdk_metadata = metadata::Wdk::try_from(&cargo_metadata)?; | ||
|
|
||
| // Find the `wdk-sys` package's PackageId in `cargo_metadata` | ||
| let wdk_sys_package_id = cargo_metadata | ||
| .packages | ||
| .iter() | ||
| .find(|pkg| pkg.name == "wdk-sys") | ||
| .map(|pkg| &pkg.id); | ||
| // Extract the features enabled for `wdk-sys` | ||
| // Produces an empty Vec if `wdk-sys` is not found in the dependency graph | ||
| let wdk_sys_enabled_features = wdk_sys_package_id | ||
|
Alan632 marked this conversation as resolved.
Outdated
|
||
| .and_then(|id| { | ||
| cargo_metadata | ||
| .resolve | ||
| .as_ref() | ||
| .and_then(|resolve| resolve.nodes.iter().find(|node| node.id == *id)) | ||
| }) | ||
| .map_or_else( | ||
| || { | ||
| tracing::warn!( | ||
| "Could not detect wdk-sys features from cargo metadata resolve. \ | ||
| Feature-dependent libraries will not be linked automatically." | ||
| ); | ||
| Vec::new() | ||
| }, | ||
| |node| { | ||
| node.features | ||
| .iter() | ||
| .filter_map(|f| from_value::<ApiSubset>(Value::String(f.clone())).ok()) | ||
| .collect() | ||
| }, | ||
| ); | ||
|
Alan632 marked this conversation as resolved.
Outdated
Alan632 marked this conversation as resolved.
Outdated
|
||
|
|
||
| // Force rebuilds if any of the manifest files change (ex. if wdk metadata | ||
| // section is modified) | ||
| for manifest_path in metadata::iter_manifest_paths(cargo_metadata) | ||
|
|
@@ -462,6 +499,7 @@ impl Config { | |
|
|
||
| Ok(Self { | ||
| driver_config: wdk_metadata.driver_model, | ||
| enabled_api_subsets: wdk_sys_enabled_features, | ||
| ..Default::default() | ||
| }) | ||
| } | ||
|
|
@@ -1157,6 +1195,17 @@ impl Config { | |
| // provides no way to set a symbol's name without also exporting the symbol: | ||
| // https://github.com/rust-lang/rust/issues/67399 | ||
| println!("cargo::rustc-cdylib-link-arg=/IGNORE:4216"); | ||
|
|
||
| // Link against VhfKm.lib (Virtual HID Framework, kernel-mode) when | ||
| // the "hid" feature is enabled in wdk-sys. Required by drivers that | ||
| // create virtual HID devices. | ||
| if self | ||
| .enabled_api_subsets | ||
| .iter() | ||
| .any(|f| f == &ApiSubset::Hid) | ||
| { | ||
|
Alan632 marked this conversation as resolved.
Outdated
|
||
| println!("cargo::rustc-cdylib-link-arg=VhfKm.lib"); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Extended current config unit tests.
Comment on lines
+1222
to
+1226
|
||
| } | ||
| } | ||
| DriverConfig::Kmdf(_) => { | ||
| // Emit KMDF-specific libraries to link to | ||
|
|
@@ -1186,6 +1235,17 @@ impl Config { | |
| // Ignore `LNK4257: object file was not compiled for kernel mode; the image | ||
| // might not run` since `rustc` has no support for `/KERNEL` | ||
| println!("cargo::rustc-cdylib-link-arg=/IGNORE:4257"); | ||
|
|
||
| // Link against VhfKm.lib (Virtual HID Framework, kernel-mode) when | ||
| // the "hid" feature is enabled in wdk-sys. Required by drivers that | ||
| // create virtual HID devices. | ||
| if self | ||
| .enabled_api_subsets | ||
| .iter() | ||
| .any(|f| f == &ApiSubset::Hid) | ||
| { | ||
| println!("cargo::rustc-cdylib-link-arg=VhfKm.lib"); | ||
|
Alan632 marked this conversation as resolved.
Outdated
Comment on lines
+1258
to
+1262
|
||
| } | ||
|
Alan632 marked this conversation as resolved.
|
||
| } | ||
| DriverConfig::Umdf(umdf_config) => { | ||
| // Emit UMDF-specific libraries to link to | ||
|
|
@@ -1200,6 +1260,17 @@ impl Config { | |
|
|
||
| // Linker arguments derived from WindowsDriver.UserMode.props in Ni(22H2) WDK | ||
| println!("cargo::rustc-cdylib-link-arg=/SUBSYSTEM:WINDOWS"); | ||
|
|
||
| // Link against VhfUm.lib (Virtual HID Framework, user-mode) when | ||
| // the "hid" feature is enabled in wdk-sys. Required by drivers that | ||
| // create virtual HID devices. | ||
| if self | ||
| .enabled_api_subsets | ||
| .iter() | ||
| .any(|f| f == &ApiSubset::Hid) | ||
| { | ||
|
Alan632 marked this conversation as resolved.
Outdated
|
||
| println!("cargo::rustc-cdylib-link-arg=VhfUm.lib"); | ||
|
Comment on lines
+1279
to
+1283
|
||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -1826,18 +1897,32 @@ mod tests { | |
| #[cfg(assert_matches_stabilized)] | ||
| assert_matches!(config.driver_config, DriverConfig::Wdm); | ||
| assert_eq!(config.cpu_architecture, CpuArchitecture::Amd64); | ||
| assert!(config.enabled_api_subsets.is_empty()); | ||
| } | ||
|
|
||
| #[test] | ||
| fn wdm_config() { | ||
| let config = with_env(&[("CARGO_CFG_TARGET_ARCH", Some("x86_64"))], || Config { | ||
| driver_config: DriverConfig::Wdm, | ||
| enabled_api_subsets: vec![ApiSubset::Hid], | ||
| ..Config::default() | ||
| }); | ||
|
|
||
| #[cfg(assert_matches_stabilized)] | ||
| assert_matches!(config.driver_config, DriverConfig::Wdm); | ||
| assert_eq!(config.cpu_architecture, CpuArchitecture::Amd64); | ||
| assert!( | ||
| config | ||
| .enabled_api_subsets | ||
| .iter() | ||
| .any(|f| f == &ApiSubset::Hid) | ||
| ); | ||
| assert!( | ||
| !config | ||
| .enabled_api_subsets | ||
| .iter() | ||
| .any(|f| f == &ApiSubset::Gpio) | ||
| ); | ||
|
Alan632 marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| #[test] | ||
|
|
@@ -1867,6 +1952,7 @@ mod tests { | |
| target_kmdf_version_minor: 15, | ||
| minimum_kmdf_version_minor: None, | ||
| }), | ||
| enabled_api_subsets: vec![ApiSubset::Hid, ApiSubset::Gpio], | ||
| ..Config::default() | ||
| }); | ||
|
|
||
|
|
@@ -1880,6 +1966,18 @@ mod tests { | |
| }) | ||
| ); | ||
| assert_eq!(config.cpu_architecture, CpuArchitecture::Amd64); | ||
| assert!( | ||
| config | ||
| .enabled_api_subsets | ||
| .iter() | ||
| .any(|f| f == &ApiSubset::Hid) | ||
| ); | ||
| assert!( | ||
| config | ||
| .enabled_api_subsets | ||
| .iter() | ||
| .any(|f| f == &ApiSubset::Gpio) | ||
| ); | ||
| } | ||
|
|
||
| #[test] | ||
|
|
@@ -1909,6 +2007,7 @@ mod tests { | |
| target_umdf_version_minor: 15, | ||
| minimum_umdf_version_minor: None, | ||
| }), | ||
| enabled_api_subsets: vec![ApiSubset::Usb], | ||
| ..Config::default() | ||
| }); | ||
|
|
||
|
|
@@ -1922,6 +2021,18 @@ mod tests { | |
| }) | ||
| ); | ||
| assert_eq!(config.cpu_architecture, CpuArchitecture::Arm64); | ||
| assert!( | ||
| !config | ||
| .enabled_api_subsets | ||
| .iter() | ||
| .any(|f| f == &ApiSubset::Hid) | ||
| ); | ||
| assert!( | ||
| config | ||
| .enabled_api_subsets | ||
| .iter() | ||
| .any(|f| f == &ApiSubset::Usb) | ||
| ); | ||
| } | ||
|
|
||
| #[test] | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.