Skip to content

Commit

Permalink
windows: attempt to enable long path support for MSVC targets
Browse files Browse the repository at this point in the history
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
  • Loading branch information
BurntSushi committed Jul 8, 2023
1 parent 3d83ead commit f291fac
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 0 deletions.
28 changes: 28 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down
28 changes: 28 additions & 0 deletions pkg/windows/Manifest.xml
Original file line number Diff line number Diff line change
@@ -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>
15 changes: 15 additions & 0 deletions pkg/windows/README.md
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit f291fac

Please sign in to comment.