Skip to content

Commit 0514c9a

Browse files
committed
toolchain: Add mold
1 parent e7b9b8b commit 0514c9a

1 file changed

Lines changed: 53 additions & 2 deletions

File tree

toolchain/building.py

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ def _ci_group(title: str):
392392

393393

394394
# ---------------------------------------------------------------------------
395-
# Plan: download host tools (clang-format, clang-tidy static binaries)
395+
# Plan: download host tools (clang-format, clang-tidy static binaries, mold linker)
396396
# ---------------------------------------------------------------------------
397397

398398
def download_host_tools_plan(host: HostInfo, base_dir: Path) -> BuildPlan:
@@ -449,6 +449,55 @@ def _up_to_date(p=tool_path, s=stamp_path, sid=stamp_id) -> bool:
449449
skip_reason=f"stamp already at {stamp_id}",
450450
))
451451

452+
# mold linker (Linux hosts only)
453+
if host.os == "linux":
454+
mold_ver = "2.41.0"
455+
mold_stamp_id = f"v{mold_ver}"
456+
mold_arch = host.arch # "x86_64" or "aarch64"
457+
mold_tarball = f"mold-{mold_ver}-{mold_arch}-linux.tar.gz"
458+
mold_url = (
459+
f"https://github.com/rui314/mold/releases/download"
460+
f"/v{mold_ver}/{mold_tarball}"
461+
)
462+
mold_path = bin_dir / "mold"
463+
mold_stamp_path = bin_dir / "mold.version"
464+
465+
def _mold_up_to_date(p=mold_path, s=mold_stamp_path, sid=mold_stamp_id) -> bool:
466+
return p.exists() and s.exists() and s.read_text().strip() == sid
467+
468+
def _download_mold(
469+
bd=bin_dir, url=mold_url, ver=mold_ver, arch=mold_arch,
470+
p=mold_path, s=mold_stamp_path, sid=mold_stamp_id,
471+
) -> None:
472+
install_dir = bd.parent # multi_build/compilers/
473+
tarball = install_dir / f"mold-{ver}-{arch}-linux.tar.gz"
474+
subprocess.run(["wget", url, "-q", "-O", str(tarball)], check=True)
475+
# Extract bin/, lib/, and libexec/ — skip share/ (docs only).
476+
# --strip-components=1 drops the top-level "mold-X.Y.Z-arch-linux/"
477+
# prefix so bin/mold lands at multi_build/compilers/bin/mold and
478+
# mold can find lib/mold/mold-wrapper.so and libexec/mold/ld via
479+
# relative paths from its own location.
480+
subprocess.run(
481+
[
482+
"tar", "xf", str(tarball),
483+
"-C", str(install_dir),
484+
"--strip-components=1",
485+
"--exclude=*/share",
486+
],
487+
check=True,
488+
)
489+
tarball.unlink(missing_ok=True)
490+
p.chmod(p.stat().st_mode | 0o111)
491+
s.write_text(sid)
492+
493+
plan.add(PythonStep(
494+
name="download-mold",
495+
fn=_download_mold,
496+
description=f"Download and extract mold v{mold_ver} ({mold_arch}-linux)",
497+
skip_if=_mold_up_to_date,
498+
skip_reason=f"mold already at {mold_stamp_id}",
499+
))
500+
452501
return plan
453502

454503

@@ -1113,6 +1162,8 @@ def _env_for_target(target: TargetSpec, host: HostInfo, base_dir: Path) -> dict[
11131162
return env
11141163

11151164
env.update(_base_env(target, host, base_dir))
1165+
compilers_bin = base_dir / "multi_build/compilers/bin"
1166+
env["PATH"] = f"{compilers_bin}:{os.environ.get('PATH', '')}"
11161167

11171168
if target.platform == "web":
11181169
default_root = base_dir / "multi_build/compilers/emsdk"
@@ -1172,7 +1223,7 @@ def _env_for_target(target: TargetSpec, host: HostInfo, base_dir: Path) -> dict[
11721223
toolchain_sysroot = toolchain_root / toolchain_prefix / "sysroot"
11731224
env["TOOLCHAIN_ROOT"] = str(toolchain_root)
11741225
env["TOOLCHAIN_SYSROOT"] = str(toolchain_sysroot)
1175-
env["PATH"] = f"{toolchain_root / 'bin'}:{os.environ.get('PATH', '')}"
1226+
env["PATH"] = f"{toolchain_root / 'bin'}:{env.get('PATH', '')}"
11761227

11771228
return env
11781229

0 commit comments

Comments
 (0)