Skip to content
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

feat: package rust-driver-makefile.toml with wdk-build package #36

Merged
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
42 changes: 42 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Makefile.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
extend = "./rust-driver-makefile.toml"
extend = "./crates/wdk-build/rust-driver-makefile.toml"

[config]
additional_profiles = ["all-default-tasks"]
Expand Down
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,22 +127,23 @@ The crates in this repository are available from [`crates.io`](https://crates.io
```

11. Add a `Makefile.toml`:

```toml
extend = ".cargo-make-loadscripts/rust-driver-makefile.toml"
extend = "target/rust-driver-makefile.toml"

[env]
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true

[config]
load_script = """
pwsh.exe -Command "\
if ($env:CARGO_MAKE_CRATE_IS_WORKSPACE) { return };\
$cargoMakeURI = 'https://raw.githubusercontent.com/microsoft/windows-drivers-rs/main/rust-driver-makefile.toml';\
New-Item -ItemType Directory .cargo-make-loadscripts -Force;\
Invoke-RestMethod -Method GET -Uri $CargoMakeURI -OutFile $env:CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY/.cargo-make-loadscripts/rust-driver-makefile.toml\
"
"""
load_script = '''
#!@rust
//! ```cargo
//! [dependencies]
//! wdk-build = "0.1.0"
//! ```
#![allow(unused_doc_comments)]
wdk_build::cargo_make::load_rust_driver_makefile()?
'''
```

12. Add an inx file that matches the name of your `cdylib` crate.
Expand Down
2 changes: 1 addition & 1 deletion crates/sample-kmdf-driver/Makefile.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
extend = "../../rust-driver-makefile.toml"
extend = "../wdk-build/rust-driver-makefile.toml"

[env]
WDK_BUILD_ADDITIONAL_INFVERIF_FLAGS = "/msft"
1 change: 1 addition & 0 deletions crates/wdk-build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ windows = { version = "0.52.0", features = [
"Win32_Foundation",
"Win32_System_Registry",
] }
cargo_metadata = "0.18.1"

[build-dependencies]
rustversion = "1.0.14"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ script_runner = "@rust"
script = '''
//! ```cargo
//! [dependencies]
//! wdk-build = { path = "./crates/wdk-build", version = "0.1.0" }
//! wdk-build = { path = ".", version = "0.1.0" }
//! ```
#![allow(unused_doc_comments)]
Expand All @@ -92,7 +92,7 @@ script_runner_args = [
script = '''
//! ```cargo
//! [dependencies]
//! wdk-build = { path = "./crates/wdk-build", version = "0.1.0" }
//! wdk-build = { path = ".", version = "0.1.0" }
//! ```
#![allow(unused_doc_comments)]
Expand Down Expand Up @@ -137,7 +137,7 @@ script_runner_args = [
script = '''
//! ```cargo
//! [dependencies]
//! wdk-build = { path = "./crates/wdk-build", version = "0.1.0" }
//! wdk-build = { path = ".", version = "0.1.0" }
//! ```
#![allow(unused_doc_comments)]
Expand Down Expand Up @@ -199,7 +199,7 @@ script_runner_args = [
script = '''
//! ```cargo
//! [dependencies]
//! wdk-build = { path = "./crates/wdk-build", version = "0.1.0" }
//! wdk-build = { path = ".", version = "0.1.0" }
//! ```
#![allow(unused_doc_comments)]
Expand All @@ -222,7 +222,7 @@ script_runner_args = [
script = '''
//! ```cargo
//! [dependencies]
//! wdk-build = { path = "./crates/wdk-build", version = "0.1.0" }
//! wdk-build = { path = ".", version = "0.1.0" }
//! ```
#![allow(unused_doc_comments)]
Expand All @@ -245,7 +245,7 @@ script_runner_args = [
script = '''
//! ```cargo
//! [dependencies]
//! wdk-build = { path = "./crates/wdk-build", version = "0.1.0" }
//! wdk-build = { path = ".", version = "0.1.0" }
//! ```
#![allow(unused_doc_comments)]
Expand All @@ -268,7 +268,7 @@ script_runner_args = [
script = '''
//! ```cargo
//! [dependencies]
//! wdk-build = { path = "./crates/wdk-build", version = "0.1.0" }
//! wdk-build = { path = ".", version = "0.1.0" }
//! ```
#![allow(unused_doc_comments)]
Expand Down Expand Up @@ -330,7 +330,7 @@ script_runner_args = [
script = '''
//! ```cargo
//! [dependencies]
//! wdk-build = { path = "./crates/wdk-build", version = "0.1.0" }
//! wdk-build = { path = ".", version = "0.1.0" }
//! ```
#![allow(unused_doc_comments)]
Expand Down
74 changes: 74 additions & 0 deletions crates/wdk-build/src/cargo_make.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use std::path::{Path, PathBuf};

use cargo_metadata::MetadataCommand;
use clap::{Args, Parser};

use crate::{
Expand All @@ -30,6 +31,8 @@ const CARGO_MAKE_CRATE_CUSTOM_TRIPLE_TARGET_DIRECTORY_ENV_VAR: &str =
"CARGO_MAKE_CRATE_CUSTOM_TRIPLE_TARGET_DIRECTORY";
const CARGO_MAKE_RUST_DEFAULT_TOOLCHAIN_ENV_VAR: &str = "CARGO_MAKE_RUST_DEFAULT_TOOLCHAIN";
const CARGO_MAKE_CRATE_FS_NAME_ENV_VAR: &str = "CARGO_MAKE_CRATE_FS_NAME";
const CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY_ENV_VAR: &str =
"CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY";
const WDK_BUILD_OUTPUT_DIRECTORY_ENV_VAR: &str = "WDK_BUILD_OUTPUT_DIRECTORY";

/// `clap` uses an exit code of 2 for usage errors: <https://github.com/clap-rs/clap/blob/14fd853fb9c5b94e371170bbd0ca2bf28ef3abff/clap_builder/src/util/mod.rs#L30C18-L30C28>
Expand Down Expand Up @@ -550,6 +553,77 @@ pub fn copy_to_driver_package_folder<P: AsRef<Path>>(path_to_copy: P) -> Result<
Ok(())
}

/// Symlinks `rust-driver-toolchain.toml` to the `target` folder where it can be
/// extended from a `Makefile.toml`. This is necessary so that paths in the
/// `rust-driver-toolchain.toml` can to be relative to
/// `CARGO_MAKE_CURRENT_TASK_INITIAL_MAKEFILE_DIRECTORY`
///
/// # Errors
///
/// This function returns:
/// - [`ConfigError::CargoMetadataError`] if there is an error executing or
/// parsing `cargo_metadata`
/// - [`ConfigError::MultipleWDKBuildCratesDetected`] if there are multiple
/// versions of the WDK build crate detected
/// - [`ConfigError::IoError`] if there is an error creating or updating the
/// symlink to `rust-driver-toolchain.toml`
///
/// # Panics
///
/// This function will panic if the `CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY`
/// environment variable is not set
pub fn load_rust_driver_makefile() -> Result<(), ConfigError> {
let cargo_metadata = MetadataCommand::new().exec()?;

let wdk_build_package_matches = cargo_metadata
.packages
.into_iter()
.filter(|package| package.name == "wdk-build")
.collect::<Vec<_>>();
if wdk_build_package_matches.len() != 1 {
return Err(ConfigError::MultipleWDKBuildCratesDetected {
package_ids: wdk_build_package_matches
.iter()
.map(|package_info| package_info.id.clone())
.collect(),
});
}

let rust_driver_makefile_toml_path = wdk_build_package_matches[0]
.manifest_path
.parent()
.expect("The parsed manifest_path should have a valid parent directory")
.join("rust-driver-makefile.toml");

let cargo_make_workspace_working_directory =
std::env::var(CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY_ENV_VAR).unwrap_or_else(|_| {
panic!("{CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY_ENV_VAR} should be set by cargo-make.")
});

let destination_path =
Path::new(&cargo_make_workspace_working_directory).join("target/rust-driver-makefile.toml");

// Only create a new symlink if the existing one is not already pointing to the
// correct file
if !destination_path.exists() {
return Ok(std::os::windows::fs::symlink_file(
rust_driver_makefile_toml_path,
destination_path,
)?);
} else if !destination_path.is_symlink()
|| std::fs::read_link(&destination_path)? != rust_driver_makefile_toml_path
{
std::fs::remove_file(&destination_path)?;
return Ok(std::os::windows::fs::symlink_file(
rust_driver_makefile_toml_path,
destination_path,
)?);
}

// Symlink is already up to date
Ok(())
}

fn configure_wdf_build_output_dir(target_arg: &Option<String>, cargo_make_cargo_profile: &str) {
let cargo_make_crate_custom_triple_target_directory = std::env::var(
CARGO_MAKE_CRATE_CUSTOM_TRIPLE_TARGET_DIRECTORY_ENV_VAR,
Expand Down
15 changes: 15 additions & 0 deletions crates/wdk-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,21 @@ pub enum ConfigError {
the environment setup scripts in the eWDK have been run."
)]
WDKContentRootDetectionError,

/// Error returned when cargo_metadata execution or parsing fails
#[error(transparent)]
CargoMetadataError(#[from] cargo_metadata::Error),

/// Error returned when multiple versions of the wdk-build package are
/// detected
#[error(
"multiple versions of the wdk-build package are detected, but only one version is \
allowed: {package_ids:#?}"
)]
MultipleWDKBuildCratesDetected {
/// package ids of the wdk-build crates detected
package_ids: Vec<cargo_metadata::PackageId>,
},
}

/// Errors that could result from parsing a configuration from a [`wdk-build`]
Expand Down
Loading