Generate the WASM Meson cross-file with resolved compiler paths. clang-tool-chain >=1.5.5 is pinned and guarantees all seven native launchers; if resolution fails the function raises (no Python-wrapper fallback). Side effects: sets ``EMCC_WASM_LD`` in os.environ pointing at the
(build_dir: Path)
| 555 | |
| 556 | |
| 557 | def _render_wasm_cross_file(build_dir: Path) -> Path: |
| 558 | """Generate the WASM Meson cross-file with resolved compiler paths. |
| 559 | |
| 560 | clang-tool-chain >=1.5.5 is pinned and guarantees all seven native |
| 561 | launchers; if resolution fails the function raises (no Python-wrapper |
| 562 | fallback). |
| 563 | |
| 564 | Side effects: sets ``EMCC_WASM_LD`` in os.environ pointing at the |
| 565 | resolved ctc-wasm-ld so emcc's internal linker invocation goes through |
| 566 | it WHEN emcc.py is imported (cold-link path). The actual patch |
| 567 | verification moved to ``run_emcc()`` in 1.5.5 — that's the only place |
| 568 | emcc.py is read in-process, and gating the patch check there avoids |
| 569 | paying ~1 ms on every warm build invocation just to confirm a |
| 570 | 1.5.5-marker-file flag. |
| 571 | """ |
| 572 | from ci.meson.build_config import resolve_wasm_native_entries |
| 573 | |
| 574 | entries = resolve_wasm_native_entries(PROJECT_ROOT) |
| 575 | os.environ["EMCC_WASM_LD"] = entries.wasm_ld |
| 576 | |
| 577 | print(f"[WASM] Using native ctc-emcc launcher: {entries.c}") |
| 578 | for label, path in ( |
| 579 | ("emar", entries.ar), |
| 580 | ("emstrip", entries.strip), |
| 581 | ("emranlib", entries.ranlib), |
| 582 | ("emnm", entries.nm), |
| 583 | ("wasm-ld", entries.wasm_ld), |
| 584 | ): |
| 585 | print(f"[WASM] Using native ctc-{label} launcher: {path}") |
| 586 | |
| 587 | c_val = _escape_meson_string(entries.c) |
| 588 | cpp_val = _escape_meson_string(entries.cpp) |
| 589 | ar_val = _escape_meson_string(entries.ar) |
| 590 | strip_val = _escape_meson_string(entries.strip) |
| 591 | ranlib_val = _escape_meson_string(entries.ranlib) |
| 592 | nm_val = _escape_meson_string(entries.nm) |
| 593 | |
| 594 | content = ( |
| 595 | "# ============================================================================\n" |
| 596 | "# Meson Cross-Compilation File for Emscripten (WASM) [AUTO-GENERATED]\n" |
| 597 | "# ============================================================================\n" |
| 598 | "# Auto-generated by ci/wasm_build.py:_render_wasm_cross_file().\n" |
| 599 | "# DO NOT EDIT — edit ci/meson/wasm_cross_file.ini (static template)\n" |
| 600 | "# and the generator instead.\n" |
| 601 | "#\n" |
| 602 | "# The [binaries] section is dynamically resolved so we can point\n" |
| 603 | "# meson at compiled ctc-* native launchers (near-zero startup) when\n" |
| 604 | "# available, with automatic fallback to the clang-tool-chain Python\n" |
| 605 | "# wrappers otherwise.\n" |
| 606 | "# ============================================================================\n" |
| 607 | "\n" |
| 608 | "[binaries]\n" |
| 609 | f"c = '{c_val}'\n" |
| 610 | f"cpp = '{cpp_val}'\n" |
| 611 | f"ar = '{ar_val}'\n" |
| 612 | f"strip = '{strip_val}'\n" |
| 613 | f"ranlib = '{ranlib_val}'\n" |
| 614 | f"nm = '{nm_val}'\n" |