mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-11-06 13:26:40 +00:00
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:
1 parent
f30e86c665
commit
fdea3e92e0
2 files changed
+60
No files matched your search
@@ -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":
|
||||
|
||||
@@ -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")
|
||||
Reference in new issue
Block a user