Skip to content

Commit 456f0ea

Browse files
committed
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
1 parent 3d83ead commit 456f0ea

File tree

3 files changed

+71
-0
lines changed

3 files changed

+71
-0
lines changed

build.rs

+28
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,34 @@ fn main() {
4848
if let Some(rev) = git_revision_hash() {
4949
println!("cargo:rustc-env=RIPGREP_BUILD_GIT_HASH={}", rev);
5050
}
51+
// Embed a Windows manifest and set some linker options. The main reason
52+
// for this is to enable long path support on Windows. This still, I
53+
// believe, requires enabling long path support in the registry. But if
54+
// that's enabled, then this will let ripgrep use C:\... style paths that
55+
// are longer than 260 characters.
56+
set_windows_exe_options();
57+
}
58+
59+
fn set_windows_exe_options() {
60+
static MANIFEST: &str = "pkg/windows/Manifest.xml";
61+
62+
let Ok(target_os) = env::var("CARGO_CFG_TARGET_OS") else { return };
63+
let Ok(target_env) = env::var("CARGO_CFG_TARGET_ENV") else { return };
64+
if !(target_os == "windows" && target_env == "msvc") {
65+
return;
66+
}
67+
68+
let Ok(mut manifest) = env::current_dir() else { return };
69+
manifest.push(MANIFEST);
70+
let Some(manifest) = manifest.to_str() else { return };
71+
72+
println!("cargo:rerun-if-changed={}", MANIFEST);
73+
// Embed the Windows application manifest file.
74+
println!("cargo:rustc-link-arg-bin=rustc-main=/MANIFEST:EMBED");
75+
println!("cargo:rustc-link-arg-bin=rustc-main=/MANIFESTINPUT:{manifest}");
76+
// Turn linker warnings into errors. Helps debugging, otherwise the
77+
// warnings get squashed (I believe).
78+
println!("cargo:rustc-link-arg-bin=rustc-main=/WX");
5179
}
5280

5381
fn git_revision_hash() -> Option<String> {

pkg/windows/Manifest.xml

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<!--
3+
This is a Windows application manifest file.
4+
See: https://docs.microsoft.com/en-us/windows/win32/sbscs/application-manifests
5+
-->
6+
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
7+
<!-- Versions rustc supports as compiler hosts -->
8+
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
9+
<application>
10+
<!-- Windows 7 --><supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
11+
<!-- Windows 8 --><supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
12+
<!-- Windows 8.1 --><supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
13+
<!-- Windows 10 and 11 --><supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
14+
</application>
15+
</compatibility>
16+
<!-- Use UTF-8 code page -->
17+
<asmv3:application>
18+
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">
19+
<activeCodePage>UTF-8</activeCodePage>
20+
</asmv3:windowsSettings>
21+
</asmv3:application>
22+
<!-- Remove (most) legacy path limits -->
23+
<asmv3:application>
24+
<asmv3:windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
25+
<ws2:longPathAware>true</ws2:longPathAware>
26+
</asmv3:windowsSettings>
27+
</asmv3:application>
28+
</assembly>

pkg/windows/README.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
This directory contains a Windows manifest for various Windows-specific
2+
settings.
3+
4+
The main thing we enable here is [`longPathAware`], which permits paths of the
5+
form `C:\` to be longer than 260 characters.
6+
7+
The approach taken here was modeled off of a [similar change for `rustc`][rustc pr].
8+
In particular, this manifest gets linked into the final binary. Those linker
9+
arguments are applied in `build.rs`.
10+
11+
This currently only applies to MSVC builds. If there's an easy way to make this
12+
apply to GNU builds as well, then patches are welcome.
13+
14+
[`longPathAware`]: https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests#longpathaware
15+
[rustc pr]: https://github.com/rust-lang/rust/pull/96737

0 commit comments

Comments
 (0)