Skip to content

WebAssembly / Emscripten target: what it needs, and why a rule package cannot supply it #597

Description

@Sunrisepeak

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:

  1. triple.cppm — accept the arch (wasm32) and the OS/env segment; today an
    unknown segment makes the whole triple unparseable.
  2. The object-format mapping above — there is no row a wasm target could take.
  3. Toolchain resolution — emcc/em++ is a driver, not one of the
    llvm/gcc/msvc families the resolver knows.
  4. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions