Fast compile using cached clang args, bypassing emcc Python overhead. On first compile, emcc is run with EMCC_VERBOSE=1 to capture the clang command it invokes internally. The command is saved as a template with {input_cpp} and {output_o} placeholders. Subsequent compiles call clang
(
wrapper_path: Path,
object_path: Path,
build_dir: Path,
emcc_args: list[str],
verbose: bool = False,
)
| 1008 | |
| 1009 | |
| 1010 | def _fast_compile( |
| 1011 | wrapper_path: Path, |
| 1012 | object_path: Path, |
| 1013 | build_dir: Path, |
| 1014 | emcc_args: list[str], |
| 1015 | verbose: bool = False, |
| 1016 | ) -> bool: |
| 1017 | """Fast compile using cached clang args, bypassing emcc Python overhead. |
| 1018 | |
| 1019 | On first compile, emcc is run with EMCC_VERBOSE=1 to capture the clang |
| 1020 | command it invokes internally. The command is saved as a template with |
| 1021 | {input_cpp} and {output_o} placeholders. Subsequent compiles call clang |
| 1022 | directly (~0.45s vs ~0.9s with emcc). |
| 1023 | |
| 1024 | Returns True on success, False to fall back to full emcc compile. |
| 1025 | """ |
| 1026 | cache_file = build_dir / "clang_compile_args.json" |
| 1027 | cache_key_file = build_dir / "clang_compile_args.key" |
| 1028 | if not cache_file.exists(): |
| 1029 | return False |
| 1030 | |
| 1031 | # Invalidate cache if emcc args changed (new defines, flags, etc.) |
| 1032 | current_key = _compile_cache_key(emcc_args) |
| 1033 | if cache_key_file.exists(): |
| 1034 | stored_key = cache_key_file.read_text(encoding="utf-8").strip() |
| 1035 | if stored_key != current_key: |
| 1036 | cache_file.unlink(missing_ok=True) |
| 1037 | cache_key_file.unlink(missing_ok=True) |
| 1038 | return False |
| 1039 | |
| 1040 | try: |
| 1041 | template_args: list[str] = json.loads(cache_file.read_text(encoding="utf-8")) |
| 1042 | except (json.JSONDecodeError, OSError): |
| 1043 | return False |
| 1044 | |
| 1045 | cmd: list[str] = [] |
| 1046 | for arg in template_args: |
| 1047 | arg = arg.replace("{input_cpp}", str(wrapper_path)) |
| 1048 | arg = arg.replace("{output_o}", str(object_path)) |
| 1049 | cmd.append(arg) |
| 1050 | |
| 1051 | if verbose: |
| 1052 | print(f"[WASM] Fast compile cmd: {cmd[:3]}...({len(cmd)} args)") |
| 1053 | |
| 1054 | try: |
| 1055 | result = subprocess.run(cmd, cwd=str(PROJECT_ROOT)) |
| 1056 | except OSError: |
| 1057 | # Executable not found (e.g. stale cache with bad path) — fall back |
| 1058 | cache_file.unlink(missing_ok=True) |
| 1059 | cache_key_file.unlink(missing_ok=True) |
| 1060 | return False |
| 1061 | if result.returncode != 0: |
| 1062 | # Cache might be stale — delete it so next run recaptures |
| 1063 | cache_file.unlink(missing_ok=True) |
| 1064 | cache_key_file.unlink(missing_ok=True) |
| 1065 | return False |
| 1066 | return True |
| 1067 |
no test coverage detected