Skip to content

feat: parameterize BMI paths for Clang module pipeline parity#34

Merged
Sunrisepeak merged 4 commits into
mainfrom
feat/clang-pipeline-parity
May 15, 2026
Merged

feat: parameterize BMI paths for Clang module pipeline parity#34
Sunrisepeak merged 4 commits into
mainfrom
feat/clang-pipeline-parity

Conversation

@Sunrisepeak
Copy link
Copy Markdown
Member

Summary

  • Introduce BmiTraits abstraction in model.cppm that encapsulates GCC vs Clang module compilation differences (BMI dir/ext, flags needed)
  • Remove is_gcc gate on dyndep — Clang 18+ supports P1689 with the same flags
  • Parameterize bmi_path lambda, bmi_basename(), and dyndep emit functions to use BmiTraits instead of hardcoded gcm.cache/*.gcm
  • Add -fmodule-output=$bmi_out to cxx_module rule for Clang (GCC writes BMI implicitly, Clang needs explicit flag)
  • Add -fprebuilt-module-path=<bmiDir> to cxxflags for Clang
  • Pass --bmi-dir/--bmi-ext through cxx_dyndep/cxx_collect Ninja rules to mcpp dyndep subcommand

This is the first of 3 PRs to bring Clang module support to GCC parity on Linux. Design doc: .agents/docs/2026-05-15-clang-parity-and-toolchain-abstraction.md

Test plan

  • mcpp build compiles successfully
  • mcpp test — all 12 test suites, 104 tests pass
  • CI passes (self-host build + test + E2E)
  • Follow-up PR2: bmi_cache neutral naming
  • Follow-up PR3: Clang multi-module E2E tests

Introduce BmiTraits abstraction (model.cppm) that encapsulates the
differences between GCC and Clang module compilation:
  - BMI directory name (gcm.cache vs pcm.cache)
  - BMI file extension (.gcm vs .pcm)
  - Whether -fmodule-output= is needed (Clang: yes)
  - Whether -fprebuilt-module-path= is needed (Clang: yes)
  - Whether -fmodules is needed for P1689 scan (GCC: yes, Clang: no)

Changes across the pipeline:
  - ninja_backend: remove is_gcc gate on dyndep, parameterize bmi_path
    lambda, add -fmodule-output=$bmi_out for Clang in cxx_module rule,
    conditionally emit -fmodules in cxx_scan, pass --bmi-dir/--bmi-ext
    to cxx_dyndep and cxx_collect rules
  - flags: add -fprebuilt-module-path=<bmiDir> for Clang
  - dyndep: add DyndepOptions, parameterize bmi_basename extension and
    directory in emit_dyndep/emit_dyndep_single/emit_dyndep_from_files
  - cli: cmd_dyndep parses --bmi-dir/--bmi-ext and passes DyndepOptions
Rename gcmFiles→bmiFiles, gcmDir()→bmiDir(), add bmiDirName/manifestTag
fields to CacheKey. Manifest format now uses the tag from CacheKey
(gcm: or pcm:) and parsing accepts both prefixes for forward compat.

Callers set bmiDirName/manifestTag via BmiTraits from PR1.
- Restore is_gcc gate on dyndep (Clang lacks -fdeps-format=p1689r5;
  needs clang-scan-deps for P1689, future work)
- Fix static-deps path: use implicit output (|) for BMI files so $out
  only contains the .o file; set $bmi_out for all compilers (GCC
  ignores it, Clang uses it for -fmodule-output)
- Add E2E test 38_llvm_modules.sh: multi-module Clang project with
  export module + cross-module import, verifying pcm.cache/ layout
Clang lacks GCC's -fdeps-format=p1689r5 compiler flag but ships
clang-scan-deps which produces identical P1689 JSON output per-file.

Changes:
  - plan.cppm: add scanDepsPath field to BuildPlan
  - clang.cppm: add find_scan_deps() helper
  - cli.cppm: discover clang-scan-deps in compiler's bin/ directory
  - ninja_backend.cppm: enable dyndep when scanDepsPath is available,
    emit Clang-specific cxx_scan rule using clang-scan-deps with
    -format=p1689 and stdout redirection to .ddi file

This gives Clang the same per-file incremental rebuild capability
that GCC has had via the dyndep pipeline.
@Sunrisepeak Sunrisepeak merged commit 9bd1a6d into main May 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant