diff --git a/build.rs b/build.rs index b4b62b9c38..3c19201e4c 100644 --- a/build.rs +++ b/build.rs @@ -48,6 +48,34 @@ fn main() { if let Some(rev) = git_revision_hash() { println!("cargo:rustc-env=RIPGREP_BUILD_GIT_HASH={}", rev); } + // Embed a Windows manifest and set some linker options. The main reason + // for this is to enable long path support on Windows. This still, I + // believe, requires enabling long path support in the registry. But if + // that's enabled, then this will let ripgrep use C:\... style paths that + // are longer than 260 characters. + set_windows_exe_options(); +} + +fn set_windows_exe_options() { + static MANIFEST: &str = "pkg/windows/Manifest.xml"; + + let Ok(target_os) = env::var("CARGO_CFG_TARGET_OS") else { return }; + let Ok(target_env) = env::var("CARGO_CFG_TARGET_ENV") else { return }; + if !(target_os == "windows" && target_env == "msvc") { + return; + } + + let Ok(mut manifest) = env::current_dir() else { return }; + manifest.push(MANIFEST); + let Some(manifest) = manifest.to_str() else { return }; + + println!("cargo:rerun-if-changed={}", MANIFEST); + // Embed the Windows application manifest file. + println!("cargo:rustc-link-arg-bin=ripgrep=/MANIFEST:EMBED"); + println!("cargo:rustc-link-arg-bin=ripgrep=/MANIFESTINPUT:{manifest}"); + // Turn linker warnings into errors. Helps debugging, otherwise the + // warnings get squashed (I believe). + println!("cargo:rustc-link-arg-bin=ripgrep=/WX"); } fn git_revision_hash() -> Option { diff --git a/pkg/windows/Manifest.xml b/pkg/windows/Manifest.xml new file mode 100644 index 0000000000..b6f0e70277 --- /dev/null +++ b/pkg/windows/Manifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + UTF-8 + + + + + + true + + + diff --git a/pkg/windows/README.md b/pkg/windows/README.md new file mode 100644 index 0000000000..7be701bf80 --- /dev/null +++ b/pkg/windows/README.md @@ -0,0 +1,15 @@ +This directory contains a Windows manifest for various Windows-specific +settings. + +The main thing we enable here is [`longPathAware`], which permits paths of the +form `C:\` to be longer than 260 characters. + +The approach taken here was modeled off of a [similar change for `rustc`][rustc pr]. +In particular, this manifest gets linked into the final binary. Those linker +arguments are applied in `build.rs`. + +This currently only applies to MSVC builds. If there's an easy way to make this +apply to GNU builds as well, then patches are welcome. + +[`longPathAware`]: https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests#longpathaware +[rustc pr]: https://github.com/rust-lang/rust/pull/96737