Skip to content

feat: lib-root convention (Levels 1+2)#15

Merged
Sunrisepeak merged 1 commit intomainfrom
feat/lib-root-convention
May 9, 2026
Merged

feat: lib-root convention (Levels 1+2)#15
Sunrisepeak merged 1 commit intomainfrom
feat/lib-root-convention

Conversation

@Sunrisepeak
Copy link
Copy Markdown
Member

Summary

Introduces a Cargo-style lib root — a single primary module-interface
file aggregating a package's public API.

Two recognised forms:

  • Convention (no config): src/<package-tail>.cppm where
    <package-tail> is the last dotted segment of [package].name:
    • mcpplibs.tinyhttpssrc/tinyhttps.cppm
    • mcpplibs.cmdlinesrc/cmdline.cppm
    • gtestsrc/gtest.cppm
  • Override: [lib] path = "src/foo.cppm" (cargo-style).

Either way the file must export module <full-package-name>;
partitions go in sibling files and are re-exported from the lib
root, mirroring Rust's lib.rs aggregating pub mods.

Lib-root validation (only for kind = "lib" / shared projects)

Situation Severity
Explicit [lib].path pointing at a missing file ERROR
Convention miss (no src/<tail>.cppm) WARNING (soft on-ramp)
Lib root exports a partition (export module foo:bar;) ERROR
Lib root exports a different module than [package].name ERROR

Pure-binary projects (mcpp itself, mcpp new-scaffolded apps) are
unaffected.

What this enables (downstream)

  • [modules].exports becomes optional for lib targets — derivable
    from the lib root in a follow-up PR
  • mcpp publish can auto-fill xpkg modules from the lib root
  • Future docs / mcpp explain use lib root as their entry

Test plan

  • mcpp build (worktree)
  • mcpp test — 9/9 unit binaries pass (incl. 4 manifest + 5
    validate new cases)
  • e2e subset (02 / 07 / 09 / 12 / 23 / 26 / 27) all pass
  • Manual smoke on mcpplibs/tinyhttps: zero warnings
  • Manual reproduction of warning path (rename src/mylib.cppm
    src/wrong.cppm): warning fires, build still succeeds
  • Full CI green

…].path`)

Introduces a Cargo-style "lib root" — a single primary module-interface
file that aggregates the package's public API. Two recognised forms:

  * Convention (no config): `src/<package-tail>.cppm` where
    `<package-tail>` is the last `.`-segment of `[package].name`.
    Examples:
      mcpplibs.tinyhttps → src/tinyhttps.cppm
      mcpplibs.cmdline   → src/cmdline.cppm
      gtest              → src/gtest.cppm
  * Override: `[lib] path = "src/foo.cppm"` (cargo-style).

Either way, the file must `export module <full-package-name>;` (no
`:partition` suffix) — partitions go in sibling files and are
re-exported from the lib root, mirroring Rust's `lib.rs` aggregating
`pub mod`s.

Lib-root checks fire only for projects that ship a `kind = "lib"` (or
`shared`) target. Pure binaries (mcpp itself, scaffolded `mcpp new`)
are unaffected.

Validation policy:
  - explicit `[lib].path` pointing at a missing file → ERROR
  - convention miss (no `src/<tail>.cppm`) → WARNING (soft on-ramp;
    existing libs aren't broken — they get a polite reminder)
  - lib-root file exists but `export module …:partition;` → ERROR
    (lib root must be the primary module, never a partition)
  - lib-root file exports a different module name than [package].name
    → ERROR

Existing libs that already follow the convention (mcpplibs.cmdline,
mcpplibs.templates, mcpplibs.tinyhttps) keep working unchanged. The
soft warning gives anyone who doesn't a clear path to compliance
without a hard break.

Coverage: 4 manifest unit tests + 5 validate tests + a manual smoke
on tinyhttps (zero warnings) and a deliberate file-rename
reproduction of the warning path.
@Sunrisepeak Sunrisepeak merged commit 1ffd275 into main May 9, 2026
1 check passed
Sunrisepeak added a commit that referenced this pull request May 9, 2026
The v0.0.2 GitHub Release is being re-issued with the same version
number to fold in three improvements that landed against main *after*
the original tag was pushed:

* fix(modgraph): partition import scanner no longer concatenates the
  unit's own `:partition` into imported names (PR #14)
* feat: lib-root convention `src/<package-tail>.cppm` + optional
  `[lib].path` (PR #15)

CHANGELOG's [0.0.2] entry is amended in place to capture them, since
no v0.0.3 has been published yet and we're keeping the version number
stable while the project is still pre-1.0. After this PR merges, the
v0.0.2 git tag and GitHub Release will be re-pointed at the new HEAD.
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