Start a zccache session with logging to the build directory. Sets ZCCACHE_SESSION_ID in os.environ so all subsequent compiler invocations through zccache use this session and get logged. The session auto-cleans up via PID monitoring when the process exits. Also sets ZCCACHE_LINK_DE
(build_dir: Path)
| 356 | |
| 357 | |
| 358 | def _start_zccache_session(build_dir: Path) -> None: |
| 359 | """Start a zccache session with logging to the build directory. |
| 360 | |
| 361 | Sets ZCCACHE_SESSION_ID in os.environ so all subsequent compiler |
| 362 | invocations through zccache use this session and get logged. |
| 363 | The session auto-cleans up via PID monitoring when the process exits. |
| 364 | |
| 365 | Also sets ZCCACHE_LINK_DEPLOY_CMD so zccache invokes |
| 366 | `clang-tool-chain-libdeploy` after each cache-miss link. This |
| 367 | materializes runtime DLLs next to the linked binary (on Windows |
| 368 | these otherwise don't get deployed because the native ctc-clang++ |
| 369 | trampoline skips Python post-link hooks) and lets zccache's |
| 370 | side-effect scanner bundle them into the cached artifact set — |
| 371 | fixing flaky error-126 DLL load failures under parallel test |
| 372 | execution. See https://github.com/FastLED/FastLED/issues/2329. |
| 373 | """ |
| 374 | if "ZCCACHE_LINK_DEPLOY_CMD" not in os.environ: |
| 375 | os.environ["ZCCACHE_LINK_DEPLOY_CMD"] = "clang-tool-chain-libdeploy" |
| 376 | os.environ.setdefault("ZCCACHE_STRICT_PATHS", "absolute") |
| 377 | # Opt in to zccache's CLI-side probe-bypass fast-path for meson |
| 378 | # configure-phase try-compiles (zackees/zccache#625, #633, #636 — bench |
| 379 | # in #636 shows 7-10s saved per configure run). Not a disable: per-call |
| 380 | # routing, only sub-4 KiB single-source no-PCH no-@rsp invocations |
| 381 | # bypass; production TUs continue to use the cache. setdefault keeps any |
| 382 | # user override intact; older zccache without this env var ignores it. |
| 383 | os.environ.setdefault("ZCCACHE_PROBE_BYPASS", "1") |
| 384 | |
| 385 | zccache_bin = _find_zccache_binary() |
| 386 | if not zccache_bin: |
| 387 | return |
| 388 | |
| 389 | build_dir.mkdir(parents=True, exist_ok=True) |
| 390 | log_path = build_dir / "zccache-session.log" |
| 391 | journal_path = build_dir / "zccache-session.jsonl" |
| 392 | |
| 393 | try: |
| 394 | result = subprocess.run( |
| 395 | [ |
| 396 | zccache_bin, |
| 397 | "session-start", |
| 398 | "--stats", |
| 399 | "--log", |
| 400 | str(log_path), |
| 401 | "--journal", |
| 402 | str(journal_path), |
| 403 | ], |
| 404 | capture_output=True, |
| 405 | text=True, |
| 406 | timeout=10, |
| 407 | ) |
| 408 | if result.returncode == 0: |
| 409 | import json |
| 410 | |
| 411 | output = result.stdout.strip() |
| 412 | try: |
| 413 | data = json.loads(output) |
| 414 | session_id = str(data["session_id"]) |
| 415 | except (json.JSONDecodeError, KeyError): |
no test coverage detected