fix(pm): ship the VC++ runtime beside ARM64 Windows ripgrep

The aarch64-pc-windows-msvc rg.exe imports VCRUNTIME140.dll (the x64
build embeds the CRT). A fresh Windows, such as Windows Sandbox, has no
copy, so staging failed verification:

  rg.exe --version exited 3221225781   (0xC0000135, STATUS_DLL_NOT_FOUND)

Our pinned Python already ships the ARM64 vcruntime140.dll. Make ripgrep
depend on python and, on win32-arm64, copy that DLL into ripgrep's entry
before publication. The loader searches the exe's folder first, and the
entry digest covers the copy.
This commit is contained in:
ethernet committed 2026-09-24 11:21:47 -04:00
1 parent f30e86c665
commit fdea3e92e0
2 files changed
+60

No files matched your search

+23
View File
@@ -730,6 +730,29 @@ class Ffmpeg(_BionicDebArm, BinaryPackage, DebPackage):
class Ripgrep(BinaryPackage):
name = "ripgrep"
binary_rel = {"win32": "rg.exe", "posix": "rg"}
# The ARM64 Windows release links the VC++ runtime dynamically (the x64
# one embeds it), and a fresh Windows has no vcruntime140.dll: rg.exe
# dies with STATUS_DLL_NOT_FOUND. Our pinned Python ships the ARM64 DLL.
deps = ("python",)
def stage(self, store: Store, staged: Path, version: str, target: str) -> None:
super().stage(store, staged, version, target)
if target != "win32-arm64":
return
from pm.install import _installed_location, _lockfile
from pm.registry import get_package
python = get_package("python")
location = _installed_location(python, _lockfile(), target)
fact = location[0].get("python") if location is not None else None
if fact is None:
raise InstallError(self.name, "ARM64 rg.exe needs vcruntime140.dll from python, which is not installed")
runtime = location[1].entry(fact["entry"]) / "vcruntime140.dll"
if not runtime.is_file():
raise InstallError(self.name, f"python's entry has no {runtime.name}")
# App-local copy: the loader searches the exe's own folder first, and
# the entry digest is recorded over it.
shutil.copy2(runtime, staged / runtime.name)
def verify(self, entry: Path, target: str) -> str:
if target == "linux-arm64-bionic":
+37
View File
@@ -0,0 +1,37 @@
"""ARM64 Windows ripgrep carries the VC++ runtime it links against.
The aarch64-pc-windows-msvc rg.exe imports VCRUNTIME140.dll (the x64 build
embeds the CRT). A fresh Windows has no copy, so staging failed with
``rg.exe --version exited 3221225781`` (0xC0000135, STATUS_DLL_NOT_FOUND).
"""
from __future__ import annotations
import pm.install
from pm.registry import get_package, walk
from pm.store import Store
def test_arm64_windows_ripgrep_stages_pythons_vc_runtime_beside_rg(tmp_path, monkeypatch):
store = Store(tmp_path / "store")
runtime = store.entry("python-1") / "vcruntime140.dll"
runtime.parent.mkdir(parents=True)
runtime.write_bytes(b"arm64 vc runtime")
monkeypatch.setattr(pm.install, "_lockfile", lambda: None)
monkeypatch.setattr(pm.install, "_installed_location",
lambda package, lockfile, target: ({"python": {"entry": "python-1"}}, store))
staged = tmp_path / "scratch" / "tree"
wrapped = staged / "ripgrep-15.2.0-aarch64-pc-windows-msvc"
wrapped.mkdir(parents=True)
(wrapped / "rg.exe").write_bytes(b"rg")
get_package("ripgrep").stage(store, staged, "15.2.0", "win32-arm64")
assert (staged / "rg.exe").is_file()
assert (staged / "vcruntime140.dll").read_bytes() == runtime.read_bytes()
def test_python_installs_before_ripgrep_so_staging_can_read_it():
order = [package.name for package in walk(["ripgrep"])]
assert order.index("python") < order.index("ripgrep")