summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Gallant <jamslam@gmail.com>2023-07-08 13:27:22 -0400
committerAndrew Gallant <jamslam@gmail.com>2023-07-08 18:52:42 -0400
commitdb6bb21a629d5b1ec1bfe89c693b280497c9eedc (patch)
tree9fe986d58a79b5d0dfeee05fbe70b635d7bb4805
parentda7c81fb960a2f5d0e3e3abd4bb86d7bb223ea57 (diff)
windows: attempt to enable long path support for MSVC targets
See the README and comments in the build.rs. Basically, this embeds an XML file that I guess is a way of setting configuration knobs on Windows. One of those knobs is enabling long path support. You still need to enable it in your registry (lol), but this will handle the other half of it. Fixes #364, Closes #2049
-rw-r--r--build.rs28
-rw-r--r--pkg/windows/Manifest.xml28
-rw-r--r--pkg/windows/README.md15
3 files changed, 71 insertions, 0 deletions
diff --git a/build.rs b/build.rs
index b4b62b9c..80cf273d 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=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