diff --git a/README.md b/README.md index 410ea63..0a67599 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ + +
# `xwin` @@ -77,6 +79,7 @@ Fixes the packages to prune unneeded files and adds symlinks to address file cas * `--include-debug-libs` - The MSVCRT includes (non-redistributable) debug versions of the various libs that are generally uninteresting to keep for most usage * `--include-debug-symbols` - The MSVCRT includes PDB (debug symbols) files for several of the libraries that are generally uninteresting to keep for most usage * `--preserve-ms-arch-notation` - By default, we convert the MS specific `x64`, `arm`, and `arm64` target architectures to the more canonical `x86_64`, `aarch`, and `aarch64` of LLVM etc when creating directories/names. Passing this flag will preserve the MS names for those targets +* `--use-winsysroot-style` - Use the /winsysroot layout, so that clang-cl's /winsysroot flag can be used with the output, rather than needing both -vctoolsdir and -winsdkdir. You will likely also want to use --preserve-ms-arch-notation and --disable-symlinks for use with clang-cl on Windows. * `--output` - The root output directory. Defaults to `./.xwin-cache/splat` if not specified * `--map` - An optional [map](#map-file) file used to configure what files are splatted, and any additional symlinks to create. diff --git a/src/ctx.rs b/src/ctx.rs index 4026899..102f197 100644 --- a/src/ctx.rs +++ b/src/ctx.rs @@ -160,10 +160,12 @@ impl Ctx { Ok(body) } + #[allow(clippy::too_many_arguments)] pub fn execute( self: std::sync::Arc, packages: std::collections::BTreeMap, payloads: Vec, + crt_version: String, sdk_version: String, arches: u32, variants: u32, @@ -179,20 +181,29 @@ impl Ctx { let splat_config = match &ops { crate::Ops::Splat(config) => { - let splat_roots = crate::splat::prep_splat(self.clone(), &config.output)?; + let splat_roots = crate::splat::prep_splat( + self.clone(), + &config.output, + config.use_winsysroot_style.then_some(&crt_version), + )?; let mut config = config.clone(); config.output = splat_roots.root.clone(); Some((splat_roots, config)) } crate::Ops::Minimize(config) => { - let splat_roots = crate::splat::prep_splat(self.clone(), &config.splat_output)?; + let splat_roots = crate::splat::prep_splat( + self.clone(), + &config.splat_output, + config.use_winsysroot_style.then_some(&crt_version), + )?; let config = crate::SplatConfig { preserve_ms_arch_notation: config.preserve_ms_arch_notation, include_debug_libs: config.include_debug_libs, include_debug_symbols: config.include_debug_symbols, enable_symlinks: config.enable_symlinks, + use_winsysroot_style: config.use_winsysroot_style, output: splat_roots.root.clone(), map: Some(config.map.clone()), copy: config.copy, @@ -266,7 +277,7 @@ impl Ctx { let sdk_headers = results.into_iter().collect::, _>>()?; let sdk_headers = sdk_headers.into_iter().flatten().collect(); - let Some(roots) = splat_config.map(|(sr, _)| sr) else { + let Some((roots, sc)) = splat_config else { return Ok(()); }; @@ -275,7 +286,14 @@ impl Ctx { let crt_ft = crt_ft.lock().take(); let atl_ft = atl_ft.lock().take(); - crate::splat::finalize_splat(&self, &roots, sdk_headers, crt_ft, atl_ft)?; + crate::splat::finalize_splat( + &self, + sc.use_winsysroot_style.then_some(&sdk_version), + &roots, + sdk_headers, + crt_ft, + atl_ft, + )?; } Ok(()) diff --git a/src/lib.rs b/src/lib.rs index b569bc8..8527d5e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -186,6 +186,7 @@ pub enum PayloadKind { } pub struct PrunedPackageList { + pub crt_version: String, pub sdk_version: String, pub payloads: Vec, } @@ -204,7 +205,7 @@ pub fn prune_pkg_list( let pkgs = &pkg_manifest.packages; let mut payloads = Vec::new(); - get_crt( + let crt_version = get_crt( pkgs, arches, variants, @@ -215,6 +216,7 @@ pub fn prune_pkg_list( let sdk_version = get_sdk(pkgs, arches, sdk_version, &mut payloads)?; Ok(PrunedPackageList { + crt_version, sdk_version, payloads, }) @@ -227,7 +229,7 @@ fn get_crt( pruned: &mut Vec, include_atl: bool, crt_version: Option, -) -> Result<(), Error> { +) -> Result { fn to_payload(mi: &manifest::ManifestItem, payload: &manifest::Payload) -> Payload { // These are really the only two we care about let kind = if mi.id.contains("Headers") { @@ -375,7 +377,7 @@ fn get_crt( } } - Ok(()) + Ok(crt_version) } fn get_atl( diff --git a/src/main.rs b/src/main.rs index 548649a..7b6daab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -59,6 +59,12 @@ pub struct SplatOptions { /// Passing this flag will preserve the MS names for those targets. #[arg(long)] preserve_ms_arch_notation: bool, + /// Use the /winsysroot layout, so that clang-cl's /winsysroot flag can be + /// used with the output, rather than needing both -vctoolsdir and + /// -winsdkdir. You will likely also want to use --preserve-ms-arch-notation + /// and --disable-symlinks for use with clang-cl on Windows. + #[arg(long)] + use_winsysroot_style: bool, } #[derive(Subcommand)] @@ -331,6 +337,7 @@ fn main() -> Result<(), Error> { include_debug_symbols: options.include_debug_symbols, enable_symlinks: !options.disable_symlinks, preserve_ms_arch_notation: options.preserve_ms_arch_notation, + use_winsysroot_style: options.use_winsysroot_style, copy, map, output: output.unwrap_or_else(|| ctx.work_dir.join("splat")), @@ -349,6 +356,7 @@ fn main() -> Result<(), Error> { include_debug_symbols: options.include_debug_symbols, enable_symlinks: !options.disable_symlinks, preserve_ms_arch_notation: options.preserve_ms_arch_notation, + use_winsysroot_style: options.use_winsysroot_style, splat_output: output.unwrap_or_else(|| ctx.work_dir.join("splat")), copy, minimize_output, @@ -419,7 +427,15 @@ fn main() -> Result<(), Error> { mp.set_move_cursor(true); let res = std::thread::spawn(move || { - ctx.execute(pkgs, work_items, pruned.sdk_version, arches, variants, op) + ctx.execute( + pkgs, + work_items, + pruned.crt_version, + pruned.sdk_version, + arches, + variants, + op, + ) }) .join(); diff --git a/src/manifest.rs b/src/manifest.rs index b1700a3..5fa8253 100644 --- a/src/manifest.rs +++ b/src/manifest.rs @@ -4,7 +4,7 @@ use std::{cmp, collections::BTreeMap}; use crate::Ctx; -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, Clone)] pub struct Payload { #[serde(rename = "fileName")] pub file_name: String, @@ -57,13 +57,13 @@ pub enum ItemKind { Zip, } -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, Clone, Copy)] #[serde(rename_all = "camelCase")] pub struct InstallSizes { pub target_drive: Option, } -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct ManifestItem { pub id: String, diff --git a/src/minimize.rs b/src/minimize.rs index f42d7ad..91e728a 100644 --- a/src/minimize.rs +++ b/src/minimize.rs @@ -5,6 +5,7 @@ pub struct MinimizeConfig { pub include_debug_libs: bool, pub include_debug_symbols: bool, pub enable_symlinks: bool, + pub use_winsysroot_style: bool, pub preserve_ms_arch_notation: bool, pub splat_output: PathBuf, pub copy: bool, diff --git a/src/splat.rs b/src/splat.rs index eeb8304..cdd8cff 100644 --- a/src/splat.rs +++ b/src/splat.rs @@ -9,6 +9,7 @@ pub struct SplatConfig { pub include_debug_symbols: bool, pub enable_symlinks: bool, pub preserve_ms_arch_notation: bool, + pub use_winsysroot_style: bool, pub output: PathBuf, pub map: Option, pub copy: bool, @@ -51,7 +52,11 @@ pub(crate) struct SplatRoots { src: PathBuf, } -pub(crate) fn prep_splat(ctx: std::sync::Arc, root: &Path) -> Result { +pub(crate) fn prep_splat( + ctx: std::sync::Arc, + root: &Path, + winroot: Option<&str>, +) -> Result { // Ensure we create the path first, you can't canonicalize a non-existant path if !root.exists() { std::fs::create_dir_all(root) @@ -59,8 +64,18 @@ pub(crate) fn prep_splat(ctx: std::sync::Arc, root: &Path) -> Result { src.push("lib/um"); - let mut target = roots.sdk.join("lib/um"); + + let mut target = roots.sdk.join("lib"); + + if config.use_winsysroot_style { + target.push(sdk_version); + } + + target.push("um"); push_arch( &mut src, @@ -283,7 +311,14 @@ pub(crate) fn splat( } PayloadKind::SdkStoreLibs => { src.push("lib/um"); - let target = roots.sdk.join("lib/um"); + + let mut target = roots.sdk.join("lib"); + + if config.use_winsysroot_style { + target.push(sdk_version); + } + + target.push("um"); Arch::iter(arches) .map(|arch| -> Result, Error> { @@ -309,16 +344,20 @@ pub(crate) fn splat( let inc_src = src.join("include/ucrt"); let tree = get_tree(&inc_src)?; - let target = if map.is_some() { - let mut inc = roots.sdk.clone(); - inc.push("Include"); + let mut target = if map.is_some() { + let mut inc = roots.sdk.join("Include"); inc.push(sdk_version); - inc.push("ucrt"); inc } else { - roots.sdk.join("include/ucrt") + let mut target = roots.sdk.join("include"); + if config.use_winsysroot_style { + target.push(sdk_version); + } + target }; + target.push("ucrt"); + let mut mappings = vec![Mapping { src: inc_src, target, @@ -329,7 +368,15 @@ pub(crate) fn splat( }]; src.push("lib/ucrt"); - let target = roots.sdk.join("lib/ucrt"); + + let mut target = roots.sdk.join("lib"); + + if config.use_winsysroot_style { + target.push(sdk_version); + } + + target.push("ucrt"); + for arch in Arch::iter(arches) { let mut src = src.clone(); let mut target = target.clone(); @@ -667,51 +714,53 @@ pub(crate) fn splat( }) .collect_into_vec(&mut results); - match kind { - PayloadKind::SdkLibs => { - // Symlink sdk/lib/{sdkversion} -> sdk/lib, regardless of filesystem case sensitivity. - let mut versioned_linkname = roots.sdk.clone(); - versioned_linkname.push("lib"); - versioned_linkname.push(sdk_version); - - // Multiple architectures both have a lib dir, - // but we only need to create this symlink once. - if !versioned_linkname.exists() { - crate::symlink_on_windows_too(".", &versioned_linkname)?; - } + if !config.use_winsysroot_style { + match kind { + PayloadKind::SdkLibs => { + // Symlink sdk/lib/{sdkversion} -> sdk/lib, regardless of filesystem case sensitivity. + let mut versioned_linkname = roots.sdk.clone(); + versioned_linkname.push("lib"); + versioned_linkname.push(sdk_version); + + // Multiple architectures both have a lib dir, + // but we only need to create this symlink once. + if !versioned_linkname.exists() { + crate::symlink_on_windows_too(".", &versioned_linkname)?; + } - // https://github.com/llvm/llvm-project/blob/release/14.x/clang/lib/Driver/ToolChains/MSVC.cpp#L1102 - if config.enable_symlinks { - let mut title_case = roots.sdk.clone(); - title_case.push("Lib"); - if !title_case.exists() { - symlink("lib", &title_case)?; + // https://github.com/llvm/llvm-project/blob/release/14.x/clang/lib/Driver/ToolChains/MSVC.cpp#L1102 + if config.enable_symlinks { + let mut title_case = roots.sdk.clone(); + title_case.push("Lib"); + if !title_case.exists() { + symlink("lib", &title_case)?; + } } } - } - PayloadKind::SdkHeaders => { - // Symlink sdk/include/{sdkversion} -> sdk/include, regardless of filesystem case sensitivity. - let mut versioned_linkname = roots.sdk.clone(); - versioned_linkname.push("include"); - versioned_linkname.push(sdk_version); - - // Desktop and Store variants both have an include dir, - // but we only need to create this symlink once. - if !versioned_linkname.exists() { - crate::symlink_on_windows_too(".", &versioned_linkname)?; - } + PayloadKind::SdkHeaders => { + // Symlink sdk/include/{sdkversion} -> sdk/include, regardless of filesystem case sensitivity. + let mut versioned_linkname = roots.sdk.clone(); + versioned_linkname.push("include"); + versioned_linkname.push(sdk_version); + + // Desktop and Store variants both have an include dir, + // but we only need to create this symlink once. + if !versioned_linkname.exists() { + crate::symlink_on_windows_too(".", &versioned_linkname)?; + } - // https://github.com/llvm/llvm-project/blob/release/14.x/clang/lib/Driver/ToolChains/MSVC.cpp#L1340-L1346 - if config.enable_symlinks { - let mut title_case = roots.sdk.clone(); - title_case.push("Include"); - if !title_case.exists() { - symlink("include", &title_case)?; + // https://github.com/llvm/llvm-project/blob/release/14.x/clang/lib/Driver/ToolChains/MSVC.cpp#L1340-L1346 + if config.enable_symlinks { + let mut title_case = roots.sdk.clone(); + title_case.push("Include"); + if !title_case.exists() { + symlink("include", &title_case)?; + } } } - } - _ => (), - }; + _ => (), + }; + } } item.progress.finish_with_message("📦 splatted"); @@ -723,6 +772,7 @@ pub(crate) fn splat( pub(crate) fn finalize_splat( ctx: &Ctx, + sdk_version: Option<&str>, roots: &SplatRoots, sdk_headers: Vec, crt_headers: Option, @@ -921,7 +971,14 @@ pub(crate) fn finalize_splat( // There is a um/gl directory, but of course there is an include for GL/ // instead, so fix that as well :p - symlink("gl", &roots.sdk.join("include/um/GL"))?; + if let Some(_sdk_version) = sdk_version { + // let mut target = roots.sdk.join("Include"); + // target.push(sdk_version); + // target.push("um/GL"); + // symlink("gl", &target)?; + } else { + symlink("gl", &roots.sdk.join("include/um/GL"))?; + } Ok(()) } diff --git a/tests/compiles.rs b/tests/compiles.rs index a78a5b6..e783d23 100644 --- a/tests/compiles.rs +++ b/tests/compiles.rs @@ -35,104 +35,129 @@ fn verify_compiles() { ) .unwrap(); - let output_dir = ctx.work_dir.join("splat"); - if !output_dir.exists() { - std::fs::create_dir_all(&output_dir).unwrap(); + #[derive(Debug)] + enum Style { + Default, + WinSysRoot, } - let op = xwin::Ops::Splat(xwin::SplatConfig { - include_debug_libs: false, - include_debug_symbols: false, - enable_symlinks: true, - preserve_ms_arch_notation: false, - map: None, - copy: true, - output: output_dir.clone(), - }); + for style in [Style::Default, Style::WinSysRoot] { + let output_dir = ctx.work_dir.join(format!("{style:?}")); + if !output_dir.exists() { + std::fs::create_dir_all(&output_dir).unwrap(); + } + + if !cfg!(target_os = "windows") && matches!(style, Style::WinSysRoot) { + continue; + } + + let op = xwin::Ops::Splat(xwin::SplatConfig { + include_debug_libs: false, + include_debug_symbols: false, + enable_symlinks: matches!(style, Style::Default), + preserve_ms_arch_notation: matches!(style, Style::WinSysRoot), + use_winsysroot_style: matches!(style, Style::WinSysRoot), + map: None, + copy: true, + output: output_dir.clone(), + }); + + ctx.clone() + .execute( + pkg_manifest.packages.clone(), + pruned + .payloads + .clone() + .into_iter() + .map(|payload| xwin::WorkItem { + progress: hidden.clone(), + payload: std::sync::Arc::new(payload), + }) + .collect(), + pruned.crt_version.clone(), + pruned.sdk_version.clone(), + xwin::Arch::X86_64 as u32, + xwin::Variant::Desktop as u32, + op, + ) + .unwrap(); + + if xwin::Path::new("tests/xwin-test/target").exists() { + std::fs::remove_dir_all("tests/xwin-test/target").expect("failed to remove target dir"); + } + + let mut cmd = std::process::Command::new("cargo"); + cmd.args([ + "build", + "--target", + "x86_64-pc-windows-msvc", + "--manifest-path", + "tests/xwin-test/Cargo.toml", + ]); + + let od = xwin::util::canonicalize(&output_dir).unwrap(); + + let includes = match style { + Style::Default => { + cmd.env("RUSTFLAGS", format!("-C linker=lld-link -Lnative={od}/crt/lib/x86_64 -Lnative={od}/sdk/lib/um/x86_64 -Lnative={od}/sdk/lib/ucrt/x86_64")); + format!("-Wno-unused-command-line-argument -fuse-ld=lld-link /imsvc{od}/crt/include /imsvc{od}/sdk/include/ucrt /imsvc{od}/sdk/include/um /imsvc{od}/sdk/include/shared") + } + Style::WinSysRoot => { + const SEP: char = '\x1F'; + cmd.env("CARGO_ENCODED_RUSTFLAGS", format!("-C{SEP}linker=lld-link{SEP}-Lnative={od}/VC/Tools/MSVC/{crt_version}/Lib/x64{SEP}-Lnative={od}/Windows Kits/10/Lib/{sdk_version}/um/x64{SEP}-Lnative={od}/Windows Kits/10/Lib/{sdk_version}/ucrt/x64", crt_version = &pruned.crt_version, sdk_version = &pruned.sdk_version)); + + format!("-Wno-unused-command-line-argument -fuse-ld=lld-link /winsysroot {od}") + } + }; + + let cc_env = [ + ("CC_x86_64_pc_windows_msvc", "clang-cl"), + ("CXX_x86_64_pc_windows_msvc", "clang-cl"), + ("AR_x86_64_pc_windows_msvc", "llvm-lib"), + ("CFLAGS_x86_64_pc_windows_msvc", &includes), + ("CXXFLAGS_x86_64_pc_windows_msvc", &includes), + ]; + + cmd.envs(cc_env); + + assert!(cmd.status().unwrap().success()); + + // Ignore the /vctoolsdir /winsdkdir test below on CI since it fails, I'm assuming + // due to the clang version in GHA being outdated, but don't have the will to + // look into it now + if !matches!(style, Style::Default) || std::env::var("CI").is_ok() { + return; + } - ctx.execute( - pkg_manifest.packages, - pruned - .payloads - .into_iter() - .map(|payload| xwin::WorkItem { - progress: hidden.clone(), - payload: std::sync::Arc::new(payload), - }) - .collect(), - pruned.sdk_version, - xwin::Arch::X86_64 as u32, - xwin::Variant::Desktop as u32, - op, - ) - .unwrap(); - - if xwin::Path::new("tests/xwin-test/target").exists() { std::fs::remove_dir_all("tests/xwin-test/target").expect("failed to remove target dir"); - } - let mut cmd = std::process::Command::new("cargo"); - cmd.args([ - "build", - "--target", - "x86_64-pc-windows-msvc", - "--manifest-path", - "tests/xwin-test/Cargo.toml", - ]); - - let od = xwin::util::canonicalize(&output_dir).unwrap(); - - let includes = format!("-Wno-unused-command-line-argument -fuse-ld=lld-link /imsvc{od}/crt/include /imsvc{od}/sdk/include/ucrt /imsvc{od}/sdk/include/um /imsvc{od}/sdk/include/shared"); - let libs = format!("-C linker=lld-link -Lnative={od}/crt/lib/x86_64 -Lnative={od}/sdk/lib/um/x86_64 -Lnative={od}/sdk/lib/ucrt/x86_64"); + let mut cmd = std::process::Command::new("cargo"); + cmd.args([ + "build", + "--target", + "x86_64-pc-windows-msvc", + "--manifest-path", + "tests/xwin-test/Cargo.toml", + ]); - let cc_env = [ - ("CC_x86_64_pc_windows_msvc", "clang-cl"), - ("CXX_x86_64_pc_windows_msvc", "clang-cl"), - ("AR_x86_64_pc_windows_msvc", "llvm-lib"), - ("CFLAGS_x86_64_pc_windows_msvc", &includes), - ("CXXFLAGS_x86_64_pc_windows_msvc", &includes), - ("RUSTFLAGS", &libs), - ]; - - cmd.envs(cc_env); - - assert!(cmd.status().unwrap().success()); - - // Ignore the /vctoolsdir /winsdkdir test below on CI since it fails, I'm assuming - // due to the clang version in GHA being outdated, but don't have the will to - // look into it now - if std::env::var("CI").is_ok() { - return; - } - - std::fs::remove_dir_all("tests/xwin-test/target").expect("failed to remove target dir"); - - let mut cmd = std::process::Command::new("cargo"); - cmd.args([ - "build", - "--target", - "x86_64-pc-windows-msvc", - "--manifest-path", - "tests/xwin-test/Cargo.toml", - ]); - - let includes = format!( + let includes = format!( "-Wno-unused-command-line-argument -fuse-ld=lld-link /vctoolsdir {od}/crt /winsdkdir {od}/sdk" ); - let libs = format!("-C linker=lld-link -Lnative={od}/crt/lib/x86_64 -Lnative={od}/sdk/lib/um/x86_64 -Lnative={od}/sdk/lib/ucrt/x86_64"); + let libs = format!("-C linker=lld-link -Lnative={od}/crt/lib/x86_64 -Lnative={od}/sdk/lib/um/x86_64 -Lnative={od}/sdk/lib/ucrt/x86_64"); - let cc_env = [ - ("CC_x86_64_pc_windows_msvc", "clang-cl"), - ("CXX_x86_64_pc_windows_msvc", "clang-cl"), - ("AR_x86_64_pc_windows_msvc", "llvm-lib"), - ("CFLAGS_x86_64_pc_windows_msvc", &includes), - ("CXXFLAGS_x86_64_pc_windows_msvc", &includes), - ("RUSTFLAGS", &libs), - ]; + let cc_env = [ + ("CC_x86_64_pc_windows_msvc", "clang-cl"), + ("CXX_x86_64_pc_windows_msvc", "clang-cl"), + ("AR_x86_64_pc_windows_msvc", "llvm-lib"), + ("CFLAGS_x86_64_pc_windows_msvc", &includes), + ("CXXFLAGS_x86_64_pc_windows_msvc", &includes), + ("RUSTFLAGS", &libs), + ]; - cmd.envs(cc_env); + cmd.envs(cc_env); - assert!(cmd.status().unwrap().success()); + assert!(cmd.status().unwrap().success()); + } } #[test] @@ -190,6 +215,7 @@ fn verify_compiles_minimized() { include_debug_symbols: false, enable_symlinks: true, preserve_ms_arch_notation: false, + use_winsysroot_style: false, map: map_path.clone(), copy: true, splat_output: output_dir.clone(), @@ -209,6 +235,7 @@ fn verify_compiles_minimized() { payload: std::sync::Arc::new(payload), }) .collect(), + pruned.crt_version, pruned.sdk_version, xwin::Arch::X86_64 as u32, xwin::Variant::Desktop as u32, diff --git a/tests/deterministic.rs b/tests/deterministic.rs index 57d775a..4f4960c 100644 --- a/tests/deterministic.rs +++ b/tests/deterministic.rs @@ -39,6 +39,7 @@ fn verify_deterministic() { include_debug_symbols: false, enable_symlinks: true, preserve_ms_arch_notation: false, + use_winsysroot_style: false, map: None, copy: true, output: output_dir.clone(), @@ -54,6 +55,7 @@ fn verify_deterministic() { payload: std::sync::Arc::new(payload), }) .collect(), + pruned.crt_version, pruned.sdk_version, xwin::Arch::X86_64 as u32, xwin::Variant::Desktop as u32, diff --git a/tests/snapshots/xwin-minimize.snap b/tests/snapshots/xwin-minimize.snap index 542bffc..ab0ac88 100644 --- a/tests/snapshots/xwin-minimize.snap +++ b/tests/snapshots/xwin-minimize.snap @@ -40,6 +40,13 @@ Options: Passing this flag will preserve the MS names for those targets. + --use-winsysroot-style + Use the /winsysroot layout, so that clang-cl's /winsysroot flag can be + used with the output, rather than needing both -vctoolsdir and + -winsdkdir. You will likely also want to use + --preserve-ms-arch-notation and --disable-symlinks for use with + clang-cl on Windows + --map The path of the filter file that is generated. Defaults to ./.xwin-cache/xwin-map.toml diff --git a/tests/snapshots/xwin-splat.snap b/tests/snapshots/xwin-splat.snap index fb7673f..bee92e6 100644 --- a/tests/snapshots/xwin-splat.snap +++ b/tests/snapshots/xwin-splat.snap @@ -34,6 +34,13 @@ Options: Passing this flag will preserve the MS names for those targets. + --use-winsysroot-style + Use the /winsysroot layout, so that clang-cl's /winsysroot flag can be + used with the output, rather than needing both -vctoolsdir and + -winsdkdir. You will likely also want to use + --preserve-ms-arch-notation and --disable-symlinks for use with + clang-cl on Windows + --output The root output directory. Defaults to `./.xwin-cache/splat` if not specified