build_web: use rustup's cargo even when another Rust comes first on PATH
A standalone "Rust stable GNU" install ahead of ~/.cargo/bin made cargo fail with E0463 (no wasm32 std). The script now puts CARGO_HOME/bin first, checks for rustup and the wasm32 target, and says what to install.
This commit is contained in:
1 parent
5eb60d2a0c
commit
34a77892c9
1 file changed
+46
-16
+46
-16
@@ -2,10 +2,11 @@
|
||||
|
||||
python tools/build_web.py [--out dist/web] [--skip-cargo]
|
||||
|
||||
Needs the wasm32-unknown-unknown target (rustup target add wasm32-unknown-unknown)
|
||||
and the wasm-bindgen CLI at the version in Cargo.lock. wasm-opt (binaryen) is
|
||||
used when it is on PATH. The output folder is static files: serve it from any
|
||||
web server (it needs http(s), not file://).
|
||||
Needs rustup with the wasm32-unknown-unknown target (rustup target add
|
||||
wasm32-unknown-unknown) and the wasm-bindgen CLI at the version in Cargo.lock.
|
||||
rustup's cargo is used even when another Rust install comes first on PATH.
|
||||
wasm-opt (binaryen) is used when it is on PATH. The output folder is static
|
||||
files: serve it from any web server (it needs http(s), not file://).
|
||||
"""
|
||||
import argparse
|
||||
import hashlib
|
||||
@@ -19,11 +20,44 @@ from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
SKIP_DIRS = {"dist", "target", "node_modules"}
|
||||
TARGET = "wasm32-unknown-unknown"
|
||||
|
||||
# rustup's bin folder first: a standalone Rust install earlier on PATH (one
|
||||
# without the wasm target, e.g. "Rust stable GNU") must not win
|
||||
CARGO_BIN = Path(os.environ.get("CARGO_HOME") or Path.home() / ".cargo") / "bin"
|
||||
ENV = dict(os.environ)
|
||||
if CARGO_BIN.is_dir():
|
||||
ENV["PATH"] = str(CARGO_BIN) + os.pathsep + ENV.get("PATH", "")
|
||||
|
||||
|
||||
def tool(name):
|
||||
return shutil.which(name, path=ENV["PATH"])
|
||||
|
||||
|
||||
def run(cmd, **kw):
|
||||
print("+", " ".join(str(c) for c in cmd), flush=True)
|
||||
subprocess.run([str(c) for c in cmd], check=True, cwd=ROOT, **kw)
|
||||
subprocess.run([str(c) for c in cmd], check=True, cwd=ROOT, env=ENV, **kw)
|
||||
|
||||
|
||||
def check_toolchain():
|
||||
"""rustup with the wasm target, and wasm-bindgen at the locked version."""
|
||||
rustup = tool("rustup")
|
||||
if not rustup:
|
||||
sys.exit("rustup not found (https://rustup.rs): the WASM build needs rustup's toolchain")
|
||||
installed = subprocess.run([rustup, "target", "list", "--installed"], capture_output=True, text=True,
|
||||
cwd=ROOT, env=ENV).stdout.split()
|
||||
if TARGET not in installed:
|
||||
sys.exit(f"the {TARGET} target is not installed: rustup target add {TARGET}")
|
||||
cargo = tool("cargo")
|
||||
if not cargo or Path(cargo).parent.resolve() != CARGO_BIN.resolve():
|
||||
sys.exit(f"cargo resolves to {cargo}, not rustup's in {CARGO_BIN}")
|
||||
want = lock_version("wasm-bindgen")
|
||||
exe = tool("wasm-bindgen")
|
||||
if not exe:
|
||||
sys.exit(f"wasm-bindgen CLI not found: cargo install wasm-bindgen-cli --version {want}")
|
||||
have = subprocess.run([exe, "--version"], capture_output=True, text=True, env=ENV).stdout.split()[-1]
|
||||
if have != want:
|
||||
sys.exit(f"wasm-bindgen CLI is {have}, Cargo.lock has {want}: cargo install wasm-bindgen-cli --version {want}")
|
||||
|
||||
|
||||
def lock_version(name):
|
||||
@@ -63,25 +97,21 @@ def main():
|
||||
wasm = ROOT / "target" / "wasm32-unknown-unknown" / "web" / "isokit_wasm.wasm"
|
||||
|
||||
if not a.skip_cargo:
|
||||
want = lock_version("wasm-bindgen")
|
||||
try:
|
||||
have = subprocess.run(["wasm-bindgen", "--version"], capture_output=True, text=True, check=True).stdout.split()[-1]
|
||||
except (OSError, subprocess.CalledProcessError):
|
||||
sys.exit(f"wasm-bindgen CLI not found: cargo install wasm-bindgen-cli --version {want}")
|
||||
if have != want:
|
||||
sys.exit(f"wasm-bindgen CLI is {have}, Cargo.lock has {want}: cargo install wasm-bindgen-cli --version {want}")
|
||||
run(["cargo", "build", "-p", "isokit-wasm", "--target", "wasm32-unknown-unknown", "--profile", "web"])
|
||||
check_toolchain()
|
||||
run([tool("cargo"), "build", "-p", "isokit-wasm", "--target", TARGET, "--profile", "web"])
|
||||
elif not tool("wasm-bindgen"):
|
||||
sys.exit("wasm-bindgen CLI not found")
|
||||
|
||||
if out.exists():
|
||||
shutil.rmtree(out)
|
||||
web.mkdir(parents=True)
|
||||
if not wasm.exists():
|
||||
sys.exit(f"{wasm} missing: run without --skip-cargo")
|
||||
run(["wasm-bindgen", "--target", "web", "--no-typescript", "--remove-name-section",
|
||||
run([tool("wasm-bindgen"), "--target", "web", "--no-typescript", "--remove-name-section",
|
||||
"--remove-producers-section", "--out-dir", web.as_posix(), wasm.as_posix()])
|
||||
bg = web / "isokit_wasm_bg.wasm"
|
||||
if shutil.which("wasm-opt"):
|
||||
run(["wasm-opt", "-Oz", "--all-features", bg.as_posix(), "-o", bg.as_posix()])
|
||||
if tool("wasm-opt"):
|
||||
run([tool("wasm-opt"), "-Oz", "--all-features", bg.as_posix(), "-o", bg.as_posix()])
|
||||
else:
|
||||
print(" (wasm-opt not found: the .wasm stays unoptimised by binaryen, about 15% larger)")
|
||||
|
||||
|
||||
Reference in new issue
Block a user