Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Draft] Windows: Add longPathAware manifest file #1898

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,13 @@ jobs:
echo "target dir is: ${{ env.TARGET_DIR }}"

- name: Build release binary
if: matrix.build != 'win-msvc' && matrix.build != 'win32-msvc'
run: ${{ env.CARGO }} build --verbose --release --features pcre2 ${{ env.TARGET_FLAGS }}

# On Windows MSVC, embed the application manifest.
- name: Build release binary
if: matrix.build == 'win-msvc' || matrix.build == 'win32-msvc'
run: ${{ env.CARGO }} rustc --verbose --release --features pcre2 ${{ env.TARGET_FLAGS }} -- -C link-arg="/MANIFEST:EMBED" -C link-arg="/MANIFESTINPUT:windows/manifest.xml"

- name: Strip release binary (linux and macos)
if: matrix.build == 'linux' || matrix.build == 'macos'
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,13 @@ If you're a **Rust programmer**, ripgrep can be installed with `cargo`.
$ cargo install ripgrep
```

### Windows long path support

By default, Windows paths are limited to 260 characters.
Long paths are supported in Windows 10 version 1607 or later but requires you to opt-in.
To do this download and then open the [LongPathsEnabled.reg](LongPathsEnabled.reg) file.

The version of ripgrep you use must also be built with long path support enabled.

### Building

Expand All @@ -360,6 +367,17 @@ $ ./target/release/rg --version
0.1.3
```

To build ripgrep with Windows long path support, use `windows/build` instead of `cargo build`.
This requires using an MSVC compatible toolchain.

```
$ cd ripgrep
$ windows/build --release
$ ./target/release/rg --version
0.1.3
```


If you have a Rust nightly compiler and a recent Intel CPU, then you can enable
additional optional SIMD acceleration like so:

Expand Down
4 changes: 4 additions & 0 deletions windows/LongPathsEnabled.reg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem]
"LongPathsEnabled"=dword:00000001
49 changes: 49 additions & 0 deletions windows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Windows application metadata

By default Windows has very strict backwards compatibility requirements to ensure old applications don't break on modern Windows.
However, sometimes it's desirable to make breaking changes.

[Application manifests](https://docs.microsoft.com/en-us/windows/win32/sbscs/application-manifests) provide a way to do both.
Older application without a manifest will continue to have the old, backwards compatible, behaviour.
Newer applications can use the manifest to opt in to new features.

A feature of particular use to ripgrep is long path support.

## Windows long paths

Newer versions of Windows 10 allow applications to use longer paths without making any changes to the way they use the Windows API. Unfortunately enabling this setting requires both the application and the user to opt in to this behaviour.

## Making ripgrep `longPathAware`

The `longPathAware` setting is enabled in the [manifest](manifest.xml). Building ripgrep with this manifest requires the following black magic (and an MSVC compatible linker):

```
cargo rustc --release -- -C link-arg="/MANIFEST:EMBED" -C link-arg="/MANIFESTINPUT:windows/manifest.xml"
```

However, even then this setting will be ignored unless the user has allowed long path support.

## Enabling long paths on your OS

For this to work you will need to be using Windows 10 version 1607 or later and have admin rights.

It requires setting a registry entry, which can be done in one of the following ways:

### Using a `.reg` file

Simply download and then open the [LongPathsEnabled.reg](LongPathsEnabled.reg) file.

### Using the Group Policy Editor

Run `gpedit.msc`. Navigate to and enable:

Computer Configuration > Administrative Templates > System > Filesystem > Enable Win32 long paths

### Using an administrator powershell

Run powershell as admin and use the following command:

```ps
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" `
-Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
```
4 changes: 4 additions & 0 deletions windows/build.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
:: Automatically embed the manifest file on Windows MSVC.
:: Any arguments are passed through this script to `cargo rustc`.
@echo off
cargo rustc %* -- -C link-arg="/MANIFEST:EMBED" -C link-arg="/MANIFESTINPUT:%~dp0manifest.xml"
42 changes: 42 additions & 0 deletions windows/manifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
This file is an application manifest for Windows binaries.
The format is documented at: 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">
<!-- Uniquely identifiy the application (name + version) -->
<assemblyIdentity
type="win32"
name="BurntSushi.github.ripgrep"
version="0.0.0.0"
/>

<!-- Supported OS versions -->
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<!--
When a new version of Windows comes out, the new identifier will be listed here:
https://docs.microsoft.com/en-us/windows/win32/sbscs/application-manifests#supportedos
-->
<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 --><supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>

<!-- Application settings -->
<asmv3:application>
<asmv3:windowsSettings
xmlns:ws16="http://schemas.microsoft.com/SMI/2016/WindowsSettings"
xmlns:ws19="http://schemas.microsoft.com/SMI/2019/WindowsSettings"
>
<!--
Allows using longer paths without special handling
See: https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd#enable-long-paths-in-windows-10-version-1607-and-later
-->
<ws16:longPathAware>true</ws16:longPathAware>
<ws19:activeCodePage>UTF-8</ws19:activeCodePage>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>