fix(pm): prepare the Windows ARM64 compiler environment for every source dependency build
cryptography ships no win_arm64 wheel, so every Windows ARM64 venv sync compiles it from the sdist and needs MSVC, Clang, Rust and static OpenSSL. Only setup-hermes.ps1 (and so activate.ps1) prepared that environment, between a `pm install --tools-only` and the real sync. install.ps1, `hermes update` and repair ran the same sync without it and failed in openssl-sys. PM owns the sync, so PM prepares it. pm/native_build.py holds the adapter (moved from scripts/build/windows_deps.py) plus source_build_environment(), which prepares only on win32-arm64 when the synced project carries the provider script. A payload has prebuilt dependencies and needs no compiler. VenvPackage.apply and build_environment pass the result to uv children only. It carries the bridged pip index settings, which managed_environment applies only to the ambient environment. The state root stays the store parent, so existing vcpkg/OpenSSL builds are reused. setup-hermes.ps1 collapses to one `pm install`: the tools-only split existed only for this preparation, and pm install already puts its tools on PATH before the venv sync (pm/cli.py activate check). Not yet verified live on Windows ARM64.
This commit is contained in:
@@ -288,8 +288,10 @@ save. The packaged `uv-cache/` is a copy, not the writable build cache.
|
||||
### Windows ARM64 build prerequisites
|
||||
|
||||
`scripts/windows-build-deps.ps1` owns Visual Studio ARM64, Clang, Rust, and
|
||||
static OpenSSL preparation. Source setup calls its initializer. Native build
|
||||
adapters use `scripts/build/windows-deps.ps1` through `windows_deps.py`, before
|
||||
static OpenSSL preparation. PM calls it through `pm/native_build.py` before any
|
||||
dependency build from a checkout, so every source install path gets it. Native
|
||||
build adapters use the same `scripts/build/windows-deps.ps1` entrypoint through
|
||||
`pm.native_build`, before
|
||||
isolating HOME or compiling Node/Python dependencies. CI uses the same script
|
||||
through `setup-windows-build-deps`, with an OpenSSL cache outside the product.
|
||||
The product compilers and assembler do not install these prerequisites.
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
"""Prepare native Windows build inputs without changing the caller's process."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
import json
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
|
||||
def prepare_windows_environment(*, source: Path, state: Path, env: Mapping[str, str]) -> dict[str, str]:
|
||||
"""The distribution adapter decides whether this target needs ARM64 tools."""
|
||||
shell = shutil.which("powershell", path=env.get("PATH")) or shutil.which("pwsh", path=env.get("PATH"))
|
||||
if shell is None:
|
||||
raise FileNotFoundError("PowerShell is required to prepare Windows ARM64 build dependencies")
|
||||
state.mkdir(parents=True, exist_ok=True)
|
||||
with tempfile.TemporaryDirectory(prefix="environment-", dir=state) as scratch:
|
||||
output = Path(scratch) / "environment.json"
|
||||
subprocess.run(
|
||||
[shell, "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File",
|
||||
str(source / "scripts/build/windows-deps.ps1"), "-StateRoot", str(state),
|
||||
"-EnvironmentFile", str(output)],
|
||||
cwd=source, env=dict(env), check=True,
|
||||
)
|
||||
prepared = json.loads(output.read_text(encoding="utf-8-sig"))
|
||||
if not isinstance(prepared, dict) or any(not isinstance(k, str) or not isinstance(v, str) for k, v in prepared.items()):
|
||||
raise ValueError("Windows build dependency provider returned an invalid environment")
|
||||
return prepared
|
||||
@@ -100,7 +100,7 @@ def prepare_tools(source: Path, work: Path, cache: Path,
|
||||
raise ValueError("desktop tools require the isolated preparation worker")
|
||||
prepared = dict(env)
|
||||
if pm.current_target() == "win32-arm64":
|
||||
from scripts.build.windows_deps import prepare_windows_environment
|
||||
from pm.native_build import prepare_windows_environment
|
||||
|
||||
prepared = prepare_windows_environment(source=source, state=cache / "native/prerequisites", env=prepared)
|
||||
if pm.current_target().startswith("darwin"):
|
||||
|
||||
@@ -106,7 +106,7 @@ def stage_native(args) -> int:
|
||||
cache = Path(getattr(args, "cache", None) or os.environ.get("UV_CACHE_DIR") or uv_cache_dir()).resolve()
|
||||
base_env = dict(os.environ)
|
||||
if current_target() == "win32-arm64":
|
||||
from scripts.build.windows_deps import prepare_windows_environment
|
||||
from pm.native_build import prepare_windows_environment
|
||||
|
||||
base_env = prepare_windows_environment(source=root, state=out.parent / ".build-deps", env=base_env)
|
||||
# Rustup resolves its installed toolchain under HOME unless these are explicit.
|
||||
|
||||
@@ -29,7 +29,7 @@ _INPUT_FILES = (
|
||||
"scripts/bundles/desktop_inputs.py", "scripts/bundles/native.py", "scripts/bundles/native_prepared.py",
|
||||
"scripts/bundles/native_build.py",
|
||||
"scripts/build/node-deps.mjs", "scripts/build/icon_environment.py",
|
||||
"scripts/build/windows_deps.py", "scripts/windows-build-deps.ps1",
|
||||
"pm/native_build.py", "scripts/windows-build-deps.ps1",
|
||||
"apps/desktop/scripts/stage-native-deps.mjs", "apps/desktop/scripts/prepare-packaging-tools.mjs",
|
||||
"apps/desktop/scripts/build-command-screenshot-monitor.mjs",
|
||||
"apps/desktop/scripts/build-hud-modifier-monitor.mjs",
|
||||
|
||||
Reference in New Issue
Block a user