What this asks for
A WebAssembly / Emscripten target, so that a project can be built with
mcpp build --target wasm32-emscripten (spelling to be decided) the way it is
built for Linux, Windows and macOS today.
Why a rule package cannot supply it
I looked for a way to do this from the outside first, because the extension
model is generous — mcpp::action runs arbitrary commands, a BSP supplies a C
library and a linker script, an adapter reaches host libraries. None of those
reach this, and the reason is structural rather than missing vocabulary:
The target's identity is a closed set in the engine.
// modules/toolchain-model/src/triple.cppm:33
std::string arch; // "x86_64" | "aarch64" | "riscv64" | ... (GNU spelling)
// modules/toolchain-model/src/triple.cppm:168-178 — object format
if (!x64 && !x32) return std::nullopt;
if (os == "windows") return x64 ? "win64" : "win32";
if (os == "macos") return x64 ? "macho64" : "macho32";
if (os == "linux") return x64 ? "elf64" : "elf32";
return std::nullopt;
// modules/toolchain-model/src/triple.cppm:783-785
// Unrecognized segment (androideabi, wasi, …): not in mcpp's target
// language — treat as unparseable rather than guessing.
return std::nullopt;
docs/22 says it plainly — "Layer names are fixed, implementations are not" —
and os / arch / the object format sit on the fixed side. A BSP fills a layer
for a triple the engine already knows (*-none-elf); it cannot introduce one.
And a rule package cannot stand in for the compiler. mcpp::action
attaches its outputs to the compile set, the link set or the artifact set, but
the package's own compile and link are the engine's, driven by the resolved
target. A rule can add objects; it cannot say "compile this package with emcc".
The only shape that would work is one role = "artifact" action shelling out to
emcc over the whole source tree, at which point mcpp is a launcher rather than
the build system.
What it would take
Roughly four places, from a read of the model rather than an implementation
attempt:
triple.cppm — accept the arch (wasm32) and the OS/env segment; today an
unknown segment makes the whole triple unparseable.
- The object-format mapping above — there is no row a wasm target could take.
- Toolchain resolution —
emcc/em++ is a driver, not one of the
llvm/gcc/msvc families the resolver knows.
- Emscripten's link semantics, which differ in kind rather than in flags: the
output is a .js + .wasm pair rather than one file, and data files are
linked in with --preload-file rather than staged beside the artifact.
(4) is the part that looks like it needs design rather than plumbing.
Where this came from
HuxerUI (https://github.com/Sunrisepeak/HuxerUI) now builds natively with mcpp
on Linux, Windows and macOS alongside its CMake build — the framework, its
applications, and a C++20 module front door. Android, iOS and Web stay
CMake-only. Android and iOS are arguably out of scope for mcpp (their
application packaging belongs to Gradle and Xcode either way), but Web is
different: an Emscripten build is an ordinary C++ compile and link with an
unusual output shape, and it is the one platform where mcpp's model looks like
it would fit if the target existed.
Happy to test a branch against a real project if that is useful.
What this asks for
A WebAssembly / Emscripten target, so that a project can be built with
mcpp build --target wasm32-emscripten(spelling to be decided) the way it isbuilt for Linux, Windows and macOS today.
Why a rule package cannot supply it
I looked for a way to do this from the outside first, because the extension
model is generous —
mcpp::actionruns arbitrary commands, a BSP supplies a Clibrary and a linker script, an adapter reaches host libraries. None of those
reach this, and the reason is structural rather than missing vocabulary:
The target's identity is a closed set in the engine.
docs/22says it plainly — "Layer names are fixed, implementations are not" —and
os/arch/ the object format sit on the fixed side. A BSP fills a layerfor a triple the engine already knows (
*-none-elf); it cannot introduce one.And a rule package cannot stand in for the compiler.
mcpp::actionattaches its outputs to the compile set, the link set or the artifact set, but
the package's own compile and link are the engine's, driven by the resolved
target. A rule can add objects; it cannot say "compile this package with emcc".
The only shape that would work is one
role = "artifact"action shelling out toemccover the whole source tree, at which point mcpp is a launcher rather thanthe build system.
What it would take
Roughly four places, from a read of the model rather than an implementation
attempt:
triple.cppm— accept the arch (wasm32) and the OS/env segment; today anunknown segment makes the whole triple unparseable.
emcc/em++is a driver, not one of thellvm/gcc/msvcfamilies the resolver knows.output is a
.js+.wasmpair rather than one file, and data files arelinked in with
--preload-filerather than staged beside the artifact.(4) is the part that looks like it needs design rather than plumbing.
Where this came from
HuxerUI (https://github.com/Sunrisepeak/HuxerUI) now builds natively with mcpp
on Linux, Windows and macOS alongside its CMake build — the framework, its
applications, and a C++20 module front door. Android, iOS and Web stay
CMake-only. Android and iOS are arguably out of scope for mcpp (their
application packaging belongs to Gradle and Xcode either way), but Web is
different: an Emscripten build is an ordinary C++ compile and link with an
unusual output shape, and it is the one platform where mcpp's model looks like
it would fit if the target existed.
Happy to test a branch against a real project if that is useful.