Skip to content

Commit

Permalink
add shared library support
Browse files Browse the repository at this point in the history
This adds support for building WASI shared libraries per
https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md.

For the time being, the goal is to allow "pseudo-dynamic" linking using the
Component Model per
https://github.com/WebAssembly/component-model/blob/main/design/mvp/examples/SharedEverythingDynamicLinking.md.
This requires all libraries to be available when the component is created, but
still allows runtime symbol resolution via `dlopen`/`dlsym` backed by a static
lookup table.  This is sufficient to support Python native extensions, for
example.  A complete demo using `wit-component` is available at
https://github.com/dicej/component-linking-demo.

This requires https://reviews.llvm.org/D153293, which we will need to backport
to LLVM 16 until 17 is released, hence the llvm-D153293-backport.patch file.

Signed-off-by: Joel Dice <[email protected]>
  • Loading branch information
dicej committed Jul 28, 2023
1 parent 7c0558b commit e5b8dd8
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 18 deletions.
12 changes: 6 additions & 6 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[submodule "src/llvm-project"]
path = src/llvm-project
url = https://github.com/llvm/llvm-project
path = src/llvm-project
url = https://github.com/llvm/llvm-project
[submodule "src/wasi-libc"]
path = src/wasi-libc
url = https://github.com/CraneStation/wasi-libc
path = src/wasi-libc
url = https://github.com/dicej/wasi-libc
[submodule "src/config"]
path = src/config
url = https://git.savannah.gnu.org/git/config.git
path = src/config
url = https://git.savannah.gnu.org/git/config.git
28 changes: 17 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ clean:

build/llvm.BUILT:
mkdir -p build/llvm
# Apply https://reviews.llvm.org/D153293 as a patch until we're ready to
# upgrade LLVM (presumably once v17 has been released)
(cd $(LLVM_PROJ_DIR) && patch -p1 -N < ../../llvm-D153293-backport.patch) || true
cd build/llvm && cmake -G Ninja \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DLLVM_ENABLE_TERMINFO=OFF \
Expand All @@ -76,8 +79,8 @@ build/llvm.BUILT:
-DLLVM_DEFAULT_TARGET_TRIPLE=wasm32-wasi \
-DLLVM_ENABLE_PROJECTS="lld;clang;clang-tools-extra" \
$(if $(patsubst 9,,$(CLANG_VERSION)), \
$(if $(patsubst 10,,$(CLANG_VERSION)), \
-DDEFAULT_SYSROOT=../share/wasi-sysroot, \
$(if $(patsubst 10,,$(CLANG_VERSION)), \
-DDEFAULT_SYSROOT=../share/wasi-sysroot, \
-DDEFAULT_SYSROOT=$(PREFIX)/share/wasi-sysroot), \
-DDEFAULT_SYSROOT=$(PREFIX)/share/wasi-sysroot) \
-DLLVM_INSTALL_BINUTILS_SYMLINKS=TRUE \
Expand Down Expand Up @@ -107,17 +110,19 @@ build/llvm.BUILT:
llvm-config
touch build/llvm.BUILT

build/wasi-libc.BUILT: build/llvm.BUILT
build/wasi-libc.BUILT: build/compiler-rt.BUILT
$(MAKE) -C $(ROOT_DIR)/src/wasi-libc \
CC=$(BUILD_PREFIX)/bin/clang \
AR=$(BUILD_PREFIX)/bin/llvm-ar \
NM=$(BUILD_PREFIX)/bin/llvm-nm \
SYSROOT=$(BUILD_PREFIX)/share/wasi-sysroot
SYSROOT=$(BUILD_PREFIX)/share/wasi-sysroot \
BUILTINS_LIB=$(BUILD_PREFIX)/lib/clang/$(CLANG_VERSION)/lib/wasi/libclang_rt.builtins-wasm32.a
$(MAKE) -C $(ROOT_DIR)/src/wasi-libc \
CC=$(BUILD_PREFIX)/bin/clang \
AR=$(BUILD_PREFIX)/bin/llvm-ar \
NM=$(BUILD_PREFIX)/bin/llvm-nm \
SYSROOT=$(BUILD_PREFIX)/share/wasi-sysroot \
BUILTINS_LIB=$(BUILD_PREFIX)/lib/clang/$(CLANG_VERSION)/lib/wasi/libclang_rt.builtins-wasm32.a \
THREAD_MODEL=posix
touch build/wasi-libc.BUILT

Expand Down Expand Up @@ -168,23 +173,24 @@ LIBCXX_CMAKE_FLAGS = \
-DLIBCXX_HAS_WIN32_THREAD_API:BOOL=OFF \
-DLLVM_COMPILER_CHECKED=ON \
-DCMAKE_BUILD_TYPE=RelWithDebugInfo \
-DLIBCXX_ENABLE_SHARED:BOOL=OFF \
-DLIBCXX_ENABLE_SHARED:BOOL=ON \
-DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY:BOOL=OFF \
-DLIBCXX_ENABLE_EXCEPTIONS:BOOL=OFF \
-DLIBCXX_ENABLE_FILESYSTEM:BOOL=OFF \
-DLIBCXX_ENABLE_ABI_LINKER_SCRIPT:BOOL=OFF \
-DLIBCXX_CXX_ABI=libcxxabi \
-DLIBCXX_CXX_ABI_INCLUDE_PATHS=$(LLVM_PROJ_DIR)/libcxxabi/include \
-DLIBCXX_HAS_MUSL_LIBC:BOOL=ON \
-DLIBCXX_ABI_VERSION=2 \
-DLIBCXXABI_ENABLE_EXCEPTIONS:BOOL=OFF \
-DLIBCXXABI_ENABLE_SHARED:BOOL=OFF \
-DLIBCXXABI_ENABLE_SHARED:BOOL=ON \
-DLIBCXXABI_SILENT_TERMINATE:BOOL=ON \
-DLIBCXXABI_ENABLE_THREADS:BOOL=@PTHREAD@ \
-DLIBCXXABI_HAS_PTHREAD_API:BOOL=@PTHREAD@ \
-DLIBCXXABI_HAS_EXTERNAL_THREAD_API:BOOL=OFF \
-DLIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY:BOOL=OFF \
-DLIBCXXABI_HAS_WIN32_THREAD_API:BOOL=OFF \
-DLIBCXXABI_ENABLE_PIC:BOOL=OFF \
-DLIBCXXABI_ENABLE_PIC:BOOL=ON \
-DWASI_SDK_PREFIX=$(BUILD_PREFIX) \
-DUNIX:BOOL=ON \
--debug-trycompile
Expand All @@ -194,8 +200,8 @@ build/libcxx.BUILT: build/llvm.BUILT build/compiler-rt.BUILT build/wasi-libc.BUI
mkdir -p build/libcxx
cd build/libcxx && cmake -G Ninja $(LIBCXX_CMAKE_FLAGS:@PTHREAD@=OFF) \
-DCMAKE_SYSROOT=$(BUILD_PREFIX)/share/wasi-sysroot \
-DCMAKE_C_FLAGS="$(DEBUG_PREFIX_MAP) $(EXTRA_CFLAGS)" \
-DCMAKE_CXX_FLAGS="$(DEBUG_PREFIX_MAP) $(EXTRA_CXXFLAGS)" \
-DCMAKE_C_FLAGS="$(DEBUG_PREFIX_MAP) $(EXTRA_CFLAGS) -fPIC" \
-DCMAKE_CXX_FLAGS="$(DEBUG_PREFIX_MAP) $(EXTRA_CXXFLAGS) -fPIC" \
-DLIBCXX_LIBDIR_SUFFIX=$(ESCAPE_SLASH)/wasm32-wasi \
-DLIBCXXABI_LIBDIR_SUFFIX=$(ESCAPE_SLASH)/wasm32-wasi \
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
Expand All @@ -204,8 +210,8 @@ build/libcxx.BUILT: build/llvm.BUILT build/compiler-rt.BUILT build/wasi-libc.BUI
mkdir -p build/libcxx-threads
cd build/libcxx-threads && cmake -G Ninja $(LIBCXX_CMAKE_FLAGS:@PTHREAD@=ON) \
-DCMAKE_SYSROOT=$(BUILD_PREFIX)/share/wasi-sysroot \
-DCMAKE_C_FLAGS="$(DEBUG_PREFIX_MAP) -pthread $(EXTRA_CFLAGS)" \
-DCMAKE_CXX_FLAGS="$(DEBUG_PREFIX_MAP) -pthread $(EXTRA_CXXFLAGS)" \
-DCMAKE_C_FLAGS="$(DEBUG_PREFIX_MAP) -pthread $(EXTRA_CFLAGS) -fPIC" \
-DCMAKE_CXX_FLAGS="$(DEBUG_PREFIX_MAP) -pthread $(EXTRA_CXXFLAGS) -fPIC" \
-DLIBCXX_LIBDIR_SUFFIX=$(ESCAPE_SLASH)/wasm32-wasi-threads \
-DLIBCXXABI_LIBDIR_SUFFIX=$(ESCAPE_SLASH)/wasm32-wasi-threads \
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
Expand Down
40 changes: 40 additions & 0 deletions llvm-D153293-backport.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index a1c4cd9ef9c7..4cbc0794f420 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -101,13 +101,16 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
<< CM << A->getOption().getName();
}
}
- if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
+ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, options::OPT_shared))
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(Crt1)));
if (Entry) {
CmdArgs.push_back(Args.MakeArgString("--entry"));
CmdArgs.push_back(Args.MakeArgString(Entry));
}

+ if (Args.hasArg(options::OPT_shared))
+ CmdArgs.push_back(Args.MakeArgString("-shared"));
+
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);

if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
index 630c786a3dc7..788e08e3c8a9 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -98,13 +98,6 @@ static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM,
return Reloc::Static;
}

- if (!TT.isOSEmscripten()) {
- // Relocation modes other than static are currently implemented in a way
- // that only works for Emscripten, so disable them if we aren't targeting
- // Emscripten.
- return Reloc::Static;
- }
-
return *RM;
}

0 comments on commit e5b8dd8

Please sign in to comment.