Feat: try again

This commit is contained in:
2026-03-17 13:51:47 +01:00
parent 85cacfe53e
commit faf541e536
4 changed files with 78 additions and 7 deletions

View File

@@ -655,6 +655,55 @@ def _build_display(
return Group(table, log_text)
def _prebuild_cross_images(root: Path, platforms: list[Platform]) -> None:
"""Pre-build Docker images for cross-compiled targets in parallel."""
cross_platforms = [p for p in platforms if p.cross]
if not cross_platforms:
return
cross_toml = root / "Cross.toml"
if not cross_toml.exists():
return
with open(cross_toml, "rb") as f:
cross_config = tomllib.load(f)
def build_image(p: Platform) -> None:
target_cfg = cross_config.get("target", {}).get(p.triple, {})
dockerfile = target_cfg.get("dockerfile")
if not dockerfile:
return
tag = f"cross-custom-{p.triple}:local"
try:
subprocess.run(
["docker", "build", "-t", tag, "-f", str(root / dockerfile), str(root)],
capture_output=True, timeout=600,
)
except Exception:
pass # non-critical, cross will build if needed
console.print("[dim]Pre-building cross-compilation Docker images...[/]")
with ThreadPoolExecutor(max_workers=len(cross_platforms)) as pool:
pool.map(build_image, cross_platforms)
def _build_native_sequential(
root: Path,
native_platforms: list[Platform],
config: BuildConfig,
completed: dict[str, PlatformResult],
start_times: dict[str, float],
) -> list[PlatformResult]:
"""Build native platforms sequentially (they share the cargo target/ lock)."""
native_results = []
for p in native_platforms:
start_times[p.alias] = time.monotonic()
r = build_platform(root, p, config)
completed[r.platform.alias] = r
native_results.append(r)
return native_results
def run_builds(
root: Path, platforms: list[Platform], config: BuildConfig, version: str, verbose: bool = False,
) -> list[PlatformResult]:
@@ -665,6 +714,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]
results: list[PlatformResult] = []
completed: dict[str, PlatformResult] = {}
start_times: dict[str, float] = {p.alias: time.monotonic() for p in platforms}
@@ -676,15 +729,31 @@ 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:
with ThreadPoolExecutor(max_workers=len(platforms)) as pool:
futures = {pool.submit(build_platform, root, p, config): p for p in platforms}
# 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:
futures = {}
if native_platforms:
f = pool.submit(
_build_native_sequential, root, native_platforms, config,
completed, start_times,
)
futures[f] = "native"
for p in cross_platforms:
f = pool.submit(build_platform, root, p, config)
futures[f] = "cross"
pending = set(futures.keys())
while pending:
done = {f for f in pending if f.done()}
for f in done:
r = f.result()
completed[r.platform.alias] = r
results.append(r)
tag = futures[f]
if tag == "native":
results.extend(f.result())
else:
results.append(f.result())
pending.discard(f)
live.update(make_display())
if pending:
@@ -936,6 +1005,8 @@ def main() -> None:
check_prerequisites(platforms, config)
_prebuild_cross_images(root, platforms)
t0 = time.monotonic()
results = run_builds(root, platforms, config, version, verbose=args.verbose)
wall_time = time.monotonic() - t0