From 24e0d070efc855d900fb04be4f4b39707628bfdd Mon Sep 17 00:00:00 2001 From: mtlcl410 <2368091+mtlcl410@users.noreply.github.com> Date: Mon, 2 Nov 2026 10:23:34 +0800 Subject: [PATCH] M10: the print crate's tests delay-load the print DLLs too (#2630) The pdfcraft-print unit-test executable imported windows.data.pdf.dll and prntvpt.dll at load time (the windows crate binds them with raw-dylib), so on a Windows installation without them it could not start, and the tests of the missing-DLL guard never ran there. crates/print/build.rs now passes /DELAYLOAD for both and delayimp.lib on MSVC, as the applications' build scripts do. Link arguments from a build script reach only this package's own executables, so dependents are unaffected. dumpbin /imports: before, both DLLs under "the following imports"; after, under "the following delay load imports". A copy of each test binary with prntvpt.dll renamed to a DLL that doesn't exist: the old one exits with 0xC0000135 (STATUS_DLL_NOT_FOUND) before main, the new one starts and runs. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Pq7HyCfwzyRXj4VfQAVVdv --- apps/pdfcraft-cli/build.rs | 2 +- apps/pdfcraft/build.rs | 2 +- crates/print/build.rs | 23 +++++++++++++++++++++++ crates/print/src/spool.rs | 6 +++--- 4 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 crates/print/build.rs diff --git a/apps/pdfcraft-cli/build.rs b/apps/pdfcraft-cli/build.rs index 1e8e69258a..9a6500b7f3 100644 --- a/apps/pdfcraft-cli/build.rs +++ b/apps/pdfcraft-cli/build.rs @@ -10,7 +10,7 @@ /// driver's print capabilities). Trimmed Windows installations (NTLite) can lack them, and a /// load-time import of a missing DLL stops the program before `main` (#2630). Delay-loaded, they /// load on the first print; `pdfcraft_print::spool` checks they exist before calling in. -/// Same list in `apps/pdfcraft{,-cli}/build.rs` and `crates/print/src/spool.rs`. +/// Same list in `apps/pdfcraft{,-cli}/build.rs`, `crates/print/build.rs` and `crates/print/src/spool.rs`. const DELAY_LOADED: [&str; 2] = ["windows.data.pdf.dll", "prntvpt.dll"]; fn main() { diff --git a/apps/pdfcraft/build.rs b/apps/pdfcraft/build.rs index ce2981ac20..b6892e7b9d 100644 --- a/apps/pdfcraft/build.rs +++ b/apps/pdfcraft/build.rs @@ -13,7 +13,7 @@ mod windows_manifest; /// driver's print capabilities). Trimmed Windows installations (NTLite) can lack them, and a /// load-time import of a missing DLL stops the program before `main` (#2630). Delay-loaded, they /// load on the first print; `pdfcraft_print::spool` checks they exist before calling in. -/// Same list in `apps/pdfcraft{,-cli}/build.rs` and `crates/print/src/spool.rs`. +/// Same list in `apps/pdfcraft{,-cli}/build.rs`, `crates/print/build.rs` and `crates/print/src/spool.rs`. const DELAY_LOADED: [&str; 2] = ["windows.data.pdf.dll", "prntvpt.dll"]; fn main() { diff --git a/crates/print/build.rs b/crates/print/build.rs new file mode 100644 index 0000000000..82b3ce3fac --- /dev/null +++ b/crates/print/build.rs @@ -0,0 +1,23 @@ +//! Windows (MSVC) only: delay-load the print DLLs in this crate's own test executable, as the +//! applications do (`apps/pdfcraft{,-cli}/build.rs`), so it starts on a Windows installation that +//! lacks them (#2630) and its tests of the missing-DLL guard in `src/spool.rs` run there. Link +//! arguments from a build script reach only this package's own executables (its tests), never +//! the crates that depend on it; each application sets its own. +//! +//! On every other target this does nothing. + +/// The in-box DLLs only printing uses (Windows.Data.Pdf draws the job, prntvpt reads the +/// driver's print capabilities). Same list in `apps/pdfcraft{,-cli}/build.rs` and +/// `src/spool.rs`. +const DELAY_LOADED: [&str; 2] = ["windows.data.pdf.dll", "prntvpt.dll"]; + +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + if std::env::var("CARGO_CFG_TARGET_OS").as_deref() != Ok("windows") || std::env::var("CARGO_CFG_TARGET_ENV").as_deref() != Ok("msvc") { + return; + } + for dll in DELAY_LOADED { + println!("cargo:rustc-link-arg=/DELAYLOAD:{dll}"); + } + println!("cargo:rustc-link-arg=delayimp.lib"); +} diff --git a/crates/print/src/spool.rs b/crates/print/src/spool.rs index 8c2d35335a..23a77bdd2f 100644 --- a/crates/print/src/spool.rs +++ b/crates/print/src/spool.rs @@ -7,9 +7,9 @@ pub use craft_print::{ }; /// Windows: the in-box DLLs printing draws and describes jobs with. The executables delay-load -/// them (`apps/pdfcraft{,-cli}/build.rs`, the same list) so a Windows installation without them -/// still starts (#2630); a call into a missing delay-loaded DLL would end the process, so -/// printing checks for them first. +/// them (`apps/pdfcraft{,-cli}/build.rs`, and `build.rs` for this crate's tests: the same list) +/// so a Windows installation without them still starts (#2630); a call into a missing +/// delay-loaded DLL would end the process, so printing checks for them first. #[cfg(windows)] pub(crate) const PRINT_DLLS: [&str; 2] = ["windows.data.pdf.dll", "prntvpt.dll"];