Compile the sketch wrapper to an object file. Two-tier compilation strategy: 1. Fast path: run clang directly (~0.45s), bypassing emcc Python overhead 2. Full path: run emcc with verbose capture (~0.9s), saves clang cmd for next time Sketch artifacts are cached per-sketch in s
(
wrapper_path: Path,
build_dir: Path,
sketch_cache_dir: Path,
mode: str,
verbose: bool = False,
)
| 1125 | |
| 1126 | |
| 1127 | def compile_sketch( |
| 1128 | wrapper_path: Path, |
| 1129 | build_dir: Path, |
| 1130 | sketch_cache_dir: Path, |
| 1131 | mode: str, |
| 1132 | verbose: bool = False, |
| 1133 | ) -> Path | None: |
| 1134 | """ |
| 1135 | Compile the sketch wrapper to an object file. |
| 1136 | |
| 1137 | Two-tier compilation strategy: |
| 1138 | 1. Fast path: run clang directly (~0.45s), bypassing emcc Python overhead |
| 1139 | 2. Full path: run emcc with verbose capture (~0.9s), saves clang cmd for next time |
| 1140 | |
| 1141 | Sketch artifacts are cached per-sketch in sketch_cache_dir. |
| 1142 | Returns path to the object file, or None on failure. |
| 1143 | """ |
| 1144 | object_path = sketch_cache_dir / "sketch.o" |
| 1145 | |
| 1146 | # Check if recompilation needed (mtime check against wrapper, .ino, extra .cpp, and library) |
| 1147 | library_archive = build_dir / "ci" / "meson" / "wasm" / "libfastled.a" |
| 1148 | # Find the .ino file that the wrapper #includes |
| 1149 | example_name = wrapper_path.stem.replace("_wrapper", "") |
| 1150 | example_dir = PROJECT_ROOT / "examples" / example_name |
| 1151 | ino_file = example_dir / f"{example_name}.ino" |
| 1152 | if object_path.exists(): |
| 1153 | object_mtime = object_path.stat().st_mtime |
| 1154 | wrapper_mtime = wrapper_path.stat().st_mtime |
| 1155 | ino_mtime = ino_file.stat().st_mtime if ino_file.exists() else 0 |
| 1156 | lib_mtime = library_archive.stat().st_mtime if library_archive.exists() else 0 |
| 1157 | # Check additional .cpp/.h files in the example directory tree |
| 1158 | extra_mtime = 0.0 |
| 1159 | for ext in ("*.cpp", "*.h"): |
| 1160 | for f in example_dir.rglob(ext): |
| 1161 | if ".build" not in f.parts: |
| 1162 | extra_mtime = max(extra_mtime, f.stat().st_mtime) |
| 1163 | if ( |
| 1164 | wrapper_mtime <= object_mtime |
| 1165 | and ino_mtime <= object_mtime |
| 1166 | and lib_mtime <= object_mtime |
| 1167 | and extra_mtime <= object_mtime |
| 1168 | ): |
| 1169 | print("[WASM] Sketch is up-to-date") |
| 1170 | return object_path |
| 1171 | |
| 1172 | sketch_flags = get_sketch_compile_flags(mode) |
| 1173 | |
| 1174 | includes = [ |
| 1175 | f"-I{PROJECT_ROOT / 'src'}", |
| 1176 | f"-I{PROJECT_ROOT / 'src' / 'platforms' / 'wasm' / 'compiler'}", |
| 1177 | f"-I{example_dir}", |
| 1178 | ] |
| 1179 | |
| 1180 | # Header unit usage: use the .pcm BMI built by build_sketch_pch() |
| 1181 | sketch_pcm_path = build_dir / "wasm_pch.h.pcm" |
| 1182 | pch_args = [] |
| 1183 | if sketch_pcm_path.exists(): |
| 1184 | pch_args = [ |
no test coverage detected