Skip to content

Commit

Permalink
Build perf: Make calls to bindgen run in parallel (#159)
Browse files Browse the repository at this point in the history
  • Loading branch information
NateD-MSFT authored May 29, 2024
1 parent c364797 commit 793a270
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 11 deletions.
4 changes: 2 additions & 2 deletions crates/wdk-build/src/bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub trait BuilderExt {
///
/// Implementation may return `wdk_build::ConfigError` if it fails to create
/// a builder
fn wdk_default(c_header_files: Vec<&str>, config: Config) -> Result<Builder, ConfigError>;
fn wdk_default(c_header_files: Vec<&str>, config: &Config) -> Result<Builder, ConfigError>;
}

impl BuilderExt for Builder {
Expand All @@ -26,7 +26,7 @@ impl BuilderExt for Builder {
///
/// Will return `wdk_build::ConfigError` if any of the resolved include or
/// library paths do not exist
fn wdk_default(c_header_files: Vec<&str>, config: Config) -> Result<Self, ConfigError> {
fn wdk_default(c_header_files: Vec<&str>, config: &Config) -> Result<Self, ConfigError> {
let mut builder = Self::default();

for c_header in c_header_files {
Expand Down
44 changes: 35 additions & 9 deletions crates/wdk-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
use std::{
env,
path::{Path, PathBuf},
sync::Arc,
thread::{self, JoinHandle},
};

use bindgen::CodegenConfig;
Expand All @@ -21,7 +23,7 @@ use wdk_build::{BuilderExt, Config, ConfigError, DriverConfig, KMDFConfig};
// "2.0", "2.15", "2.17", "2.19", "2.21", "2.23", "2.25", "2.27", "2.31",
// "2.33", ];

fn generate_constants(out_path: &Path, config: Config) -> Result<(), ConfigError> {
fn generate_constants(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
Ok(
bindgen::Builder::wdk_default(vec!["src/ntddk-input.h", "src/wdf-input.h"], config)?
.with_codegen_config(CodegenConfig::VARS)
Expand All @@ -31,7 +33,7 @@ fn generate_constants(out_path: &Path, config: Config) -> Result<(), ConfigError
)
}

fn generate_types(out_path: &Path, config: Config) -> Result<(), ConfigError> {
fn generate_types(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
Ok(
bindgen::Builder::wdk_default(vec!["src/ntddk-input.h", "src/wdf-input.h"], config)?
.with_codegen_config(CodegenConfig::TYPES)
Expand All @@ -41,7 +43,7 @@ fn generate_types(out_path: &Path, config: Config) -> Result<(), ConfigError> {
)
}

fn generate_ntddk(out_path: &Path, config: Config) -> Result<(), ConfigError> {
fn generate_ntddk(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
Ok(
bindgen::Builder::wdk_default(vec!["src/ntddk-input.h"], config)?
.with_codegen_config((CodegenConfig::TYPES | CodegenConfig::VARS).complement())
Expand All @@ -51,7 +53,7 @@ fn generate_ntddk(out_path: &Path, config: Config) -> Result<(), ConfigError> {
)
}

fn generate_wdf(out_path: &Path, config: Config) -> Result<(), ConfigError> {
fn generate_wdf(out_path: &Path, config: &Config) -> Result<(), ConfigError> {
// As of NI WDK, this may generate an empty file due to no non-type and non-var
// items in the wdf headers(i.e. functions are all inlined). This step is
// intentionally left here in case older WDKs have non-inlined functions or new
Expand All @@ -67,6 +69,15 @@ fn generate_wdf(out_path: &Path, config: Config) -> Result<(), ConfigError> {
)
}

type GenerateFn = fn(&Path, &Config) -> Result<(), ConfigError>;

const GENERATE_FUNCTIONS: [GenerateFn; 4] = [
generate_constants,
generate_types,
generate_ntddk,
generate_wdf,
];

fn main() -> anyhow::Result<()> {
let tracing_filter = EnvFilter::default()
// Show errors and warnings by default
Expand Down Expand Up @@ -135,12 +146,27 @@ fn main() -> anyhow::Result<()> {
),
];

let mut handles = Vec::<JoinHandle<Result<(), ConfigError>>>::new();
let config_arc = Arc::new(config);

for out_path in out_paths {
generate_constants(&out_path, config.clone())?;
generate_types(&out_path, config.clone())?;
generate_ntddk(&out_path, config.clone())?;
generate_wdf(&out_path, config.clone())?;
let path_arc = Arc::new(out_path);
for generate_function in GENERATE_FUNCTIONS {
let temp_path = path_arc.clone();
let temp_config = config_arc.clone();
let handle: JoinHandle<Result<(), ConfigError>> = thread::spawn(move || {
generate_function(&temp_path, &temp_config)?;
Ok(())
});
handles.push(handle);
}
}

for handle in handles {
if let Err(e) = handle.join().unwrap() {
return Err(e.into());
}
}

Ok(config.export_config()?)
Ok(config_arc.export_config()?)
}

0 comments on commit 793a270

Please sign in to comment.