Link sketch.o + libfastled.a → fastled.js + fastled.wasm. Two-tier linking strategy: 1. Fast path: reuse cached JS glue + run wasm-ld directly (~0.2s) 2. Full path: run emcc to generate JS glue + wasm (~1.1s), then cache The JS glue is identical across all sketches (no EM_ASM/
(
sketch_object: Path,
build_dir: Path,
sketch_cache_dir: Path,
output_js: Path,
mode: str,
verbose: bool = False,
)
| 1445 | |
| 1446 | |
| 1447 | def link_wasm( |
| 1448 | sketch_object: Path, |
| 1449 | build_dir: Path, |
| 1450 | sketch_cache_dir: Path, |
| 1451 | output_js: Path, |
| 1452 | mode: str, |
| 1453 | verbose: bool = False, |
| 1454 | ) -> bool: |
| 1455 | """ |
| 1456 | Link sketch.o + libfastled.a → fastled.js + fastled.wasm. |
| 1457 | |
| 1458 | Two-tier linking strategy: |
| 1459 | 1. Fast path: reuse cached JS glue + run wasm-ld directly (~0.2s) |
| 1460 | 2. Full path: run emcc to generate JS glue + wasm (~1.1s), then cache |
| 1461 | |
| 1462 | The JS glue is identical across all sketches (no EM_ASM/EM_JS), so after |
| 1463 | one full link the JS is cached and subsequent links skip emcc entirely. |
| 1464 | |
| 1465 | Returns True on success. |
| 1466 | """ |
| 1467 | library_archive = build_dir / "ci" / "meson" / "wasm" / "libfastled.a" |
| 1468 | |
| 1469 | if not library_archive.exists(): |
| 1470 | print(f"[WASM] Library not found: {library_archive}") |
| 1471 | return False |
| 1472 | |
| 1473 | # Intermediate linked output in per-sketch cache |
| 1474 | cached_js = sketch_cache_dir / "fastled.js" |
| 1475 | cached_wasm = sketch_cache_dir / "fastled.wasm" |
| 1476 | |
| 1477 | # Check if linking needed (compare inputs vs cached output) |
| 1478 | if cached_js.exists() and cached_wasm.exists(): |
| 1479 | output_mtime = min(cached_js.stat().st_mtime, cached_wasm.stat().st_mtime) |
| 1480 | inputs_newer = ( |
| 1481 | sketch_object.stat().st_mtime > output_mtime |
| 1482 | or library_archive.stat().st_mtime > output_mtime |
| 1483 | ) |
| 1484 | if not inputs_newer: |
| 1485 | _copy_linked_output(sketch_cache_dir, output_js) |
| 1486 | print("[WASM] Link output up-to-date (cached)") |
| 1487 | return True |
| 1488 | |
| 1489 | # Fast path: reuse cached JS glue + run wasm-ld directly. |
| 1490 | # Disabled when asyncify is active — asyncify is a Binaryen pass that |
| 1491 | # only runs through emcc, not wasm-ld. |
| 1492 | # Also disabled when SEPARATE_DWARF_URL is used — emcc handles DWARF |
| 1493 | # extraction as a post-link step that wasm-ld alone cannot perform. |
| 1494 | link_flags = get_link_flags(mode) |
| 1495 | uses_asyncify = any("ASYNCIFY" in f for f in link_flags) |
| 1496 | needs_separate_dwarf = any("SEPARATE_DWARF" in f for f in link_flags) |
| 1497 | if not uses_asyncify and not needs_separate_dwarf: |
| 1498 | if _fast_link( |
| 1499 | sketch_object, cached_wasm, build_dir, mode, library_archive, verbose |
| 1500 | ): |
| 1501 | _copy_linked_output(sketch_cache_dir, output_js) |
| 1502 | print(f"[WASM] Output: {output_js}") |
| 1503 | return True |
| 1504 |
no test coverage detected