meson: Serialize npm install for the agents

Parallel installs of the frida binding race on the prebuild cache, which
breaks the build on Windows.
This commit is contained in:
Ole André Vadla Ravnås committed 2026-11-07 17:28:41 +01:00
1 parent a67ebfd7dd
commit 6bbae44a5d
2 files changed
+35 -7

No files matched your search

+34 -6
View File
@@ -3,19 +3,22 @@ import platform
import shutil
import subprocess
import sys
import time
from contextlib import contextmanager
from pathlib import Path
from typing import List
def main(argv: List[str]):
npm = argv[1]
paths = [Path(p).resolve() for p in argv[2:]]
npm_lock = Path(argv[2])
paths = [Path(p).resolve() for p in argv[3:]]
inputs = paths[:-2]
output_js = paths[-2]
priv_dir = paths[-1]
try:
build(npm, inputs, output_js, priv_dir)
build(npm, npm_lock, inputs, output_js, priv_dir)
except subprocess.CalledProcessError as e:
print(e, file=sys.stderr)
print("Output:\n\t| " + "\n\t| ".join(e.output.strip().split("\n")), file=sys.stderr)
@@ -25,7 +28,7 @@ def main(argv: List[str]):
sys.exit(1)
def build(npm: Path, inputs: List[Path], output_js: Path, priv_dir: Path):
def build(npm: Path, npm_lock: Path, inputs: List[Path], output_js: Path, priv_dir: Path):
pkg_file = next((f for f in inputs if f.name == "package.json"))
pkg_parent = pkg_file.parent
entrypoint = inputs[0].relative_to(pkg_parent)
@@ -40,14 +43,39 @@ def build(npm: Path, inputs: List[Path], output_js: Path, priv_dir: Path):
shutil.copy(srcfile, dstfile)
subprocess.run(
[npm, "install"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding="utf-8", cwd=priv_dir, check=True
)
with exclusive_lock(npm_lock):
subprocess.run(
[npm, "install"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
encoding="utf-8",
cwd=priv_dir,
check=True,
)
frida_compile = priv_dir / "node_modules" / ".bin" / f"frida-compile{script_suffix()}"
subprocess.run([frida_compile, entrypoint, "-S", "-c", "-o", output_js], cwd=priv_dir, check=True)
@contextmanager
def exclusive_lock(path: Path):
with path.open("ab") as f:
if platform.system() == "Windows":
import msvcrt
while True:
try:
msvcrt.locking(f.fileno(), msvcrt.LK_LOCK, 1)
break
except OSError:
time.sleep(0.1)
else:
import fcntl
fcntl.flock(f, fcntl.LOCK_EX)
yield
def script_suffix() -> str:
return ".cmd" if platform.system() == "Windows" else ""
+1 -1
View File
@@ -1,4 +1,4 @@
build_agent = [python, files('build.py'), npm]
build_agent = [python, files('build.py'), npm, meson.current_build_dir() / 'npm-install.lock']
subdir('fs')
subdir('repl')