diff options
-rw-r--r-- | build.rs | 28 | ||||
-rw-r--r-- | pkg/windows/Manifest.xml | 28 | ||||
-rw-r--r-- | pkg/windows/README.md | 15 |
3 files changed, 71 insertions, 0 deletions
@@ -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=rg=/MANIFEST:EMBED"); + println!("cargo:rustc-link-arg-bin=rg=/MANIFESTINPUT:{manifest}"); + // Turn linker warnings into errors. Helps debugging, otherwise the + // warnings get squashed (I believe). + println!("cargo:rustc-link-arg-bin=rg=/WX"); } fn git_revision_hash() -> Option<String> { diff --git a/pkg/windows/Manifest.xml b/pkg/windows/Manifest.xml new file mode 100644 index 00000000..b6f0e702 --- /dev/null +++ b/pkg/windows/Manifest.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!-- +This is a Windows application manifest file. +See: https://docs.microsoft.com/en-us/windows/win32/sbscs/application-manifests +--> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> + <!-- Versions rustc supports as compiler hosts --> + <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> + <application> + <!-- Windows 7 --><supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> + <!-- Windows 8 --><supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> + <!-- Windows 8.1 --><supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> + <!-- Windows 10 and 11 --><supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> + </application> + </compatibility> + <!-- Use UTF-8 code page --> + <asmv3:application> + <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings"> + <activeCodePage>UTF-8</activeCodePage> + </asmv3:windowsSettings> + </asmv3:application> + <!-- Remove (most) legacy path limits --> + <asmv3:application> + <asmv3:windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings"> + <ws2:longPathAware>true</ws2:longPathAware> + </asmv3:windowsSettings> + </asmv3:application> +</assembly> diff --git a/pkg/windows/README.md b/pkg/windows/README.md new file mode 100644 index 00000000..7be701bf --- /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 |