Clang++ for wasm32 and the basic C++ libs

Short preamble about emscripten

emscripten would certainly help a lot - I tried it and indeed, everything is much simpler in the C++ world, but I’d like, as a challenge, & in order to build a wasm with a small footprint, & in order to control and understand more of what’s happening in the code/libs, to keep using Clang++, at least for now. So I decided not to use emscripten nor its libs.


I'm developing a small wasm32 project with Clang, it's more of a PoC for the time being, but that's very interesting, crossing the worlds of assembly and JS in a browser. Creation of a memory space in JS, sharing with the wasm, exchange data, customization of the wasm for stack size, stack first, memory handling... all went well, better than expected. Then I did a tiny C++ program using a tiny class

Node *node = new Node(position);

And wasm-ld always complained about the lack of the “new” operator (to ensure this is the problem, I implemented my own “new” operator and that worked).

When I built llvm 18 from source, I noticed it searched (and finds) g++ (12/11 & 10 on my Ubuntu 22.03). Then I read somewhere that it actually uses the g++ libs(?). And since (it seems) g++ does not have C++ libs for wasm32, there is no way to “bypass” emscripten?

I don’t need exceptions and all the bells and whistles of C++, just the basics, “new”, “delete” and “cstdlib” headers and associated wasm-libs.

Actually my question, being a beginner, would merely be a confirmation of the above (no c++ wasm std libs in clang, nor in g++)? And if, hopefully, I happen to be wrong, please let me know how to build it for wasm32.

LLVM has its own C++ runtime, libc++. It isn’t the default on Linux, which is why you’re seeing g++ (technically libstdc++, the GNU C++ standard library) being searched for, but -stdlib=libc++ would attempt to use libc++.

Emscripten maintains forks of the LLVM runtime libraries, per https://github.com/emscripten-core/emscripten/blob/594d27d6590b381cd5844b7b3ae4af472fe5c38d/docs/process.md#updating-the-llvm-libraries. I don’t know what changes they’ve made and how far you’d get just using the vanilla versions of the libraries. @sbc100 might be the best person to answer that.

You will need to (at least) compile libc++, and libc. This is because libc++ tends to depend on libc for things like malloc (needed by new)

Note that both emscripten and wasi-sdk use a musl-based libc rather then llvm’s libc.

If you want something bare bones I would recommend using the sysroot from wasi-sdk rather then trying to build your own sysroot from scratch.

Thank your for your replies.

I did try to compile Clang/LLVM (release 16.0.6 – initially the latest 18.0.0 → errors, then thought maybe it’s better to use the last stable), got errors like (roughly, don’t remember exactly) No threads support, fixed, then undefined ldiv_t type, fixed, … each time rm -rfing the build dir in case of previous compiles side-effects and ended up with this cmake setup

cmake  \
  -G "Unix Makefiles" \
  -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld" \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_CXX_COMPILER="g++" \
  -DLLVM_TARGETS_TO_BUILD=WebAssembly \
  -DLLVM_ENABLE_THREADS=OFF \
  -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
  -DLLVM_RUNTIME_TARGETS=wasm32 \
  -DRUNTIMES_wasm32_LIBCXX_ENABLE_THREADS=OFF \
  -DLLVM_INCLUDE_BENCHMARKS=OFF \
  -DLLVM_INCLUDE_EXAMPLES=OFF \
  -DLLVM_INCLUDE_TESTS=OFF \
  -DLLVM_BUILD_TOOLS=OFF \
  -DLLVM_ENABLE_EH=OFF \
  -DLLVM_ENABLE_RTTI=OFF \
  ../llvm

which had other errors. near the end of the build (linking) … don’t remember exactly (started to give up!).

Of course it chose g++ because that is the compiler installed, didn’t want to tell the whole story initially. Actually I did install the default Ubuntu 22.04 clang package which has wasm32 support, but it’s v14, too old, and doesn’t support newer wasm-ld options (like -z stack-size).

So then I installed the latest binaries 16.0.6 from https://releases.llvm.org/ for Ubuntu (18).
And I don’t see the C++ libs for wasm in it(?). So I guess this one expects the libs from the compiler installed, ie g++(?).

So to summarize,

LLVM has its own C++ runtime

  • I’d be happy to use CLang++ >= 16 binaries that support the c++ libs for wasm32 on Ubuntu, but the latest release downloaded from “releases” (16.0.6) doesn’t have - seemingly - these wasm C++ libs
  • the default clang package for Ubuntu does support wasm32 but it’s too old
  • the compilation I tried failed at some point, and after going through many forums and posts from people having the same problem, then getting it fixed, then they fall into other problems that they don’t get fixed, I’m a bit at a loss
  • using g++ instead of Clang to compile the whole thing is probably not the best idea, but, honestly, if I had a Clang++ with wasm C++ libs support from the start, well I wouldn’t have to compile anything…

(most of the problems reported here are probably due to my CLang inexperience - in the meantime
I did implement my own new and delete ops class inherited into the main classes, and a basic malloc / free in the linear memory that seems to work, maybe the clib++ won’t be necessary after all)