Feat: big movement for ASIO
This commit is contained in:
100
scripts/build.py
100
scripts/build.py
@@ -3,7 +3,7 @@
|
||||
# requires-python = ">=3.11"
|
||||
# dependencies = ["rich>=13.0", "questionary>=2.0"]
|
||||
# ///
|
||||
"""Cagire release builder — replaces build-all.sh, make-dmg.sh, make-appimage.sh."""
|
||||
"""Cagire release builder."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -150,6 +150,8 @@ def get_version(root: Path) -> str:
|
||||
|
||||
|
||||
def builder_for(p: Platform) -> str:
|
||||
if p.os == "windows" and p.cross:
|
||||
return "cargo-xwin"
|
||||
return "cross" if p.cross else "cargo"
|
||||
|
||||
|
||||
@@ -195,12 +197,31 @@ def run_cmd(
|
||||
# Build functions
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _macos_env(p: Platform) -> dict[str, str] | None:
|
||||
if p.os == "macos":
|
||||
return {"MACOSX_DEPLOYMENT_TARGET": "12.0"}
|
||||
def _find_llvm_prefix() -> str | None:
|
||||
"""Find Homebrew LLVM installation path."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["brew", "--prefix", "llvm"], capture_output=True, text=True,
|
||||
)
|
||||
if result.returncode == 0:
|
||||
return result.stdout.strip()
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def _cross_env(p: Platform) -> dict[str, str] | None:
|
||||
env = {}
|
||||
if p.os == "macos":
|
||||
env["MACOSX_DEPLOYMENT_TARGET"] = "12.0"
|
||||
if p.os == "windows" and p.cross:
|
||||
env["VCINSTALLDIR"] = "/dummy"
|
||||
llvm_prefix = _find_llvm_prefix()
|
||||
if llvm_prefix:
|
||||
env["LIBCLANG_PATH"] = f"{llvm_prefix}/lib"
|
||||
return env or None
|
||||
|
||||
|
||||
def _platform_features(p: Platform) -> list[str]:
|
||||
if p.os == "windows":
|
||||
return ["--features", "asio"]
|
||||
@@ -211,7 +232,7 @@ def build_binary(root: Path, p: Platform, log: list[str], extra_args: list[str]
|
||||
features = _platform_features(p) if platform_features else []
|
||||
cmd = [builder_for(p), "build", "--release", *target_flags(p), *features, *(extra_args or [])]
|
||||
log.append(f" Building: {' '.join(extra_args or ['default'])}")
|
||||
run_cmd(cmd, log, env=_macos_env(p), cwd=root)
|
||||
run_cmd(cmd, log, env=_cross_env(p), cwd=root)
|
||||
|
||||
|
||||
def bundle_plugins(root: Path, p: Platform, log: list[str]) -> None:
|
||||
@@ -224,7 +245,7 @@ def bundle_plugins(root: Path, p: Platform, log: list[str]) -> None:
|
||||
def _bundle_plugins_native(root: Path, p: Platform, log: list[str]) -> None:
|
||||
log.append(" Bundling plugins (native xtask)")
|
||||
cmd = ["cargo", "xtask", "bundle", PLUGIN_NAME, "--release", *target_flags(p)]
|
||||
run_cmd(cmd, log, env=_macos_env(p), cwd=root)
|
||||
run_cmd(cmd, log, env=_cross_env(p), cwd=root)
|
||||
|
||||
|
||||
def _bundle_plugins_cross(root: Path, p: Platform, log: list[str]) -> None:
|
||||
@@ -267,7 +288,7 @@ def bundle_desktop_app(root: Path, p: Platform, log: list[str]) -> None:
|
||||
return
|
||||
log.append(" Bundling desktop .app")
|
||||
cmd = ["cargo", "bundle", "--release", "--features", "desktop", "--bin", "cagire-desktop", *target_flags(p)]
|
||||
run_cmd(cmd, log, env=_macos_env(p), cwd=root)
|
||||
run_cmd(cmd, log, env=_cross_env(p), cwd=root)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -444,36 +465,6 @@ def make_appimage(root: Path, binary: Path, arch: str, output_dir: Path, log: li
|
||||
return _make_appimage_docker(root, binary, arch, output_dir, log)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Packaging: NSIS
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def make_nsis(root: Path, rd: Path, version: str, output_dir: Path, config: BuildConfig, log: list[str]) -> str | None:
|
||||
if not shutil.which("makensis"):
|
||||
log.append(" makensis not found, skipping NSIS installer")
|
||||
return None
|
||||
|
||||
log.append(" Building NSIS installer")
|
||||
abs_root = str(root.resolve())
|
||||
cmd = [
|
||||
"makensis",
|
||||
f"-DVERSION={version}",
|
||||
f"-DICON={abs_root}/assets/Cagire.ico",
|
||||
f"-DOUTDIR={abs_root}/{OUT}",
|
||||
]
|
||||
if config.cli:
|
||||
cmd.append(f"-DCLI_EXE={abs_root}/{rd.relative_to(root)}/cagire.exe")
|
||||
if config.desktop:
|
||||
cmd.append(f"-DDESKTOP_EXE={abs_root}/{rd.relative_to(root)}/cagire-desktop.exe")
|
||||
cmd.append(str(root / "nsis" / "cagire.nsi"))
|
||||
run_cmd(cmd, log)
|
||||
|
||||
installer = f"cagire-{version}-windows-x86_64-setup.exe"
|
||||
log.append(f" Installer -> {output_dir / installer}")
|
||||
return str(output_dir / installer)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Artifact copying & packaging dispatch
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -483,7 +474,6 @@ def copy_artifacts(root: Path, p: Platform, config: BuildConfig, log: list[str])
|
||||
rd = release_dir(root, p)
|
||||
out = root / OUT
|
||||
sx = suffix_for(p)
|
||||
version = get_version(root)
|
||||
artifacts: list[str] = []
|
||||
|
||||
if config.cli:
|
||||
@@ -515,11 +505,6 @@ def copy_artifacts(root: Path, p: Platform, config: BuildConfig, log: list[str])
|
||||
if dmg:
|
||||
artifacts.append(dmg)
|
||||
|
||||
if p.os == "windows":
|
||||
nsis = make_nsis(root, rd, version, out, config, log)
|
||||
if nsis:
|
||||
artifacts.append(nsis)
|
||||
|
||||
if p.os == "linux":
|
||||
if config.cli:
|
||||
ai = make_appimage(root, rd / "cagire", p.arch, out, log)
|
||||
@@ -725,9 +710,10 @@ def run_builds(
|
||||
for p in platforms:
|
||||
_update_phase(p.alias, "waiting", 0)
|
||||
|
||||
# Split into native (share cargo lock) and cross (independent Docker builds)
|
||||
native_platforms = [p for p in platforms if not p.cross]
|
||||
cross_platforms = [p for p in platforms if p.cross]
|
||||
# Docker-isolated cross builds (Linux only — each in its own container)
|
||||
docker_cross = [p for p in platforms if p.cross and p.os != "windows"]
|
||||
# Local builds share cargo lock — run sequentially
|
||||
local_builds = [p for p in platforms if not p.cross or p.os == "windows"]
|
||||
|
||||
results: list[PlatformResult] = []
|
||||
completed: dict[str, PlatformResult] = {}
|
||||
@@ -740,19 +726,19 @@ def run_builds(
|
||||
return _build_display(platforms, config, completed, start_times, log_max_lines)
|
||||
|
||||
with Live(make_display(), console=console, refresh_per_second=4) as live:
|
||||
# Native builds run sequentially in one thread (they contend on cargo lock).
|
||||
# Cross builds run in parallel (each in its own Docker container).
|
||||
with ThreadPoolExecutor(max_workers=max(len(cross_platforms) + 1, 1)) as pool:
|
||||
# Local builds run sequentially (they contend on cargo lock).
|
||||
# Docker cross builds run in parallel (each in its own container).
|
||||
with ThreadPoolExecutor(max_workers=max(len(docker_cross) + 1, 1)) as pool:
|
||||
futures = {}
|
||||
|
||||
if native_platforms:
|
||||
if local_builds:
|
||||
f = pool.submit(
|
||||
_build_native_sequential, root, native_platforms, config,
|
||||
_build_native_sequential, root, local_builds, config,
|
||||
completed, start_times,
|
||||
)
|
||||
futures[f] = "native"
|
||||
|
||||
for p in cross_platforms:
|
||||
for p in docker_cross:
|
||||
f = pool.submit(build_platform, root, p, config)
|
||||
futures[f] = "cross"
|
||||
|
||||
@@ -928,20 +914,22 @@ def check_git_clean(root: Path) -> tuple[str, bool]:
|
||||
|
||||
def check_prerequisites(platforms: list[Platform], config: BuildConfig) -> None:
|
||||
"""Verify required tools are available, fail fast if not."""
|
||||
need_cross = any(p.cross for p in platforms)
|
||||
need_xwin = any(p.os == "windows" and p.cross for p in platforms)
|
||||
need_cross = any(p.cross and p.os != "windows" for p in platforms)
|
||||
need_docker = any(p.cross and p.os == "linux" for p in platforms)
|
||||
need_bundle = config.desktop and any(not p.cross and p.os == "macos" for p in platforms)
|
||||
need_nsis = any(p.os == "windows" for p in platforms)
|
||||
|
||||
checks: list[tuple[str, bool]] = [("cargo", True)]
|
||||
if need_xwin:
|
||||
checks.append(("cargo-xwin", True))
|
||||
checks.append(("clang", True))
|
||||
checks.append(("cmake", True))
|
||||
if need_cross:
|
||||
checks.append(("cross", True))
|
||||
if need_docker:
|
||||
checks.append(("docker", True))
|
||||
if need_bundle:
|
||||
checks.append(("cargo-bundle", True))
|
||||
if need_nsis:
|
||||
checks.append(("makensis", False))
|
||||
|
||||
console.print("[bold]Prerequisites:[/]")
|
||||
missing_critical: list[str] = []
|
||||
|
||||
Reference in New Issue
Block a user