From 65cc765563dc1ad263646ff2fdf60384e1e27bc6 Mon Sep 17 00:00:00 2001 From: Carlos Segarra Date: Tue, 13 Feb 2024 18:28:47 +0000 Subject: [PATCH] wasi: attempt at having two different targets for threads and non-threads --- LLVM.makefile | 112 +++++++++++++++++++++++-------------- WasiToolchain.cmake | 10 ++-- faasmtools/build.py | 23 +++++++- faasmtools/compile_util.py | 2 +- libfaasm/CMakeLists.txt | 1 - tasks/func.py | 12 +++- third-party/wasi-libc | 2 +- 7 files changed, 108 insertions(+), 54 deletions(-) diff --git a/LLVM.makefile b/LLVM.makefile index 28c9b3ae..fcf6d8fd 100644 --- a/LLVM.makefile +++ b/LLVM.makefile @@ -91,8 +91,13 @@ $(BUILD_DIR)/wasi-libc.BUILT: $(BUILD_DIR)/compiler-rt.BUILT AR=$(FAASM_TOOLCHAIN_DIR)/bin/llvm-ar \ NM=$(FAASM_TOOLCHAIN_DIR)/bin/llvm-nm \ SYSROOT=$(FAASM_SYSROOT) \ - THREAD_MODEL=faasm \ - default + default libc_so + $(MAKE) -C ${WASI_LIBC_DIR} \ + CC=$(FAASM_TOOLCHAIN_DIR)/bin/clang \ + AR=$(FAASM_TOOLCHAIN_DIR)/bin/llvm-ar \ + NM=$(FAASM_TOOLCHAIN_DIR)/bin/llvm-nm \ + SYSROOT=$(FAASM_SYSROOT) \ + THREAD_MODEL=posix touch $(BUILD_DIR)/wasi-libc.BUILT $(BUILD_DIR)/compiler-rt.BUILT: $(BUILD_DIR)/llvm.BUILT @@ -124,59 +129,82 @@ $(BUILD_DIR)/compiler-rt.BUILT: $(BUILD_DIR)/llvm.BUILT $(FAASM_TOOLCHAIN_DIR)/lib/clang/$(CLANG_VERSION_MAJOR)/lib/wasi/libclang_rt.builtins-wasm32.a touch $(BUILD_DIR)/compiler-rt.BUILT +# Flags for libcxx and libcxxabi. +# $(1): pthreads ON or OFF +# $(2): shared libraries ON or OFF +LIBCXX_CMAKE_FLAGS = \ + -DCMAKE_C_COMPILER_WORKS=ON \ + -DCMAKE_CXX_COMPILER_WORKS=ON \ + -DCMAKE_AR=$(FAASM_TOOLCHAIN_DIR)/bin/ar \ + -DCMAKE_TOOLCHAIN_FILE=$(FAASM_TOOLCHAIN_FILE) \ + -DCMAKE_STAGING_PREFIX=$(FAASM_SYSROOT) \ + -DCMAKE_POSITION_INDEPENDENT_CODE=$(2) \ + -DLLVM_CONFIG_PATH=$(LLVM_CONFIG) \ + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ + -DCXX_SUPPORTS_CXX11=ON \ + -DLIBCXX_ENABLE_THREADS:BOOL=$(1) \ + -DLIBCXX_HAS_PTHREAD_API:BOOL=$(1) \ + -DLIBCXX_HAS_EXTERNAL_THREAD_API:BOOL=OFF \ + -DLIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY:BOOL=OFF \ + -DLIBCXX_HAS_WIN32_THREAD_API:BOOL=OFF \ + -DLLVM_COMPILER_CHECKED=ON \ + -DCMAKE_BUILD_TYPE=RelWithDebugInfo \ + -DLIBCXX_ENABLE_SHARED:BOOL=$(2) \ + -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY:BOOL=OFF \ + -DLIBCXX_ENABLE_EXCEPTIONS:BOOL=OFF \ + -DLIBCXX_ENABLE_FILESYSTEM:BOOL=ON \ + -DLIBCXX_ENABLE_ABI_LINKER_SCRIPT:BOOL=OFF \ + -DLIBCXX_USE_COMPILER_RT=ON \ + -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=$(2) \ + -DLIBCXXABI_SILENT_TERMINATE:BOOL=ON \ + -DLIBCXXABI_ENABLE_THREADS:BOOL=$(1) \ + -DLIBCXXABI_HAS_PTHREAD_API:BOOL=$(1) \ + -DLIBCXXABI_HAS_EXTERNAL_THREAD_API:BOOL=OFF \ + -DLIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY:BOOL=OFF \ + -DLIBCXXABI_HAS_WIN32_THREAD_API:BOOL=OFF \ + -DLIBCXX_ENABLE_PIC:BOOL=$(2) \ + -DUNIX:BOOL=ON \ + --debug-trycompile + $(BUILD_DIR)/libcxx.BUILT: $(BUILD_DIR)/llvm.BUILT ${BUILD_DIR}/wasi-libc.BUILT + # Build different libcxx targets mkdir -p $(BUILD_DIR)/libcxx - cd $(BUILD_DIR)/libcxx; cmake -G Ninja \ - -DCMAKE_C_COMPILER_WORKS=ON \ - -DCMAKE_CXX_COMPILER_WORKS=ON \ - -DCMAKE_AR=$(FAASM_TOOLCHAIN_DIR)/bin/ar \ - -DCMAKE_TOOLCHAIN_FILE=$(FAASM_TOOLCHAIN_FILE) \ - -DCMAKE_STAGING_PREFIX=$(FAASM_SYSROOT) \ - -DCMAKE_POSITION_INDEPENDENT_CODE=OFF \ - -DLLVM_CONFIG_PATH=$(LLVM_CONFIG) \ - -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ - -DCXX_SUPPORTS_CXX11=ON \ - -DLIBCXX_ENABLE_THREADS:BOOL=ON \ - -DLIBCXX_HAS_PTHREAD_API:BOOL=ON \ - -DLIBCXX_HAS_EXTERNAL_THREAD_API:BOOL=OFF \ - -DLIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY:BOOL=OFF \ - -DLIBCXX_HAS_WIN32_THREAD_API:BOOL=OFF \ - -DLLVM_COMPILER_CHECKED=ON \ - -DCMAKE_BUILD_TYPE=RelWithDebugInfo \ - -DLIBCXX_ENABLE_SHARED:BOOL=OFF \ - -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY:BOOL=OFF \ - -DLIBCXX_ENABLE_EXCEPTIONS:BOOL=OFF \ - -DLIBCXX_ENABLE_FILESYSTEM:BOOL=ON \ - -DLIBCXX_ENABLE_ABI_LINKER_SCRIPT:BOOL=OFF \ - -DLIBCXX_USE_COMPILER_RT=ON \ - -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_SILENT_TERMINATE:BOOL=ON \ - -DLIBCXXABI_ENABLE_THREADS:BOOL=ON \ - -DLIBCXXABI_HAS_PTHREAD_API:BOOL=ON \ - -DLIBCXXABI_HAS_EXTERNAL_THREAD_API:BOOL=OFF \ - -DLIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY:BOOL=OFF \ - -DLIBCXXABI_HAS_WIN32_THREAD_API:BOOL=OFF \ - -DLIBCXX_ENABLE_PIC:BOOL=OFF \ - -DUNIX:BOOL=ON \ - --debug-trycompile \ + cd $(BUILD_DIR)/libcxx && cmake -G Ninja $(call LIBCXX_CMAKE_FLAGS,OFF,ON) \ -DCMAKE_SYSROOT=${FAASM_SYSROOT} \ - -DCMAKE_C_FLAGS="-I$(FAASM_SYSROOT)/include --target=wasm32-wasi" \ - -DCMAKE_CXX_FLAGS="-I$(FAASM_SYSROOT)/include -I$(FAASM_SYSROOT)/include/c++/v1 --target=wasm32-wasi" \ + -DCMAKE_C_FLAGS="--target=wasm32-wasi" \ + -DCMAKE_CXX_FLAGS="--target=wasm32-wasi" \ -DLIBCXX_LIBDIR_SUFFIX=/wasm32-wasi \ -DLIBCXXABI_LIBDIR_SUFFIX=/wasm32-wasi \ -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ $(LLVM_PROJ_DIR)/runtimes + mkdir -p $(BUILD_DIR)/libcxx-threads + cd $(BUILD_DIR)/libcxx-threads && cmake -G Ninja $(call LIBCXX_CMAKE_FLAGS,ON,OFF) \ + -DCMAKE_SYSROOT=${FAASM_SYSROOT} \ + -DCMAKE_C_FLAGS="--target=wasm32-wasi-threads" \ + -DCMAKE_CXX_FLAGS="--target=wasm32-wasi-threads" \ + -DLIBCXX_LIBDIR_SUFFIX=/wasm32-wasi-threads \ + -DLIBCXXABI_LIBDIR_SUFFIX=/wasm32-wasi-threads \ + -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ + $(LLVM_PROJ_DIR)/runtimes + # Do the install ninja -v -C $(BUILD_DIR)/libcxx install + mv $(FAASM_WASM_SYSROOT)/include/c++ $(FAASM_WASM_SYSROOT)/include/wasm32-wasi/ + ninja -v -C $(BUILD_DIR)/libcxx-threads install + mv $(FAASM_WASM_SYSROOT)/include/c++ $(FAASM_WASM_SYSROOT)/include/wasm32-wasi-threads/ + # As of this writing, `clang++` will ignore the above include dirs unless this one also exists: + mkdir -p $(FAASM_WASM_SYSROOT)/include/c++/v1 touch $(BUILD_DIR)/libcxx.BUILT + .PHONY: extras extras: $(BUILD_DIR)/libcxx.BUILT cp $(FAASM_CPP_PROJ_ROOT)/sysroot_extras/* $(FAASM_SYSROOT)/lib/wasm32-wasi/ + cp $(FAASM_CPP_PROJ_ROOT)/sysroot_extras/* $(FAASM_SYSROOT)/lib/wasm32-wasi-threads/ llvm: $(BUILD_DIR)/llvm.BUILT diff --git a/WasiToolchain.cmake b/WasiToolchain.cmake index b0181df0..45402e11 100644 --- a/WasiToolchain.cmake +++ b/WasiToolchain.cmake @@ -19,7 +19,7 @@ set(UNIX 1) set(CMAKE_SYSTEM_NAME WASI) set(CMAKE_SYSTEM_VERSION 1) set(CMAKE_SYSTEM_PROCESSOR wasm32) -set(WASM_TRIPLE wasm32-wasi) +set(WASM_TRIPLE $ENV{FAASM_WASM_TRIPLE}) set(WASI_HOST_EXE_SUFFIX "") @@ -52,15 +52,13 @@ unset(CMAKE_DL_LIBS CACHE) # Add definition for flagging Faasm add_definitions(-D__faasm) -set(FAASM_COMPILER_FLAGS $ENV{FAASM_WASM_CFLAGS}) - if(FAASM_BUILD_SHARED) - set(FAASM_COMPILER_FLAGS "${FAASM_COMPILER_FLAGS} $ENV{FAASM_WASM_CFLAGS_SHARED}") + set(FAASM_COMPILER_FLAGS "$ENV{FAASM_WASM_CFLAGS} $ENV{FAASM_WASM_CFLAGS_SHARED}") endif() set(CMAKE_SYSROOT ${FAASM_SYSROOT} CACHE STRING "faasm build") -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FAASM_COMPILER_FLAGS}" CACHE STRING "faasm build") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FAASM_COMPILER_FLAGS}" CACHE STRING "faasm build") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} $ENV{FAASM_WASM_CFLAGS}" CACHE STRING "faasm build") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{FAASM_WASM_CXXFLAGS}" CACHE STRING "faasm build") set(CMAKE_LINKER_FLAGS $ENV{FAASM_WASM_LINKER_FLAGS} CACHE STRING "faasm build") set(CMAKE_SHARED_LINKER_FLAGS $ENV{FAASM_WASM_SHARED_LINKER_FLAGS} CACHE STRING "faasm build") set(CMAKE_EXE_LINKER_FLAGS $ENV{FAASM_WASM_EXE_LINKER_FLAGS} CACHE STRING "faasm build") diff --git a/faasmtools/build.py b/faasmtools/build.py index 256ab265..52d557b8 100644 --- a/faasmtools/build.py +++ b/faasmtools/build.py @@ -142,7 +142,7 @@ "-Xlinker --export={}".format(FAASM_WASM_CTORS_FUNC_NAME), "-Xlinker --export=__stack_pointer", "-Xlinker --max-memory={}".format(FAASM_WASM_MAX_MEMORY), - "-Xlinker --features=mutable-globals,sign-ext,simd128", + "-Xlinker --features=bulk-memory,mutable-globals,sign-ext,simd128", "-Wl,-z,stack-size={} -Wl".format(FAASM_WASM_STACK_SIZE), ] @@ -188,6 +188,8 @@ # Env. variables as a dictionary: prefix with FAASM_WASM or FAASM_NATIVE # depending on the build type variables target +# WARNING: do NOT import this method directly, instead use the getter method: +# get_faasm_build_env_dict FAASM_BUILD_ENV_DICT = { "CMAKE_ROOT": FAASM_CMAKE_ROOT, "FAASM_NATIVE_INSTALL_DIR": FAASM_NATIVE_DIR, @@ -206,6 +208,8 @@ "FAASM_WASM_SYSROOT": WASM_SYSROOT, "FAASM_WASM_CFLAGS": " ".join(WASM_CFLAGS), "FAASM_WASM_CFLAGS_SHARED": " ".join(WASM_CFLAGS_SHARED), + "FAASM_WASM_CXXFLAGS": " ".join(WASM_CXXFLAGS), + "FAASM_WASM_CXXFLAGS_SHARED": " ".join(WASM_CXXFLAGS_SHARED), "FAASM_WASM_EXE_LINKER_FLAGS": " ".join(WASM_EXE_LDFLAGS), "FAASM_WASM_EXE_LINKER_FLAGS_SHARED": " ".join(WASM_EXE_LDFLAGS_SHARED), "FAASM_WASM_SHARED_LINKER_FLAGS": " ".join(WASM_LDFLAGS_SHARED), @@ -224,6 +228,23 @@ } +def get_faasm_build_env_dict(is_threads=False): + """ + This method returns the right set of environment variables needed to use + our toolchain file as well as most cross-compilation scripts in Faasm. + """ + build_env_dicts = FAASM_BUILD_ENV_DICT + if is_threads: + build_env_dicts["FAASM_WASM_TRIPLE"] = "wasm32-wasi-threads" + build_env_dicts["FAASM_WASM_CFLAGS"] += " -pthread" + build_env_dicts["FAASM_WASM_CXXFLAGS"] += " -pthread" + build_env_dicts["FAASM_WASM_EXE_LINKER_FLAGS"] += " -Wl,--import-memory" + build_env_dicts["FAASM_WASM_EXE_LINKER_FLAGS"] += " -Wl,--export-memory" + else: + build_env_dicts["FAASM_WASM_TRIPLE"] = "wasm32-wasi" + + + def get_dict_as_cmake_vars(env_dict): return " ".join(["-D{}={}".format(k, env_dict[k]) for k in env_dict]) diff --git a/faasmtools/compile_util.py b/faasmtools/compile_util.py index a3def6af..50388f1d 100644 --- a/faasmtools/compile_util.py +++ b/faasmtools/compile_util.py @@ -9,7 +9,7 @@ from subprocess import run -def wasm_cmake(src_dir, build_dir, target, clean=False, debug=False): +def wasm_cmake(src_dir, build_dir, target, clean=False, debug=False, is_threads=False): cmake_build_type = "Debug" if debug else "Release" if exists(build_dir) and clean: diff --git a/libfaasm/CMakeLists.txt b/libfaasm/CMakeLists.txt index 55bae2cd..d17616a9 100644 --- a/libfaasm/CMakeLists.txt +++ b/libfaasm/CMakeLists.txt @@ -35,7 +35,6 @@ set(LIB_FILES zygote.cpp ) - if (CMAKE_SYSTEM_NAME STREQUAL "WASI") message(STATUS "Libfaasm WebAssembly build") diff --git a/tasks/func.py b/tasks/func.py index b9b29d46..ca721dec 100644 --- a/tasks/func.py +++ b/tasks/func.py @@ -15,6 +15,14 @@ NATIVE_FUNC_BUILD_DIR = join(PROJ_ROOT, "build", "native-func") +def _is_threaded_func(user, func): + """ + Work out if the function requires using the wasm32-wasi or the + wasm32-wasi-threads target + """ + return user in ["threads", "omp"] + + def _get_all_user_funcs(user): # Work out all the functions for this user (that we assume will have been # built) @@ -64,7 +72,7 @@ def compile(ctx, user, func, clean=False, debug=False, native=False): ) else: # Build the function (gets written to the build dir) - wasm_cmake(FUNC_DIR, FUNC_BUILD_DIR, func, clean, debug) + wasm_cmake(FUNC_DIR, FUNC_BUILD_DIR, func, clean, debug, _is_threaded_func(user, func)) # Copy into place _copy_built_function(user, func) @@ -145,7 +153,7 @@ def user(ctx, user, clean=False, debug=False): """ # Build all funcs for this user (will fail if any builds fail) target = "{}_all_funcs".format(user) - wasm_cmake(FUNC_DIR, FUNC_BUILD_DIR, target, clean, debug) + wasm_cmake(FUNC_DIR, FUNC_BUILD_DIR, target, clean, debug, _is_threaded_func(user, "")) funcs = _get_all_user_funcs(user) for f in funcs: diff --git a/third-party/wasi-libc b/third-party/wasi-libc index df72bea1..b37edadc 160000 --- a/third-party/wasi-libc +++ b/third-party/wasi-libc @@ -1 +1 @@ -Subproject commit df72bea123a7b1d670a9bfba15124e7e02e22baa +Subproject commit b37edadc81a9c24b3c4c93f1ba8e14210144832f