Feat: try again
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user