I am trying to build clang statically with only the WebAssembly target. The purpose is to have a portable executable that would work on any modern linux and able to compile C/C++ to WASM.
For example, I should be able to compile something like this:
#include <cstdint>
#include <cstddef>
void vec_inc(uint32_t *v, size_t len) {
for (auto i = 0; i < len; ++i) {
v[i]++;
}
}
I was able to build clang and can compile simple freestanding program, but I’d like to be able to use at least part of the runtime like the basic type definitions and ideally the STL. Is this doable?
After some investigation, this is where I stand right now:
cmake ../llvm \
-DLLVM_ENABLE_PROJECTS='clang;lld' \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DCMAKE_EXE_LINKER_FLAGS=-static \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DLLVM_TARGETS_TO_BUILD=WebAssembly \
-DLLVM_ENABLE_RUNTIMES='libcxx;libcxxabi' \
-DLLVM_RUNTIME_TARGETS=wasm32 \
-DLLVM_INCLUDE_BENCHMARKS=OFF \
-DLLVM_INCLUDE_EXAMPLES=OFF \
-DLLVM_INCLUDE_TESTS=OFF \
-DLLVM_BUILD_TOOLS=OFF \
-DLLVM_ENABLE_EH=ON \
-DLLVM_ENABLE_RTTI=ON
I am not knowledgeable in the LLVM build system so this is the result of a trial and error process which might have produced something sub-optimal. Please let me know if anything stands out.
Now I am hitting a wall. The runtime does not build because:
llvm-project-release_15.x/build/include/c++/v1/__config:924:8: error: "No thread API"
Looking at the code:
// Thread API
// clang-format off
# if !defined(_LIBCPP_HAS_NO_THREADS) && \
!defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && \
!defined(_LIBCPP_HAS_THREAD_API_WIN32) && \
!defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
# if defined(__FreeBSD__) || \
defined(__wasi__) || \
defined(__NetBSD__) || \
defined(__OpenBSD__) || \
defined(__NuttX__) || \
defined(__linux__) || \
defined(__GNU__) || \
defined(__APPLE__) || \
defined(__sun__) || \
defined(__MVS__) || \
defined(_AIX) || \
defined(__EMSCRIPTEN__)
// clang-format on
# define _LIBCPP_HAS_THREAD_API_PTHREAD
# elif defined(__Fuchsia__)
// TODO(44575): Switch to C11 thread API when possible.
# define _LIBCPP_HAS_THREAD_API_PTHREAD
# elif defined(_LIBCPP_WIN32API)
# define _LIBCPP_HAS_THREAD_API_WIN32
# else
# error "No thread API"
# endif // _LIBCPP_HAS_THREAD_API
# endif // _LIBCPP_HAS_NO_THREADS
# if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
# if defined(__ANDROID__) && __ANDROID_API__ >= 30
# define _LIBCPP_HAS_COND_CLOCKWAIT
# elif defined(_LIBCPP_GLIBC_PREREQ)
# if _LIBCPP_GLIBC_PREREQ(2, 30)
# define _LIBCPP_HAS_COND_CLOCKWAIT
# endif
# endif
# endif
Here I guess we are trying to assess which threading library/method we are going to use. Note that I don’t necessarily need threading. Setting LLVM_ENABLE_THREADS=OFF didn’t change anything though.
If anyone can help, it’d be appreciated.