mcpplibs.mwrap.boost@1.92.0· English · 简体中文 Consumer guide: usage.md
A module wrapper: Boost 1.92.0's headers stay untouched upstream code, and a C++23 module layer makes them importable while preserving the upstream API. The wrapper does not re-implement Boost, does not relocate its entities into a new namespace, and does not link a second Boost implementation.
- 116 library module interfaces + the root module + the macro mapping module.
- 22 pure include-only libraries and 2 compiled include-only features (
log,unit-test-framework): consumed by header, listed in usage.md. - 11 libraries need external toolchains/SDKs and are not declared.
boost-m/
├── mcpp.toml package identity, features, targets (generated blocks)
├── build.mcpp root-closure partition generator
├── upstream/boost/ pinned official Boost tree (pruned) + SOURCE.md
├── upstream/boost-module/ retained pre-mwrap wrapper licence/README/history
├── patches/ replayable adaptations; final/<path> = stored forms
├── port/ wrapper TUs (system/thread/leaf extras)
├── port/include/mwrap/boost/ <mwrap/boost/macros.hpp> include entry
├── src/ module interfaces, root module, macros module
├── generated/exports/ committed export lists (.inc) and edges (.deps)
├── generated/meta/ committed lists/maps the generators and build.mcpp read
├── templates/ basic (default) and lib templates
├── tests/ one standalone program per file
├── examples/ basic, git-dep, profiles consumers
├── tools/ import, generation, audit, packaging, CI helpers
└── docs/
Nothing wrapper-side lives under upstream/; nothing upstream-side lives under
src/ or port/.
Each src/<lib>.cppm follows one shape:
module; // global module fragment
#include <boost/optional.hpp> // the exact headers the export list came from
#include <boost/optional/optional_io.hpp>
export module mcpplibs.mwrap.boost.optional;
export import mcpplibs.mwrap.boost.core;
export import mcpplibs.mwrap.boost.type_traits;
#include "../generated/exports/optional.inc" // export namespace boost { using ...; }- The GMF include set comes from the library's public include DAG, minus headers
that are not standalone-parseable; the
.incfile carries theexport namespace boost { using ...; }list generated from a libclang AST snapshot. - One entity has one export owner. A dependency that another target library owns
becomes an
export importedge in the primary module, recorded in<lib>.depsas the complete module name. - Cross-library type references, friend operators, ADL helpers and constants that a patch gave external linkage are part of the audit; an unexportable entity is documented in usage.md with a raw-header alternative, never silently pruned.
src/version.cppmis a thin entry re-exportingmcpplibs.mwrap.boost.macros; the mapped constants live only insrc/macros.cppm.
import mcpplibs.mwrap.boost; must re-export exactly the modules of the active
feature set. A committed file cannot express that, and a build-time rewrite of a
committed file cannot be safe when several consumers build the same checkout.
The interface root src/boost.cppm is therefore fixed:
export module mcpplibs.mwrap.boost;
export import :closure;and build.mcpp writes the partition :closure into MCPP_OUT_DIR
(target/.build-mcpp/out/<configuration>/<package>/boost_closure.cppm), then
selects it with mcpp::source() using the absolute path. The output directory is
per configuration — target, profile, toolchain and feature set — so two builds
with different features cannot overwrite each other's closure, and the package
root stays read-only. The file is written only when its content changes, so an
unchanged feature set does not rebuild the module.
build.mcpp also validates the profile features: one profile per axis, and an
arch-gated profile only on its architecture. Both failures are diagnosed before
the module graph is scanned.
Known aggregate limits are reported, not hidden: under GCC the closure leaves out
mcpplibs.mwrap.boost.sort (BMI ICE when an aggregate re-exports it) and warns;
a clang build of the whole closure can hit the source-location limit.
python3 tools/import_boost.py --tarball boost_1_92_0.tar.gz # repopulates upstream/boost/
python3 tools/reapply_hand_edits.py # vendored adaptations
python3 tools/gen_exports.py --emit-cppm # generated/exports/*.inc|*.deps + draft .cppm
python3 tools/reapply_hand_edits.py # module-side adaptations, final forms
python3 tools/gen_features.py # mcpp.toml blocks + generated/meta/*
python3 tools/gen_features.py --check
python3 tools/gen_audit.py # export completeness (AST)
python3 tools/gen_audit.py --macros # macro-surface inventory
git diff --exit-code && git status --shortimport_boost.pyis the single upstream import: URL, archive SHA-256, kept entries, pruned directories/files and the CRLF-normalized files are recorded inupstream/boost/SOURCE.md. The releaseREADME.mdandLICENSE_1_0.txtare copied byte-for-byte;.gitattributesdisables text conversion underupstream/**.reapply_hand_edits.pynever reads Git history. It appliespatches/*.patch(forward/reverse idempotent, with apatch -p1fallback when Git is absent) and replays hand-maintained final forms frompatches/final/<path>. A patch whose anchor is missing is an error unless listed inTOLERANTwith a written reason.gen_exports.pykeeps its two passes: the libclang AST snapshot produces the export lists, and a body-reference pass completes the.depsedges. Caches and bundle TUs live under the gitignoredtarget/gen/.gen_features.pysplices two marked blocks inmcpp.tomland writesgenerated/meta/{libs.json,features.lst,modules.lst,profiles.lst}. It is byte- and mtime-idempotent. Feature names are kebab-case;implieslists feature names (never internal keys), derived from each interface'sexport importlines plus the generated body edges.modules.lstis the feature → module mapbuild.mcppreads;all-modulesexpands to the 117 module entries.gen_audit.pyis the migration gate for export completeness; its report is reviewed with the committed tree, not treated as "not public API" on failure.
Generation needs LLVM 23.1.3 with matching libclang and the pinned MinGW sysroot
(tools/fetch_mingw_sysroot.py, tools/uv.lock). Consumers do not: they use the
committed output.
One feature per library, additive across dependency edges. A feature's sources
are its interface plus, for compiled libraries, its upstream src/** TU globs.
log's and unit-test-framework's TUs are feature-gated; the rest also appear
in the base source list so mcpp test sees the full surface while mcpp build
compiles only active features.
mcpp build mode drops every feature-listed source and re-adds the active ones;
mcpp test keeps the base list and excludes only feature-provided sources. That
pair of rules is why the base list is generated from the union and why the
Boost.Test framework TUs are deliberately feature-only (the two Boost.Test forms
must never link together).
The module TUs, the library TUs and raw-header consumers share one configuration:
BOOST_FILESYSTEM_VERSION=3,BOOST_THREAD_VERSION=2— the baseline the exports were generated against, pinned in[build].defines;BOOST_ALL_NO_LIB,_MT,WIN32_LEAN_AND_MEAN,SECURITY_WIN32;- per-glob
BOOST_THREAD_BUILD_LIBonupstream/boost/libs/thread/src/**; port/includeandupstream/boostpublic; log/atomic private include dirs are listed inprivate_include_dirs;-wfor vendored header noise;-Wno-invalid-specializationunder clang (poly_collection specializesstd::is_void);- the profile's
NDEBUGstate reaches the headers, so release-only declaration differences follow upstream: Boost.uBLAS's tensorBOOST_UBLAS_INLINEordering is corrected bypatches/numeric.patch(it is ill-formed when the macro expands toinline), and the checked-build-onlysame_impl_exexport is guarded ingenerated/exports/numeric.incby the replay tool.
The same upstream/boost tree feeds the interfaces, the library TUs and raw
header consumption. One Boost implementation per program: there is no
compat.boost dependency, and a second copy must not be added.
- Wrapper contribution (modules, port, tools, templates, tests, docs):
Apache-2.0,
LICENSE+NOTICE(mcpp-community). - Boost upstream under
upstream/boost/: BSL-1.0, its ownREADME.mdandLICENSE_1_0.txt, hashed inupstream/documents.json. - Retained pre-mwrap wrapper contribution under
upstream/boost-module/: BSL-1.0,SOURCE.mdrecords repository, commits and old identity.
runtime.deploy ships all three under distinct licenses/boost/...
destinations, so equal basenames cannot overwrite one another; a consumer bundle
keeps byte-identical notices.
- Native build +
mcpp teston Linux x86_64 (GCC 16.1, LLVM), Linux arm64 (GCC), macOS arm64 (LLVM), Windows x86_64 (clang-msvc). tools/ci/verify_generated.py: import/replay, generation, feature splice and audit on a clean tree, withgit diff/git statusas the oracle; a second build on the same configuration records the incremental TU count and mtimes.tools/check_mwrap_release.py: identity, version scheme, tag, licence split and retained-document bytes.tools/test_template.py: installs an isolatedMCPP_HOMEfixture, runs a realmcpp new, parses the rendered manifest (complete selector, version, features), then builds and runs the project — no sed rendering.tools/package-source.sh:boost-m-<version>.tar.gzfrom the tracked tree, hash next to the archive, compressed with a bounded thread count. The release workflow publishes that asset for the immutablemwrap-<version>tag only.
Heavy builds stay below 80% of the machine's effective CPU/memory: set
MCPP_JOBS/-j, avoid parallel full-tree builds, and keep AST generation
single-threaded per library. The vendored tree is 400+ MB; a local fixture copy
hardlinks it when the filesystem allows.