From df364ff665b01a3add723d268dc8a223c8ca31b2 Mon Sep 17 00:00:00 2001 From: Seonghyun Kim Date: Tue, 6 Oct 2026 13:48:10 +0900 Subject: [PATCH 1/2] Update cmake files for support cmake 2.8.12~4.x Use standard CMake inputs and independent library, shell and API test options. Select configuration flags at build time for multi-config generators and retain legacy input aliases. Update GCutil to the latest bdwgc_8_3_pre_260715 branch and make WABT and WASI builds compatible with the supported CMake versions. Update build instructions and CI commands. Signed-off-by: Seonghyun Kim --- .github/workflows/actions.yml | 48 ++++----- .gitmodules | 1 + CMakeLists.txt | 156 ++++++++++++++++++++---------- README.md | 36 +++++-- build/config.cmake | 23 ++--- build/target.cmake | 78 +++++++-------- build/walrus.cmake | 131 +++++++++++++------------ third_party/GCutil | 2 +- third_party/uvwasi/CMakeLists.txt | 55 +++++------ third_party/wabt/CMakeLists.txt | 11 ++- 10 files changed, 305 insertions(+), 236 deletions(-) diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index dcea171cf..5aa28ae58 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -41,9 +41,9 @@ jobs: brew install ninja pkg-config - name: Build x64 env: - BUILD_OPTIONS: -DWALRUS_MODE=${{ matrix.mode }} -DWALRUS_OUTPUT=shell -GNinja + BUILD_OPTIONS: -DCMAKE_BUILD_TYPE=${{ matrix.mode }} -DWALRUS_ENABLE_SHELL=ON -GNinja run: | - cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/mac $BUILD_OPTIONS + cmake -H. -Bout/mac $BUILD_OPTIONS ninja -Cout/mac - name: "Remove 2 test files due to stack overflow occurred by recursion calls in debug mode build by clang" if: matrix.mode == 'debug' && matrix.switch == '' @@ -78,9 +78,9 @@ jobs: brew install ninja - name: Build arm64 env: - BUILD_OPTIONS: -DWALRUS_MODE=${{ matrix.mode }} -DWALRUS_OUTPUT=shell -GNinja + BUILD_OPTIONS: -DCMAKE_BUILD_TYPE=${{ matrix.mode }} -DWALRUS_ENABLE_SHELL=ON -GNinja run: | - cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/mac $BUILD_OPTIONS + cmake -H. -Bout/mac $BUILD_OPTIONS ninja -Cout/mac - name: "Remove 2 test files due to stack overflow occurred by recursion calls in debug mode build by clang" if: matrix.mode == 'debug' @@ -131,9 +131,9 @@ jobs: sudo apt install -y ninja-build gcc-multilib g++-multilib - name: ${{ matrix.compile.name }} ${{ matrix.arch }} env: - BUILD_OPTIONS: -DWALRUS_ARCH=${{ matrix.arch }} -DWALRUS_MODE=${{ matrix.mode }} -DWALRUS_OUTPUT=shell ${{ matrix.compile.options }} -GNinja + BUILD_OPTIONS: -DWALRUS_ARCH=${{ matrix.arch }} -DCMAKE_BUILD_TYPE=${{ matrix.mode }} -DWALRUS_ENABLE_SHELL=ON ${{ matrix.compile.options }} -GNinja run: | - CC=clang CXX=clang++ cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/ $BUILD_OPTIONS + CC=clang CXX=clang++ cmake -H. -Bout/ $BUILD_OPTIONS ninja -Cout/ - name: "Remove 2 test files due to stack overflow occurred by recursion calls in debug mode build by clang when walrus interpreter is used" if: matrix.mode == 'debug' && matrix.switch == '' @@ -173,9 +173,9 @@ jobs: sudo apt install -y ninja-build gcc-multilib g++-multilib - name: Build ${{ matrix.arch }} env: - BUILD_OPTIONS: -DWALRUS_ARCH=${{ matrix.arch }} -DWALRUS_HOST=linux -DWALRUS_MODE=debug -DWALRUS_OUTPUT=shell -GNinja + BUILD_OPTIONS: -DWALRUS_ARCH=${{ matrix.arch }} -DWALRUS_HOST=linux -DCMAKE_BUILD_TYPE=Debug -DWALRUS_ENABLE_SHELL=ON -GNinja run: | - cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/linux/${{ matrix.arch }} $BUILD_OPTIONS + cmake -H. -Bout/linux/${{ matrix.arch }} $BUILD_OPTIONS ninja -Cout/linux/${{ matrix.arch }} - name: Run Tests run: | @@ -193,9 +193,9 @@ jobs: sudo apt install -y ninja-build gcc-multilib g++-multilib - name: Build x64 env: - BUILD_OPTIONS: -DWALRUS_JITPERF=1 -DWALRUS_MODE=debug -DWALRUS_OUTPUT=shell -GNinja + BUILD_OPTIONS: -DWALRUS_JITPERF=1 -DCMAKE_BUILD_TYPE=Debug -DWALRUS_ENABLE_SHELL=ON -GNinja run: | - cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/linux/x64 $BUILD_OPTIONS + cmake -H. -Bout/linux/x64 $BUILD_OPTIONS ninja -Cout/linux/x64 build-test-on-aarch64-linux: @@ -219,9 +219,9 @@ jobs: sudo apt install -y ninja-build - name: Build aarch64-${{ matrix.mode }} ( ${{ matrix.switch }} ) env: - BUILD_OPTIONS: -DWALRUS_ARCH=aarch64 -DWALRUS_HOST=linux -DWALRUS_MODE=${{ matrix.mode }}-DWALRUS_OUTPUT=shell -GNinja + BUILD_OPTIONS: -DWALRUS_ARCH=aarch64 -DWALRUS_HOST=linux -DCMAKE_BUILD_TYPE=${{ matrix.mode }} -DWALRUS_ENABLE_SHELL=ON -GNinja run: | - cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/linux/aarch64/${{ matrix.mode }} $BUILD_OPTIONS + cmake -H. -Bout/linux/aarch64/${{ matrix.mode }} $BUILD_OPTIONS ninja -Cout/linux/aarch64/${{ matrix.mode }} - name: Run Tests run: | @@ -307,7 +307,7 @@ jobs: CFLAGS: ${{ matrix.arch.toolchain.CFLAGS }} CXXFLAGS: ${{ matrix.arch.toolchain.CXXFLAGS }} run: | - cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -DCMAKE_EXE_LINKER_FLAGS="-static" -Bout/ -DCMAKE_BUILD_TYPE=${{ matrix.mode }} -DWALRUS_ARCH=${{ matrix.arch.walrus }} -DWALRUS_HOST=linux -DWALRUS_MODE=debug -DWALRUS_OUTPUT=shell ${{ matrix.compile.options }} -GNinja + cmake -H. -DCMAKE_EXE_LINKER_FLAGS="-static" -Bout/ -DCMAKE_BUILD_TYPE=${{ matrix.mode }} -DWALRUS_ARCH=${{ matrix.arch.walrus }} -DWALRUS_HOST=linux -DWALRUS_ENABLE_SHELL=ON ${{ matrix.compile.options }} -GNinja ninja -C out/ - name: "Remove 2 test files due to stack overflow occurred by recursion calls in interpreter mode build by gcc" if: matrix.switch == '' @@ -371,7 +371,7 @@ jobs: sdk: "10.0.26100.0" - name: Build ${{ matrix.arch }} Release run: | - CMake -DCMAKE_POLICY_VERSION_MINIMUM="3.5" -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_SYSTEM_VERSION:STRING="10.0" -DCMAKE_SYSTEM_PROCESSOR=${{ matrix.arch }} -Bout/ -G Ninja -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=release + CMake -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_SYSTEM_VERSION:STRING="10.0" -DCMAKE_SYSTEM_PROCESSOR=${{ matrix.arch }} -Bout/ -G Ninja -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=release CMake --build out/ --config Release - name: Run tests run: | @@ -399,9 +399,9 @@ jobs: sudo apt install -y ninja-build gcc-multilib g++-multilib - name: Build ${{ matrix.arch}} env: - BUILD_OPTIONS: -DWALRUS_ARCH=${{ matrix.arch }} -DWALRUS_HOST=linux -DWALRUS_MODE=${{ matrix.mode }} -DWALRUS_OUTPUT=shell -DWALRUS_EXTENDED_FEATURES=ON -GNinja + BUILD_OPTIONS: -DWALRUS_ARCH=${{ matrix.arch }} -DWALRUS_HOST=linux -DCMAKE_BUILD_TYPE=${{ matrix.mode }} -DWALRUS_ENABLE_SHELL=ON -DWALRUS_EXTENDED_FEATURES=ON -GNinja run: | - cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/extended $BUILD_OPTIONS + cmake -H. -Bout/extended $BUILD_OPTIONS ninja -Cout/extended - name: Run Tests run: | @@ -428,9 +428,9 @@ jobs: sudo pip install tqdm - name: Build ${{ matrix.arch }} env: - BUILD_OPTIONS: -DWALRUS_ARCH=${{ matrix.arch }} -DWALRUS_HOST=linux -DWALRUS_MODE=release -DWALRUS_OUTPUT=shell -GNinja + BUILD_OPTIONS: -DWALRUS_ARCH=${{ matrix.arch }} -DWALRUS_HOST=linux -DCMAKE_BUILD_TYPE=Release -DWALRUS_ENABLE_SHELL=ON -GNinja run: | - cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/linux/${{ matrix.arch }} $BUILD_OPTIONS + cmake -H. -Bout/linux/${{ matrix.arch }} $BUILD_OPTIONS ninja -Cout/linux/${{ matrix.arch }} - name: Run Tests run: | @@ -456,9 +456,9 @@ jobs: sudo pip install py-markdown-table - name: Build ${{ matrix.arch }} env: - BUILD_OPTIONS: -DWALRUS_ARCH=${{ matrix.arch }} -DWALRUS_HOST=linux -DWALRUS_MODE=release -DWALRUS_OUTPUT=shell -GNinja + BUILD_OPTIONS: -DWALRUS_ARCH=${{ matrix.arch }} -DWALRUS_HOST=linux -DCMAKE_BUILD_TYPE=Release -DWALRUS_ENABLE_SHELL=ON -GNinja run: | - cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/polybench/${{ matrix.arch }} $BUILD_OPTIONS + cmake -H. -Bout/polybench/${{ matrix.arch }} $BUILD_OPTIONS ninja -Cout/polybench/${{ matrix.arch }} - name: Run PolyBench Tests run: | @@ -480,9 +480,9 @@ jobs: sudo apt install -y ninja-build gcc-multilib g++-multilib - name: Build x64 env: - BUILD_OPTIONS: -DWALRUS_MODE=${{ matrix.mode }} -DWALRUS_ARCH=x64 -DWALRUS_OUTPUT=api_test -GNinja + BUILD_OPTIONS: -DCMAKE_BUILD_TYPE=${{ matrix.mode }} -DWALRUS_ARCH=x64 -DWALRUS_ENABLE_SHELL=OFF -DWALRUS_BUILD_API_TESTS=ON -GNinja run: | - cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/api_test $BUILD_OPTIONS + cmake -H. -Bout/api_test $BUILD_OPTIONS ninja -Cout/api_test cp third_party/wasm-c-api/example/*.wasm out/api_test/. - name: Run Tests @@ -515,10 +515,10 @@ jobs: tar xzf cov-analysis-linux64.tar.gz --strip 1 -C cov-analysis-linux64 - name: Build env: - BUILD_OPTIONS: -DWALRUS_MODE=release -DWALRUS_OUTPUT=shell -GNinja + BUILD_OPTIONS: -DCMAKE_BUILD_TYPE=Release -DWALRUS_ENABLE_SHELL=ON -GNinja run: | export PATH=$GITHUB_WORKSPACE/cov-analysis-linux64/bin:$PATH - cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/coverity_scan $BUILD_OPTIONS + cmake -H. -Bout/coverity_scan $BUILD_OPTIONS cov-build --dir cov-int ninja -Cout/coverity_scan - name: Submit env: diff --git a/.gitmodules b/.gitmodules index 475901e6b..a2a4cf8c4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,6 +5,7 @@ [submodule "third_party/GCutil"] path = third_party/GCutil url = https://github.com/Samsung/gcutil.git + branch = bdwgc_8_3_pre_260715 ignore = untracked [submodule "third_party/wasm-c-api"] path = third_party/wasm-c-api diff --git a/CMakeLists.txt b/CMakeLists.txt index db802a4ec..15bcfb554 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,87 +1,145 @@ -CMAKE_MINIMUM_REQUIRED (VERSION 2.8.12) +# Older CMake ignores the policy upper bound; CMake 4.x requires it. +CMAKE_MINIMUM_REQUIRED (VERSION 2.8.12...4.0 FATAL_ERROR) PROJECT (WALRUS) # CONFIGURATION SET (CMAKE_EXPORT_COMPILE_COMMANDS ON) -# input variable list -# WALRUS_ASAN, WALRUS_SMALL_CONFIG, WALRUS_DEBUG_INFO - -MESSAGE(VERBOSE "CMAKE_SYSTEM_NAME: " ${CMAKE_SYSTEM_NAME}) -MESSAGE(VERBOSE "CMAKE_SYSTEM_PROCESSOR: " ${CMAKE_SYSTEM_PROCESSOR}) -# TODO: Support multi-config generator -MESSAGE(VERBOSE "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE}) -IF (NOT DEFINED WALRUS_MODE) - IF ("${CMAKE_BUILD_TYPE}" STREQUAL "") - SET(WALRUS_MODE "release") - ELSEIF (${CMAKE_BUILD_TYPE} STREQUAL "Release") - SET(WALRUS_MODE "release") - ELSEIF (${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") - SET(WALRUS_MODE "release") - SET(WALRUS_DEBUG_INFO ON) - ELSEIF (${CMAKE_BUILD_TYPE} STREQUAL "MinSizeRel") - SET(WALRUS_MODE "release") - SET(WALRUS_SMALL_CONFIG ON) +# Honor standard CMake configuration variables. Legacy inputs remain aliases. +IF (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) + IF (DEFINED WALRUS_MODE) + IF (WALRUS_MODE STREQUAL "debug") + SET (_walrus_build_type Debug) + ELSEIF (WALRUS_MODE STREQUAL "release") + SET (_walrus_build_type Release) + ELSE() + MESSAGE (FATAL_ERROR "WALRUS_MODE must be debug or release") + ENDIF() ELSE() - SET(WALRUS_MODE "debug") + SET (_walrus_build_type Release) + ENDIF() + SET (CMAKE_BUILD_TYPE "${_walrus_build_type}" CACHE STRING "Build configuration" FORCE) + SET_PROPERTY (CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release RelWithDebInfo MinSizeRel) +ENDIF() +STRING (TOLOWER "${CMAKE_BUILD_TYPE}" _walrus_build_type_lower) +IF (_walrus_build_type_lower STREQUAL "debug") + SET (WALRUS_MODE debug) +ELSE() + SET (WALRUS_MODE release) +ENDIF() + +# Detect multilib targets without changing the caller's platform variables. +SET (_walrus_processor "${CMAKE_SYSTEM_PROCESSOR}") +IF (CMAKE_SIZEOF_VOID_P EQUAL 4 AND _walrus_processor MATCHES "^(x86_64|AMD64|x64)$") + SET (_walrus_processor i386) +ENDIF() +IF (("${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS} $ENV{CFLAGS} $ENV{CXXFLAGS} $ENV{LDFLAGS}" MATCHES "-m32") + AND (_walrus_processor MATCHES "^(x86_64|AMD64|x64)$")) + SET (_walrus_processor i386) +ENDIF() +IF (NOT _walrus_processor AND CMAKE_OSX_ARCHITECTURES) + LIST (LENGTH CMAKE_OSX_ARCHITECTURES _walrus_arch_count) + IF (_walrus_arch_count EQUAL 1) + SET (_walrus_processor "${CMAKE_OSX_ARCHITECTURES}") ENDIF() ENDIF() IF (NOT DEFINED WALRUS_ARCH) - IF (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "X86" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86" - OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i386" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i686") + IF (_walrus_processor STREQUAL "X86" OR _walrus_processor STREQUAL "x86" + OR _walrus_processor STREQUAL "i386" OR _walrus_processor STREQUAL "i686") SET(WALRUS_ARCH "x86") - ELSEIF (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64" - OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x64" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "EM64T") + ELSEIF (_walrus_processor STREQUAL "AMD64" OR _walrus_processor STREQUAL "x86_64" + OR _walrus_processor STREQUAL "x64" OR _walrus_processor STREQUAL "EM64T") SET(WALRUS_ARCH "x64") - ELSEIF (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm32" - OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "armv7l") + ELSEIF (_walrus_processor STREQUAL "arm" OR _walrus_processor STREQUAL "arm32" + OR _walrus_processor STREQUAL "armv7l") SET(WALRUS_ARCH "arm") - ELSEIF (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm64" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64") + ELSEIF (_walrus_processor STREQUAL "arm64" OR _walrus_processor STREQUAL "ARM64" OR _walrus_processor STREQUAL "aarch64" OR _walrus_processor STREQUAL "AARCH64") SET(WALRUS_ARCH "aarch64") - ELSEIF (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "riscv64") + ELSEIF (_walrus_processor STREQUAL "riscv64") SET(WALRUS_ARCH "riscv64") ENDIF() ENDIF() IF (NOT DEFINED WALRUS_HOST) - IF (${CMAKE_SYSTEM_NAME} STREQUAL "Windows" OR ${CMAKE_SYSTEM_NAME} STREQUAL "WindowsStore") + IF (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") SET(WALRUS_HOST "windows") - ELSEIF (${CMAKE_SYSTEM_NAME} STREQUAL "Android") + ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "Android") SET(WALRUS_HOST "android") - ELSEIF (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") + ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "Darwin") SET(WALRUS_HOST "darwin") + ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "Tizen") + SET(WALRUS_HOST "tizen") ELSE() SET(WALRUS_HOST "linux") ENDIF() ENDIF() -IF (NOT DEFINED WALRUS_MODE) - SET (WALRUS_MODE "release") +# Preserve parent-provided normal variables on old CMake too (CMP0077 only +# exists since 3.13), and keep all inputs visible as BOOL cache entries. +MACRO (WALRUS_OPTION _name _help _default) + IF (DEFINED ${_name}) + SET (${_name} "${${_name}}" CACHE BOOL "${_help}") + ENDIF() + OPTION (${_name} "${_help}" "${_default}") +ENDMACRO() + +# Project-specific booleans inherit standard defaults without modifying them. +SET (_walrus_shared_default OFF) +IF (DEFINED BUILD_SHARED_LIBS) + SET (_walrus_shared_default "${BUILD_SHARED_LIBS}") ENDIF() -IF (NOT DEFINED WALRUS_OUTPUT) - SET (WALRUS_OUTPUT "shell") +SET (_walrus_shell_default ON) +IF (DEFINED ENABLE_SHELL) + SET (_walrus_shell_default "${ENABLE_SHELL}") ENDIF() - -IF (NOT DEFINED WALRUS_WASI) - # Enable WASI by default - SET (WALRUS_WASI ON) - - IF(NOT DEFINED WALRUS_WASI_NN) - SET (WALRUS_WASI_NN OFF) +SET (_walrus_api_test_default OFF) +IF (DEFINED WALRUS_OUTPUT) + IF (WALRUS_OUTPUT STREQUAL "shared_lib") + SET (_walrus_shared_default ON) + SET (_walrus_shell_default OFF) + ELSEIF (WALRUS_OUTPUT STREQUAL "static_lib") + SET (_walrus_shared_default OFF) + SET (_walrus_shell_default OFF) + ELSEIF (WALRUS_OUTPUT STREQUAL "api_test") + SET (_walrus_shared_default OFF) + SET (_walrus_shell_default OFF) + SET (_walrus_api_test_default ON) + ELSEIF (WALRUS_OUTPUT STREQUAL "shell") + SET (_walrus_shell_default ON) + ELSE() + MESSAGE (FATAL_ERROR "Unknown WALRUS_OUTPUT: ${WALRUS_OUTPUT}") ENDIF() ENDIF() - -IF (NOT DEFINED WALRUS_GC) - # Enable gc by default - SET (WALRUS_GC ON) +WALRUS_OPTION (WALRUS_BUILD_SHARED_LIBS "Build the Walrus library as a shared library" ${_walrus_shared_default}) +WALRUS_OPTION (WALRUS_BUILD_GC_SHARED_LIBS "Build GCutil as a shared library" OFF) +WALRUS_OPTION (WALRUS_ENABLE_SHELL "Build the Walrus command-line shell" ${_walrus_shell_default}) +WALRUS_OPTION (WALRUS_BUILD_API_TESTS "Build wasm-c-api examples" ${_walrus_api_test_default}) +WALRUS_OPTION (WALRUS_WASI "Enable WASI support" ON) +WALRUS_OPTION (WALRUS_WASI_NN "Enable WASI neural-network support (requires CMake 3.14+)" OFF) +WALRUS_OPTION (WALRUS_GC "Enable WebAssembly garbage collection" ON) +WALRUS_OPTION (WALRUS_JIT "Enable the JIT compiler" ON) +WALRUS_OPTION (WALRUS_ASAN "Build with AddressSanitizer" OFF) +WALRUS_OPTION (WALRUS_SMALL_CONFIG "Optimize for binary size" OFF) +WALRUS_OPTION (WALRUS_DEBUG_INFO "Include debug information" OFF) +WALRUS_OPTION (WALRUS_VALGRIND "Enable Valgrind profiling" OFF) +WALRUS_OPTION (WALRUS_GOOGLE_PERF "Enable Google performance profiling" OFF) +WALRUS_OPTION (WALRUS_COVERAGE "Enable code coverage" OFF) +WALRUS_OPTION (WALRUS_JITPERF "Enable JIT perf support" OFF) +IF (WALRUS_WASI_NN AND NOT WALRUS_WASI) + MESSAGE (FATAL_ERROR "WALRUS_WASI_NN requires WALRUS_WASI=ON") +ENDIF() +IF (WALRUS_WASI_NN AND CMAKE_VERSION VERSION_LESS 3.14) + MESSAGE (FATAL_ERROR "WALRUS_WASI_NN requires CMake 3.14 or newer") ENDIF() MESSAGE(STATUS "Walrus Arch: " ${WALRUS_ARCH}) MESSAGE(STATUS "Walrus Host: " ${WALRUS_HOST}) MESSAGE(STATUS "Walrus Mode: " ${WALRUS_MODE}) -MESSAGE(STATUS "Walrus Output: " ${WALRUS_OUTPUT}) +MESSAGE(STATUS "Walrus Shared Library: " ${WALRUS_BUILD_SHARED_LIBS}) +MESSAGE(STATUS "Walrus Shell: " ${WALRUS_ENABLE_SHELL}) +MESSAGE(STATUS "Walrus API Tests: " ${WALRUS_BUILD_API_TESTS}) MESSAGE(STATUS "Walrus WASI Enabled: " ${WALRUS_WASI}) MESSAGE(STATUS "Walrus GC Enabled: " ${WALRUS_GC}) MESSAGE(STATUS "Walrus WASI-NN Enabled: " ${WALRUS_WASI_NN}) @@ -95,5 +153,5 @@ INCLUDE (ProcessorCount) PROCESSORCOUNT (NPROCS) # INCLUDE CMAKE FILES -INCLUDE (${PROJECT_SOURCE_DIR}/build/config.cmake) -INCLUDE (${PROJECT_SOURCE_DIR}/build/walrus.cmake) +INCLUDE (${CMAKE_CURRENT_SOURCE_DIR}/build/config.cmake) +INCLUDE (${CMAKE_CURRENT_SOURCE_DIR}/build/walrus.cmake) diff --git a/README.md b/README.md index 785b2bd55..d26ea9706 100644 --- a/README.md +++ b/README.md @@ -22,16 +22,40 @@ This will fetch the testsuite and gtest repos, which are needed for some tests. You'll need [CMake](https://cmake.org). You can then run CMake, the normal way: -> Note: Due to the need for supporting old targets only supporting cmake 2.8, the defined cmake version is 2.8, however due to many environments shipping newer cmake versions which do not support cmake versions below 3.5, you may need to override the minimum version using `-DCMAKE_POLICY_VERSION_MINIMUM=3.5` +The build supports CMake 2.8.12 through 4.x without a policy-version override. +WASI uses a system libuv (with pkg-config); when none is available, downloading +libuv requires CMake 3.14 or newer. WASI-NN requires CMake 3.14 or newer. ```console -$ cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -H. -Bout/release/x64 -DWALRUS_ARCH=x64 -DWALRUS_HOST=linux -DWALRUS_MODE=release -DWALRUS_OUTPUT=shell -GNinja -$ ninja -Cout/release/x64 -$ ./out/release/x64/walrus test.wasm // run walrus executable +$ cmake -H. -Bout/release/x64 -DCMAKE_BUILD_TYPE=Release -DWALRUS_ENABLE_SHELL=ON -GNinja +$ cmake --build out/release/x64 +$ ./out/release/x64/walrus test.wasm ``` -This will produce build files using CMake's default build generator. Read the -CMake documentation for more information. +Use standard CMake inputs for the build configuration (`CMAKE_BUILD_TYPE` or +`cmake --build ... --config Debug` with a multi-config generator), target system +(`CMAKE_SYSTEM_NAME`, `CMAKE_SYSTEM_PROCESSOR`, or `CMAKE_TOOLCHAIN_FILE`) and +compiler flags (`CMAKE_C_FLAGS`, `CMAKE_CXX_FLAGS`, and `CMAKE_*_LINKER_FLAGS`). + +| Option | Default | Purpose | +| --- | --- | --- | +| `WALRUS_BUILD_SHARED_LIBS` | `BUILD_SHARED_LIBS`, otherwise `OFF` | Build a shared rather than static Walrus library | +| `WALRUS_BUILD_GC_SHARED_LIBS` | `OFF` | Build GCutil as a shared library | +| `WALRUS_ENABLE_SHELL` | `ENABLE_SHELL`, otherwise `ON` | Build the `walrus` executable alongside the library | +| `WALRUS_BUILD_API_TESTS` | `OFF` | Build wasm-c-api examples | +| `WALRUS_WASI` | `ON` | Enable WASI | +| `WALRUS_WASI_NN` | `OFF` | Enable WASI neural networks | +| `WALRUS_GC` | `ON` | Enable WebAssembly GC | +| `WALRUS_JIT` | `ON` | Enable JIT compilation | +| `WALRUS_ASAN` | `OFF` | Enable AddressSanitizer | +| `WALRUS_SMALL_CONFIG` | `OFF` | Optimize for binary size | +| `WALRUS_DEBUG_INFO` | `OFF` | Add debug information independently of build type | + +`WALRUS_HOST` and `WALRUS_ARCH` remain available as explicit overrides. +Legacy `WALRUS_MODE=debug/release` supplies the default build type when +`CMAKE_BUILD_TYPE` is unset. Legacy `WALRUS_OUTPUT=shell/static_lib/shared_lib/api_test` +supplies defaults for the independent output options; explicit new options take +precedence. Walrus does not overwrite the parent's `BUILD_SHARED_LIBS` or `ENABLE_SHELL`. ## Perf diff --git a/build/config.cmake b/build/config.cmake index 7acb91ecc..831f9a08c 100644 --- a/build/config.cmake +++ b/build/config.cmake @@ -5,7 +5,7 @@ ####################################################### # PATH ####################################################### -SET (WALRUS_ROOT ${PROJECT_SOURCE_DIR}) +SET (WALRUS_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) SET (WALRUS_THIRD_PARTY_ROOT ${WALRUS_ROOT}/third_party) SET (SLJIT_ROOT ${WALRUS_THIRD_PARTY_ROOT}/sljit) SET (GCUTIL_ROOT ${WALRUS_THIRD_PARTY_ROOT}/GCutil) @@ -24,22 +24,11 @@ SET (WALRUS_DEFINITIONS -DWALRUS ) -SET (CXXFLAGS_FROM_ENV $ENV{CXXFLAGS}) -SEPARATE_ARGUMENTS(CXXFLAGS_FROM_ENV) -SET (LDFLAGS_FROM_ENV $ENV{LDFLAGS}) -SEPARATE_ARGUMENTS(LDFLAGS_FROM_ENV) - -# these flags assigned from external should have the highest priority -SET (CXXFLAGS_FROM_ENV ${CXXFLAGS_FROM_ENV} ${WALRUS_CXXFLAGS_FROM_EXTERNAL}) -SET (LDFLAGS_FROM_ENV ${LDFLAGS_FROM_ENV} ${WALRUS_LDFLAGS_FROM_EXTERNAL}) - -IF (${WALRUS_OUTPUT} STREQUAL "shared_lib" AND ${WALRUS_HOST} STREQUAL "android") - SET (WALRUS_LDFLAGS ${WALRUS_LDFLAGS} -shared) -ENDIF() - -IF (NOT DEFINED WALRUS_JIT) - SET (WALRUS_JIT ON) -ENDIF() +# CMake already consumes CXXFLAGS and LDFLAGS when initializing its cache. +# Keep only the legacy explicit flag lists here to avoid applying environment +# flags twice or overriding configuration-specific optimization flags. +SET (CXXFLAGS_FROM_ENV ${WALRUS_CXXFLAGS_FROM_EXTERNAL}) +SET (LDFLAGS_FROM_ENV ${WALRUS_LDFLAGS_FROM_EXTERNAL}) ####################################################### # FLAGS FOR ADDITIONAL FUNCTION diff --git a/build/target.cmake b/build/target.cmake index 0fa6d8a2a..faac0fbc4 100644 --- a/build/target.cmake +++ b/build/target.cmake @@ -15,20 +15,20 @@ SET (WALRUS_BUILD_64BIT OFF) # clang-cl defines ${CMAKE_CXX_COMPILER_ID} "Clang" and ${CMAKE_CXX_COMPILER_FRONTEND_VARIANT} "MSVC" SET (COMPILER_CLANG_CL OFF) -IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") +IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") IF (DEFINED CMAKE_CXX_COMPILER_FRONTEND_VARIANT) - IF ("${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "MSVC") + IF (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") SET (COMPILER_CLANG_CL ON) ENDIF() ENDIF() ENDIF() # Default options per compiler -IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" OR ${COMPILER_CLANG_CL}) +IF (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR COMPILER_CLANG_CL) SET (WALRUS_CXXFLAGS /std:c++14 /fp:strict /Zc:__cplusplus /EHs /source-charset:utf-8 /D_CRT_SECURE_NO_WARNINGS /DGC_NOT_DLL /D_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING /wd4244 /wd4267 /wd4805 /wd4018 /wd4172) SET (WALRUS_CXXFLAGS_RELEASE /O2 /Oy-) SET (WALRUS_THIRDPARTY_CFLAGS /D_CRT_SECURE_NO_WARNINGS /DGC_NOT_DLL /Oy- /wd4146 /EHs) - IF (${COMPILER_CLANG_CL}) + IF (COMPILER_CLANG_CL) SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS} /EHs -Wno-invalid-offsetof -Wno-inline-new-delete -fintegrated-cc1) ENDIF() @@ -36,16 +36,16 @@ IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" OR ${COMPILER_CLANG_CL}) SET (WALRUS_CXXFLAGS_RELEASE ${WALRUS_CXXFLAGS_RELEASE} /Os) ENDIF() IF (WALRUS_DEBUG_INFO) - SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS} /DEBUG:FULL) + SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS} /Zi) ENDIF() SET (WALRUS_CXXFLAGS_SHAREDLIB) SET (WALRUS_LDFLAGS_SHAREDLIB) - SET (WALRUS_CXXFLAGS_STATICLIB /DWASM_API_EXTERN) - SET (WALRUS_CXXFLAGS_SHELL /DWASM_API_EXTERN /std:c++14) -ELSEIF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + SET (WALRUS_CXXFLAGS_STATICLIB /DWASM_API_EXTERN=) + SET (WALRUS_CXXFLAGS_SHELL /DWASM_API_EXTERN= /std:c++14) +ELSEIF (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS} - -std=c++11 -g3 + -std=c++11 -fno-rtti -fno-math-errno -fdata-sections -ffunction-sections @@ -62,7 +62,7 @@ ELSEIF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") endif() SET (WALRUS_CXXFLAGS_DEBUG -O0 -Wall -Wextra -Werror) SET (WALRUS_CXXFLAGS_RELEASE -O2 -fno-stack-protector -fno-omit-frame-pointer) - SET (WALRUS_THIRDPARTY_CFLAGS -w -g3 -fdata-sections -ffunction-sections -fno-omit-frame-pointer -fvisibility=hidden) + SET (WALRUS_THIRDPARTY_CFLAGS -w -fdata-sections -ffunction-sections -fno-omit-frame-pointer -fvisibility=hidden) IF (WALRUS_SMALL_CONFIG) SET (WALRUS_CXXFLAGS_RELEASE ${WALRUS_CXXFLAGS_RELEASE} -Os) @@ -75,10 +75,10 @@ ELSEIF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") SET (WALRUS_CXXFLAGS_STATICLIB -fPIC -DWASM_API_EXTERN=) SET (WALRUS_CXXFLAGS_SHELL -DWASM_API_EXTERN= -frtti -std=c++11) -ELSEIF ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # Clang and AppleClang +ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang") # Clang and AppleClang SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS} - -std=c++11 -g3 + -std=c++11 -fno-rtti -fno-math-errno -fdata-sections -ffunction-sections @@ -97,7 +97,7 @@ ELSEIF ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # Clang and AppleClang endif() SET (WALRUS_CXXFLAGS_DEBUG -O0 -Wall -Wextra -Werror) SET (WALRUS_CXXFLAGS_RELEASE -O2 -fno-stack-protector -fno-omit-frame-pointer) - SET (WALRUS_THIRDPARTY_CFLAGS -w -g3 -fdata-sections -ffunction-sections -fno-omit-frame-pointer -fvisibility=hidden) + SET (WALRUS_THIRDPARTY_CFLAGS -w -fdata-sections -ffunction-sections -fno-omit-frame-pointer -fvisibility=hidden) IF (WALRUS_SMALL_CONFIG) SET (WALRUS_CXXFLAGS_RELEASE ${WALRUS_CXXFLAGS_RELEASE} -Os) @@ -114,73 +114,73 @@ ELSE() ENDIF() # Default options per host -IF (${WALRUS_HOST} STREQUAL "linux") +IF (WALRUS_HOST STREQUAL "linux") FIND_PACKAGE (PkgConfig REQUIRED) # default set of LDFLAGS SET (WALRUS_LDFLAGS -lpthread -lrt -Wl,--gc-sections) - IF ((${WALRUS_ARCH} STREQUAL "x64") OR (${WALRUS_ARCH} STREQUAL "x86_64")) + IF ((WALRUS_ARCH STREQUAL "x64") OR (WALRUS_ARCH STREQUAL "x86_64")) SET (WALRUS_BUILD_64BIT ON) - ELSEIF ((${WALRUS_ARCH} STREQUAL "x86") OR (${WALRUS_ARCH} STREQUAL "i686")) + ELSEIF ((WALRUS_ARCH STREQUAL "x86") OR (WALRUS_ARCH STREQUAL "i686")) SET (WALRUS_BUILD_32BIT ON) SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS} -m32 -mfpmath=sse -msse -msse2) SET (WALRUS_LDFLAGS ${WALRUS_LDFLAGS} -m32) SET (WALRUS_THIRDPARTY_CFLAGS ${WALRUS_THIRDPARTY_CFLAGS} -m32) - ELSEIF (${WALRUS_ARCH} STREQUAL "arm") + ELSEIF (WALRUS_ARCH STREQUAL "arm") SET (WALRUS_BUILD_32BIT ON) - ELSEIF (${WALRUS_ARCH} STREQUAL "aarch64") + ELSEIF (WALRUS_ARCH STREQUAL "aarch64") SET (WALRUS_BUILD_64BIT ON) - ELSEIF (${WALRUS_ARCH} STREQUAL "riscv64") + ELSEIF (WALRUS_ARCH STREQUAL "riscv64") SET (WALRUS_BUILD_64BIT ON) ELSE() MESSAGE (FATAL_ERROR ${WALRUS_ARCH} " is unsupported") ENDIF() -ELSEIF (${WALRUS_HOST} STREQUAL "tizen" OR ${WALRUS_HOST} STREQUAL "tizen_obs") +ELSEIF (WALRUS_HOST STREQUAL "tizen" OR WALRUS_HOST STREQUAL "tizen_obs") FIND_PACKAGE (PkgConfig REQUIRED) # default set of LDFLAGS SET (WALRUS_LDFLAGS -lpthread -lrt -Wl,--gc-sections) SET (WALRUS_DEFINITIONS -DWALRUS_TIZEN) - IF ((${WALRUS_ARCH} STREQUAL "x64") OR (${WALRUS_ARCH} STREQUAL "x86_64")) + IF ((WALRUS_ARCH STREQUAL "x64") OR (WALRUS_ARCH STREQUAL "x86_64")) SET (WALRUS_BUILD_64BIT ON) - ELSEIF ((${WALRUS_ARCH} STREQUAL "x86") OR (${WALRUS_ARCH} STREQUAL "i686")) + ELSEIF ((WALRUS_ARCH STREQUAL "x86") OR (WALRUS_ARCH STREQUAL "i686")) SET (WALRUS_BUILD_32BIT ON) SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS} -m32 -mfpmath=sse -msse -msse2) SET (WALRUS_LDFLAGS ${WALRUS_LDFLAGS} -m32) SET (WALRUS_THIRDPARTY_CFLAGS ${WALRUS_THIRDPARTY_CFLAGS} -m32) - ELSEIF (${WALRUS_ARCH} STREQUAL "arm") + ELSEIF (WALRUS_ARCH STREQUAL "arm") SET (WALRUS_BUILD_32BIT ON) SET (WALRUS_CXXFLAGS_DEBUG -O1) SET (WALRUS_CXXFLAGS_RELEASE -O2) - ELSEIF (${WALRUS_ARCH} STREQUAL "aarch64") + ELSEIF (WALRUS_ARCH STREQUAL "aarch64") SET (WALRUS_BUILD_64BIT ON) - ELSEIF (${WALRUS_ARCH} STREQUAL "riscv64") + ELSEIF (WALRUS_ARCH STREQUAL "riscv64") SET (WALRUS_BUILD_64BIT ON) ELSE() MESSAGE (FATAL_ERROR ${WALRUS_ARCH} " is unsupported") ENDIF() -ELSEIF (${WALRUS_HOST} STREQUAL "android") +ELSEIF (WALRUS_HOST STREQUAL "android") FIND_PACKAGE (PkgConfig REQUIRED) SET (WALRUS_DEFINITIONS -DANDROID=1 -DWALRUS_ANDROID=1) SET (WALRUS_THIRDPARTY_CFLAGS ${WALRUS_THIRDPARTY_CFLAGS} -mstackrealign) SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS} -mstackrealign) - IF (${WALRUS_ARCH} STREQUAL "arm") + IF (WALRUS_ARCH STREQUAL "arm") SET (WALRUS_BUILD_32BIT ON) SET (WALRUS_LDFLAGS -fPIE -pie -march=armv7-a -Wl,--fix-cortex-a8 -llog -Wl,--gc-sections) - ELSEIF ((${WALRUS_ARCH} STREQUAL "arm64") OR (${WALRUS_ARCH} STREQUAL "aarch64")) + ELSEIF ((WALRUS_ARCH STREQUAL "arm64") OR (WALRUS_ARCH STREQUAL "aarch64")) SET (WALRUS_BUILD_64BIT ON) SET (WALRUS_LDFLAGS -fPIE -pie -llog -Wl,--gc-sections) - ELSEIF (${WALRUS_ARCH} STREQUAL "x86") + ELSEIF (WALRUS_ARCH STREQUAL "x86") SET (WALRUS_BUILD_32BIT ON) SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS} -m32 -mfpmath=sse -msse -msse2 -mstackrealign) SET (WALRUS_LDFLAGS -fPIE -pie -llog -Wl,--gc-sections -m32) - ELSEIF (${WALRUS_ARCH} STREQUAL "x86_64" OR ${WALRUS_ARCH} STREQUAL "x64") + ELSEIF (WALRUS_ARCH STREQUAL "x86_64" OR WALRUS_ARCH STREQUAL "x64") SET (WALRUS_BUILD_64BIT ON) SET (WALRUS_LDFLAGS -fPIE -pie -llog -Wl,--gc-sections) # bdwgc android amd64 cannot support keeping back ptrs SET (WALRUS_THIRDPARTY_CFLAGS ${WALRUS_THIRDPARTY_CFLAGS} -UKEEP_BACK_PTRS -USAVE_CALL_COUNT -UDBG_HDRS_ALL) ENDIF() -ELSEIF (${WALRUS_HOST} STREQUAL "darwin") +ELSEIF (WALRUS_HOST STREQUAL "darwin") FIND_PACKAGE (PkgConfig REQUIRED) - IF ((NOT ${WALRUS_ARCH} STREQUAL "x64") AND (NOT ${WALRUS_ARCH} STREQUAL "aarch64")) + IF ((NOT WALRUS_ARCH STREQUAL "x64") AND (NOT WALRUS_ARCH STREQUAL "aarch64")) MESSAGE (FATAL_ERROR ${WALRUS_ARCH} " is unsupported") ENDIF() SET (WALRUS_LDFLAGS -lpthread -Wl,-dead_strip) @@ -188,27 +188,27 @@ ELSEIF (${WALRUS_HOST} STREQUAL "darwin") SET (WALRUS_THIRDPARTY_CFLAGS ${WALRUS_THIRDPARTY_CFLAGS} -UHAVE_PTHREAD_GETATTR_NP -UUSE_GET_STACKBASE_FOR_MAIN) SET (WALRUS_BUILD_64BIT ON) SET (WALRUS_BUILD_64BIT_LARGE ON) -ELSEIF (${WALRUS_HOST} STREQUAL "windows") +ELSEIF (WALRUS_HOST STREQUAL "windows") # in windows, default stack limit is 1MB # but expand stack to 8MB when building to exe for running test - IF (${WALRUS_OUTPUT} STREQUAL "shell") + IF (WALRUS_ENABLE_SHELL) # Default limit on windows is 1MB # but we needs more stack to pass testcases # and we needs more reserved space for process stackoverflow exception # msvc process native exception catch on top of stack :( SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS} /DSTACK_LIMIT_FROM_BASE=4194304) - SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:16777216") + SET (WALRUS_SHELL_LDFLAGS /STACK:16777216) ELSE() SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS} /DSTACK_LIMIT_FROM_BASE=524288) ENDIF() - IF ((${WALRUS_ARCH} STREQUAL "x64") OR (${WALRUS_ARCH} STREQUAL "x86_64")) + IF ((WALRUS_ARCH STREQUAL "x64") OR (WALRUS_ARCH STREQUAL "x86_64")) SET (WALRUS_BUILD_64BIT ON) - ELSEIF ((${WALRUS_ARCH} STREQUAL "x86") OR (${WALRUS_ARCH} STREQUAL "i686")) + ELSEIF ((WALRUS_ARCH STREQUAL "x86") OR (WALRUS_ARCH STREQUAL "i686")) SET (WALRUS_BUILD_32BIT ON) - ELSEIF (${WALRUS_ARCH} STREQUAL "arm") + ELSEIF (WALRUS_ARCH STREQUAL "arm") SET (WALRUS_BUILD_32BIT ON) - ELSEIF (${WALRUS_ARCH} STREQUAL "aarch64" OR (${WALRUS_ARCH} STREQUAL "arm64")) + ELSEIF (WALRUS_ARCH STREQUAL "aarch64" OR (WALRUS_ARCH STREQUAL "arm64")) SET (WALRUS_BUILD_64BIT ON) ELSE() MESSAGE (FATAL_ERROR ${WALRUS_ARCH} " is unsupported") diff --git a/build/walrus.cmake b/build/walrus.cmake index 757b7b095..0458275d9 100644 --- a/build/walrus.cmake +++ b/build/walrus.cmake @@ -5,24 +5,28 @@ SET (WALRUS_INCDIRS ${GCUTIL_ROOT}/include/ ) -IF (${WALRUS_MODE} STREQUAL "debug") - SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS_DEBUG} ${WALRUS_CXXFLAGS}) - SET (WALRUS_LDFLAGS ${WALRUS_LDFLAGS_DEBUG} ${WALRUS_LDFLAGS}) - SET (WALRUS_DEFINITIONS ${WALRUS_DEFINITIONS} ${WALRUS_DEFINITIONS_DEBUG}) -ELSEIF (${WALRUS_MODE} STREQUAL "release") - SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS_RELEASE} ${WALRUS_CXXFLAGS}) - SET (WALRUS_LDFLAGS ${WALRUS_LDFLAGS_RELEASE} ${WALRUS_LDFLAGS}) - SET (WALRUS_DEFINITIONS ${WALRUS_DEFINITIONS} ${WALRUS_DEFINITIONS_RELEASE}) +# Select configuration flags at build time for single- and multi-config generators. +IF (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR COMPILER_CLANG_CL) + STRING (REPLACE "/O2" "/O1" WALRUS_CXXFLAGS_MINSIZEREL "${WALRUS_CXXFLAGS_RELEASE}") +ELSE() + STRING (REPLACE "-O2" "-Os" WALRUS_CXXFLAGS_MINSIZEREL "${WALRUS_CXXFLAGS_RELEASE}") ENDIF() - -IF (${WALRUS_OUTPUT} STREQUAL "shared_lib") +SET (WALRUS_CONFIG_CXXFLAGS) +# One flag per expression keeps lists intact on CMake 2.8.12 as well. +FOREACH (_walrus_flag ${WALRUS_CXXFLAGS_DEBUG}) + LIST (APPEND WALRUS_CONFIG_CXXFLAGS "$<$:${_walrus_flag}>") +ENDFOREACH() +FOREACH (_walrus_flag ${WALRUS_CXXFLAGS_MINSIZEREL}) + LIST (APPEND WALRUS_CONFIG_CXXFLAGS "$<$:${_walrus_flag}>") +ENDFOREACH() +FOREACH (_walrus_flag ${WALRUS_CXXFLAGS_RELEASE}) + LIST (APPEND WALRUS_CONFIG_CXXFLAGS "$<$>,$>>:${_walrus_flag}>") +ENDFOREACH() +IF (WALRUS_BUILD_SHARED_LIBS) SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS} ${WALRUS_CXXFLAGS_SHAREDLIB}) SET (WALRUS_LDFLAGS ${WALRUS_LDFLAGS} ${WALRUS_LDFLAGS_SHAREDLIB}) - SET (WALRUS_DEFINITIONS ${WALRUS_DEFINITIONS} ${WALRUS_DEFINITIONS_SHAREDLIB}) -ELSEIF (${WALRUS_OUTPUT} STREQUAL "static_lib" OR ${WALRUS_OUTPUT} STREQUAL "shell") +ELSE() SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS} ${WALRUS_CXXFLAGS_STATICLIB}) - SET (WALRUS_LDFLAGS ${WALRUS_LDFLAGS} ${WALRUS_LDFLAGS_STATICLIB}) - SET (WALRUS_DEFINITIONS ${WALRUS_DEFINITIONS} ${WALRUS_DEFINITIONS_STATICLIB}) ENDIF() IF (WALRUS_ASAN) @@ -51,11 +55,9 @@ SET (WALRUS_SRC_LIST ${WALRUS_SRC} ) -IF (${WALRUS_OUTPUT} STREQUAL "shared_lib") - SET (WALRUS_THIRDPARTY_CFLAGS ${WALRUS_THIRDPARTY_CFLAGS} ${WALRUS_CXXFLAGS_SHAREDLIB}) -ELSEIF (${WALRUS_OUTPUT} STREQUAL "static_lib") - SET (WALRUS_THIRDPARTY_CFLAGS ${WALRUS_THIRDPARTY_CFLAGS} ${WALRUS_CXXFLAGS_STATICLIB}) -ENDIF() +# Dependencies must be linkable into shared Walrus libraries too. +SET (CMAKE_POSITION_INDEPENDENT_CODE ON) +SET (WALRUS_THIRDPARTY_CFLAGS ${WALRUS_THIRDPARTY_CFLAGS} ${WALRUS_CXXFLAGS_SHAREDLIB}) IF (WALRUS_GC) # GCUTIL @@ -63,31 +65,27 @@ IF (WALRUS_GC) IF (WALRUS_SMALL_CONFIG) SET (GCUTIL_CFLAGS ${GCUTIL_CFLAGS} -DSMALL_CONFIG -DMAX_HEAP_SECTS=512) ENDIF() - SET (GCUTIL_MODE ${WALRUS_MODE}) - ADD_SUBDIRECTORY (third_party/GCutil) + SET (GCUTIL_BUILD_SHARED_LIBS ${WALRUS_BUILD_GC_SHARED_LIBS}) + ADD_SUBDIRECTORY (${WALRUS_ROOT}/third_party/GCutil ${CMAKE_CURRENT_BINARY_DIR}/third_party/GCutil) SET (WALRUS_LIBRARIES ${WALRUS_LIBRARIES} gc-lib) SET (WALRUS_DEFINITIONS ${WALRUS_DEFINITIONS} -DENABLE_GC) ENDIF() # wabt SET (WABT_ARCH ${WALRUS_ARCH}) -IF (${WALRUS_MODE} STREQUAL "debug") - SET (WABT_CXX_FLAGS ${WALRUS_THIRDPARTY_CFLAGS} ${WALRUS_CXXFLAGS_DEBUG}) -ELSEIF (${WALRUS_MODE} STREQUAL "release") - SET (WABT_CXX_FLAGS ${WALRUS_THIRDPARTY_CFLAGS} ${WALRUS_CXXFLAGS_RELEASE}) -ENDIF() +SET (WABT_CXX_FLAGS ${WALRUS_THIRDPARTY_CFLAGS} ${WALRUS_CONFIG_CXXFLAGS}) SET (WABT_DEFINITIONS ${WALRUS_DEFINITIONS}) SET (WITH_EXCEPTIONS TRUE) -ADD_SUBDIRECTORY (third_party/wabt) +ADD_SUBDIRECTORY (${WALRUS_ROOT}/third_party/wabt ${CMAKE_CURRENT_BINARY_DIR}/third_party/wabt) SET (WALRUS_LIBRARIES ${WALRUS_LIBRARIES} wabt) IF (WALRUS_WASI) # uvwasi and nntrainer - IF (${WALRUS_ARCH} STREQUAL "x86") + IF (WALRUS_ARCH STREQUAL "x86") SET (UVWASI_BUILD_X86 ON) ENDIF() - ADD_SUBDIRECTORY (third_party/uvwasi) + ADD_SUBDIRECTORY (${WALRUS_ROOT}/third_party/uvwasi ${CMAKE_CURRENT_BINARY_DIR}/third_party/uvwasi) LIST (APPEND WALRUS_INCDIRS ${WALRUS_THIRD_PARTY_ROOT}/uvwasi/uvwasi/src) SET (WALRUS_DEFINITIONS ${WALRUS_DEFINITIONS} -DENABLE_WASI) SET (WALRUS_LIBRARIES ${WALRUS_LIBRARIES} uvwasi_a) @@ -107,44 +105,49 @@ ENDIF() # BUILD INCLUDE_DIRECTORIES (${WALRUS_INCDIRS}) - -IF (${WALRUS_OUTPUT} MATCHES "_lib") - # walrus library using wasm-c-api - IF (${WALRUS_OUTPUT} STREQUAL "static_lib") - ADD_LIBRARY (${WALRUS_TARGET} STATIC ${WALRUS_SRC_LIST} ${WALRUS_ROOT}/src/api/wasm.cpp) - ELSE () - ADD_LIBRARY (${WALRUS_TARGET} SHARED ${WALRUS_SRC_LIST} ${WALRUS_ROOT}/src/api/wasm.cpp) +IF (WALRUS_BUILD_SHARED_LIBS) + ADD_LIBRARY (${WALRUS_TARGET} SHARED ${WALRUS_SRC_LIST} ${WALRUS_ROOT}/src/api/wasm.cpp) +ELSE() + ADD_LIBRARY (${WALRUS_TARGET} STATIC ${WALRUS_SRC_LIST} ${WALRUS_ROOT}/src/api/wasm.cpp) +ENDIF() +TARGET_LINK_LIBRARIES (${WALRUS_TARGET} PRIVATE ${WALRUS_LIBRARIES} ${WALRUS_LDFLAGS} ${LDFLAGS_FROM_ENV}) +IF (WALRUS_BUILD_SHARED_LIBS AND WALRUS_HOST STREQUAL "android") + TARGET_LINK_LIBRARIES (${WALRUS_TARGET} PRIVATE -shared) +ENDIF() +TARGET_INCLUDE_DIRECTORIES (${WALRUS_TARGET} PUBLIC ${WALRUS_ROOT}/src/api/) +TARGET_COMPILE_DEFINITIONS (${WALRUS_TARGET} PRIVATE ${WALRUS_DEFINITIONS}) +TARGET_COMPILE_OPTIONS (${WALRUS_TARGET} PRIVATE ${WALRUS_CONFIG_CXXFLAGS} ${WALRUS_CXXFLAGS} ${CXXFLAGS_FROM_ENV}) + +IF (WALRUS_ENABLE_SHELL) + # The shell uses internal C++ APIs, which the wasm-c-api shared library + # deliberately hides. Reuse the core sources for a shared-library build. + IF (WALRUS_BUILD_SHARED_LIBS) + ADD_EXECUTABLE (walrus_shell ${WALRUS_SRC_LIST} ${WALRUS_ROOT}/src/shell/Shell.cpp) + TARGET_LINK_LIBRARIES (walrus_shell PRIVATE ${WALRUS_LIBRARIES} ${WALRUS_LDFLAGS} ${LDFLAGS_FROM_ENV}) + ELSE() + ADD_EXECUTABLE (walrus_shell ${WALRUS_ROOT}/src/shell/Shell.cpp) + TARGET_LINK_LIBRARIES (walrus_shell PRIVATE ${WALRUS_TARGET}) ENDIF() - - TARGET_LINK_LIBRARIES (${WALRUS_TARGET} PRIVATE ${WALRUS_LIBRARIES} ${WALRUS_LDFLAGS} ${LDFLAGS_FROM_ENV}) - TARGET_INCLUDE_DIRECTORIES (${WALRUS_TARGET} PUBLIC ${WALRUS_ROOT}/src/api/) - TARGET_COMPILE_DEFINITIONS (${WALRUS_TARGET} PRIVATE ${WALRUS_DEFINITIONS}) - TARGET_COMPILE_OPTIONS (${WALRUS_TARGET} PRIVATE ${WALRUS_CXXFLAGS} ${CXXFLAGS_FROM_ENV}) -ELSEIF (${WALRUS_OUTPUT} MATCHES "shell") - ADD_EXECUTABLE (${WALRUS_TARGET} ${WALRUS_SRC_LIST} ${WALRUS_ROOT}/src/shell/Shell.cpp) - - TARGET_LINK_LIBRARIES (${WALRUS_TARGET} PRIVATE ${WALRUS_LIBRARIES} ${WALRUS_LDFLAGS} ${LDFLAGS_FROM_ENV}) - IF(WALRUS_WASI_NN) - IF(WASI_NN_BACKEND STREQUAL "nntrainer") - TARGET_INCLUDE_DIRECTORIES(${WALRUS_TARGET} PRIVATE ${nntrainer_SOURCE_DIR}/api/) - TARGET_INCLUDE_DIRECTORIES(${WALRUS_TARGET} PRIVATE ${nntrainer_SOURCE_DIR}/api/ccapi/include/) - - TARGET_LINK_LIBRARIES(${WALRUS_TARGET} PRIVATE ${WALRUS_THIRD_PARTY_ROOT}/nntrainer/libnntrainer.so ) - TARGET_LINK_LIBRARIES(${WALRUS_TARGET} PRIVATE ${WALRUS_THIRD_PARTY_ROOT}/nntrainer/libccapi-nntrainer.so ) - ENDIF() + SET_TARGET_PROPERTIES (walrus_shell PROPERTIES OUTPUT_NAME walrus) + # Avoid colliding with walrus.lib (the DLL import library) on Windows. + IF (WIN32) + SET_TARGET_PROPERTIES (walrus_shell PROPERTIES ARCHIVE_OUTPUT_NAME walrus_shell) ENDIF() + TARGET_LINK_LIBRARIES (walrus_shell PRIVATE ${WALRUS_LIBRARIES}) + IF (WALRUS_SHELL_LDFLAGS) + # Slash-prefixed MSVC options are treated as paths by TARGET_LINK_LIBRARIES. + SET_PROPERTY (TARGET walrus_shell APPEND_STRING PROPERTY LINK_FLAGS " ${WALRUS_SHELL_LDFLAGS}") + ENDIF() + TARGET_INCLUDE_DIRECTORIES (walrus_shell PRIVATE ${WALRUS_ROOT}/third_party/wabt/include ${CMAKE_CURRENT_BINARY_DIR}/third_party/wabt/include) + TARGET_COMPILE_DEFINITIONS (walrus_shell PRIVATE ${WALRUS_DEFINITIONS}) + TARGET_COMPILE_OPTIONS (walrus_shell PRIVATE ${WALRUS_CONFIG_CXXFLAGS} ${WALRUS_CXXFLAGS} ${WALRUS_CXXFLAGS_SHELL} ${CXXFLAGS_FROM_ENV} ${PROFILER_FLAGS}) + IF (WALRUS_WASI_NN AND WASI_NN_BACKEND STREQUAL "nntrainer") + TARGET_INCLUDE_DIRECTORIES (walrus_shell PRIVATE ${nntrainer_SOURCE_DIR}/api/ ${nntrainer_SOURCE_DIR}/api/ccapi/include/) + TARGET_LINK_LIBRARIES (walrus_shell PRIVATE ${WALRUS_THIRD_PARTY_ROOT}/nntrainer/libnntrainer.so ${WALRUS_THIRD_PARTY_ROOT}/nntrainer/libccapi-nntrainer.so) + ENDIF() +ENDIF() - TARGET_COMPILE_DEFINITIONS (${WALRUS_TARGET} PRIVATE ${WALRUS_DEFINITIONS}) - TARGET_COMPILE_OPTIONS (${WALRUS_TARGET} PRIVATE ${WALRUS_CXXFLAGS} ${WALRUS_CXXFLAGS_SHELL} ${CXXFLAGS_FROM_ENV} ${PROFILER_FLAGS}) -ELSEIF (${WALRUS_OUTPUT} STREQUAL "api_test") - # BUILD WASM API TESTS - ADD_LIBRARY (${WALRUS_TARGET} STATIC ${WALRUS_SRC_LIST} ${WALRUS_ROOT}/src/api/wasm.cpp) - - TARGET_LINK_LIBRARIES (${WALRUS_TARGET} PRIVATE ${WALRUS_LIBRARIES} ${WALRUS_LDFLAGS} ${LDFLAGS_FROM_ENV}) - TARGET_INCLUDE_DIRECTORIES (${WALRUS_TARGET} PUBLIC ${WALRUS_ROOT}/src/api/) - TARGET_COMPILE_DEFINITIONS (${WALRUS_TARGET} PRIVATE ${WALRUS_DEFINITIONS}) - TARGET_COMPILE_OPTIONS (${WALRUS_TARGET} PRIVATE ${WALRUS_CXXFLAGS} ${CXXFLAGS_FROM_ENV}) - +IF (WALRUS_BUILD_API_TESTS) function(c_api_example NAME) set(EXENAME wasm-c-api-${NAME}) add_executable(${EXENAME} ${WALRUS_THIRD_PARTY_ROOT}/wasm-c-api/example/${NAME}.c) diff --git a/third_party/GCutil b/third_party/GCutil index 2df725649..11759e9fc 160000 --- a/third_party/GCutil +++ b/third_party/GCutil @@ -1 +1 @@ -Subproject commit 2df725649843dc50f9855a0afe6bc81f9ef7f7a4 +Subproject commit 11759e9fccdb8798d40583008e876c3c37bfe2e5 diff --git a/third_party/uvwasi/CMakeLists.txt b/third_party/uvwasi/CMakeLists.txt index cc979d17e..a76134ee7 100644 --- a/third_party/uvwasi/CMakeLists.txt +++ b/third_party/uvwasi/CMakeLists.txt @@ -1,10 +1,5 @@ -cmake_minimum_required(VERSION 3.14) -project ( - uvwasi - DESCRIPTION "WASI syscall API built atop libuv" - VERSION 0.0.21 - LANGUAGES C -) +cmake_minimum_required(VERSION 2.8.12...4.0) +project(uvwasi C) set(UVWASI_DIR ${PROJECT_SOURCE_DIR}/uvwasi) @@ -19,8 +14,6 @@ cmake_dependent_option(UVWASI_BUILD_TESTS "Build the unit tests when uvwasi is the root project" ON "CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/out) - if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU") list(APPEND uvwasi_cflags -fvisibility=hidden --std=gnu89) @@ -30,7 +23,7 @@ if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU") if (UVWASI_BUILD_X86) # set x86 build flag add_compile_options( -m32 ) - add_link_options( -m32 ) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") endif() endif() @@ -42,34 +35,34 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") list(APPEND uvwasi_defines _GNU_SOURCE _POSIX_C_SOURCE=200112) endif() -if (WALRUS_MODE STREQUAL "debug") - list(APPEND uvwasi_cflags -O0 -g) +if (CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU") + list(APPEND uvwasi_cflags "$<$:-O0>" "$<$:-g>") if (UVWASI_DEBUG_LOG) list(APPEND uvwasi_defines UVWASI_DEBUG_LOG) endif () endif () -#find_package(LIBUV QUIET) -#if(LIBUV_FOUND) -# include_directories(${LIBUV_INCLUDE_DIR}) -#else() +# Old CMake can use a system libuv; newer CMake can fetch the pinned version. +find_package(PkgConfig QUIET) +if (PKG_CONFIG_FOUND) + pkg_check_modules(LIBUV QUIET libuv>=1.34) +endif () +if (LIBUV_FOUND) + link_directories(${LIBUV_LIBRARY_DIRS}) + list(APPEND uvwasi_cflags ${LIBUV_CFLAGS_OTHER}) +else () + if (CMAKE_VERSION VERSION_LESS 3.14) + message(FATAL_ERROR "WASI on CMake older than 3.14 requires system libuv (pkg-config libuv), or WALRUS_WASI=OFF") + endif () include(FetchContent) - ## https://libuv.org - FetchContent_Declare( - libuv - GIT_REPOSITORY https://github.com/libuv/libuv.git - GIT_TAG ${LIBUV_VERSION}) - - FetchContent_GetProperties(libuv) + FetchContent_Declare(libuv + GIT_REPOSITORY https://github.com/libuv/libuv.git + GIT_TAG ${LIBUV_VERSION}) FetchContent_MakeAvailable(libuv) - if(NOT libuv_POPULATED) - include_directories("${libuv_SOURCE_DIR}/include") - add_subdirectory(${libuv_SOURCE_DIR} ${libuv_BINARY_DIR} EXCLUDE_FROM_ALL) - endif() - set(LIBUV_INCLUDE_DIR ${libuv_SOURCE_DIR}/include) + set(LIBUV_INCLUDE_DIRS ${libuv_SOURCE_DIR}/include) set(LIBUV_LIBRARIES uv_a) -#endif() +endif () ## uvwasi source code files. set(uvwasi_sources @@ -95,7 +88,7 @@ endif() add_library(uvwasi_a STATIC ${uvwasi_sources}) target_compile_definitions(uvwasi_a PRIVATE ${uvwasi_defines}) target_compile_options(uvwasi_a PRIVATE ${uvwasi_cflags}) -target_include_directories(uvwasi_a PUBLIC ${UVWASI_DIR}/include ${LIBUV_INCLUDE_DIR}) +target_include_directories(uvwasi_a PUBLIC ${UVWASI_DIR}/include ${LIBUV_INCLUDE_DIRS}) target_link_libraries(uvwasi_a PRIVATE ${LIBUV_LIBRARIES}) message(STATUS "summary of uvwasi build options: @@ -107,7 +100,7 @@ message(STATUS "summary of uvwasi build options: CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS} LibUV libraries: ${LIBUV_LIBRARIES} - LibUV includes: ${LIBUV_INCLUDE_DIR} + LibUV includes: ${LIBUV_INCLUDE_DIRS} Debug logging: ${UVWASI_DEBUG_LOG} Code coverage: ${CODE_COVERAGE} ASAN: ${ASAN} diff --git a/third_party/wabt/CMakeLists.txt b/third_party/wabt/CMakeLists.txt index af2c0636c..a6ce1abf6 100644 --- a/third_party/wabt/CMakeLists.txt +++ b/third_party/wabt/CMakeLists.txt @@ -14,12 +14,16 @@ # limitations under the License. # -cmake_minimum_required(VERSION 3.5.0) -project(WABT LANGUAGES C CXX VERSION 1.0.30) +cmake_minimum_required(VERSION 2.8.12...4.0) +project(WABT C CXX) +set(PROJECT_VERSION 1.0.30) include(GNUInstallDirs) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) +if (CMAKE_VERSION VERSION_LESS 3.1 AND NOT MSVC) + add_compile_options(-std=c++11) +endif () set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -220,9 +224,6 @@ endif() add_compile_options(${WABT_CXX_FLAGS_INTERNAL}) add_compile_options(${WABT_CXX_FLAGS}) -set(WABT_CXXFLAGS_FROM_ENV $ENV{CXXFLAGS}) -separate_arguments(WABT_CXXFLAGS_FROM_ENV) -add_compile_options(${WABT_CXXFLAGS_FROM_ENV}) add_library(wabt STATIC ${WABT_LIBRARY_SRC}) target_include_directories(wabt PUBLIC ${PROJECT_SOURCE_DIR}/include "$") From a55356f14a7baea9c648ca25c9e6798d1103a700 Mon Sep 17 00:00:00 2001 From: Seonghyun Kim Date: Tue, 6 Oct 2026 14:09:00 +0900 Subject: [PATCH 2/2] Scope CMake settings to individual targets Keep compiler flags, definitions, include paths and PIC settings on their owning targets. Pass sanitizer runtime requirements through dependency links and resolve libuv libraries without changing directory search paths. Namespace dependency options and cached probes, preserve parent CMake settings, and add isolation regression checks to CI. Signed-off-by: Seonghyun Kim --- .github/workflows/actions.yml | 15 ++ CMakeLists.txt | 16 +- README.md | 16 ++ build/config.cmake | 12 +- build/target.cmake | 8 +- build/walrus.cmake | 76 +++++---- test/cmake/isolation/CMakeLists.txt | 76 +++++++++ test/cmake/isolation/sentinel.c | 10 ++ test/cmake/isolation/sentinel.cpp | 10 ++ third_party/uvwasi/CMakeLists.txt | 86 ++++++---- third_party/wabt/CMakeLists.txt | 254 +++++++++++++++------------- 11 files changed, 384 insertions(+), 195 deletions(-) create mode 100644 test/cmake/isolation/CMakeLists.txt create mode 100644 test/cmake/isolation/sentinel.c create mode 100644 test/cmake/isolation/sentinel.cpp diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 5aa28ae58..96e133497 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -10,6 +10,21 @@ env: RUNNER: tools/run-tests.py jobs: + check-cmake-isolation: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install Packages + run: sudo apt-get update && sudo apt-get install -y ninja-build pkg-config libuv1-dev + - name: Check parent and target isolation + run: | + cmake -Htest/cmake/isolation -Bout/cmake-isolation -GNinja + cmake --build out/cmake-isolation --target walrus-isolation + cmake -Htest/cmake/isolation -Bout/cmake-isolation-asan -GNinja -DWABT_USE_ASAN=ON -DUVWASI_ASAN=ON + cmake --build out/cmake-isolation-asan --target walrus-isolation + check-tidy: runs-on: ubuntu-latest steps: diff --git a/CMakeLists.txt b/CMakeLists.txt index 15bcfb554..cdd0128ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,9 @@ CMAKE_MINIMUM_REQUIRED (VERSION 2.8.12...4.0 FATAL_ERROR) PROJECT (WALRUS) # CONFIGURATION -SET (CMAKE_EXPORT_COMPILE_COMMANDS ON) +IF (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND NOT DEFINED CMAKE_EXPORT_COMPILE_COMMANDS) + SET (CMAKE_EXPORT_COMPILE_COMMANDS ON) +ENDIF() # Honor standard CMake configuration variables. Legacy inputs remain aliases. IF (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) @@ -19,8 +21,13 @@ IF (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) ELSE() SET (_walrus_build_type Release) ENDIF() - SET (CMAKE_BUILD_TYPE "${_walrus_build_type}" CACHE STRING "Build configuration" FORCE) - SET_PROPERTY (CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release RelWithDebInfo MinSizeRel) + IF (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + SET (CMAKE_BUILD_TYPE "${_walrus_build_type}" CACHE STRING "Build configuration" FORCE) + SET_PROPERTY (CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release RelWithDebInfo MinSizeRel) + ELSE() + # A subproject must not change its parent's configuration cache. + SET (CMAKE_BUILD_TYPE "${_walrus_build_type}") + ENDIF() ENDIF() STRING (TOLOWER "${CMAKE_BUILD_TYPE}" _walrus_build_type_lower) IF (_walrus_build_type_lower STREQUAL "debug") @@ -149,9 +156,6 @@ ENDIF() SET (WALRUS_TARGET walrus) -INCLUDE (ProcessorCount) -PROCESSORCOUNT (NPROCS) - # INCLUDE CMAKE FILES INCLUDE (${CMAKE_CURRENT_SOURCE_DIR}/build/config.cmake) INCLUDE (${CMAKE_CURRENT_SOURCE_DIR}/build/walrus.cmake) diff --git a/README.md b/README.md index d26ea9706..2121113bd 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,22 @@ Legacy `WALRUS_MODE=debug/release` supplies the default build type when supplies defaults for the independent output options; explicit new options take precedence. Walrus does not overwrite the parent's `BUILD_SHARED_LIBS` or `ENABLE_SHELL`. +Build flags, definitions, include paths and PIC settings are applied to individual +targets. Embedding Walrus does not change parent or unrelated target settings. +WABT options use the `WABT_` prefix (for example `WABT_USE_ASAN` and +`WABT_WERROR`), and WASI uses `UVWASI_ASAN`. Legacy unprefixed options are +read as defaults without creating unprefixed cache entries. + +To check build-setting isolation, configure and build the standalone fixture: + +```console +$ cmake -Htest/cmake/isolation -Bout/cmake-isolation -GNinja +$ cmake --build out/cmake-isolation --target walrus-isolation +``` + +The same fixture supports `-DWABT_USE_ASAN=ON -DUVWASI_ASAN=ON` to check +that sanitizer settings stay on their owning targets. + ## Perf You'll need [Perf](https://perf.wiki.kernel.org/index.php/Main_Page). diff --git a/build/config.cmake b/build/config.cmake index 831f9a08c..aa7625163 100644 --- a/build/config.cmake +++ b/build/config.cmake @@ -7,8 +7,8 @@ ####################################################### SET (WALRUS_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) SET (WALRUS_THIRD_PARTY_ROOT ${WALRUS_ROOT}/third_party) -SET (SLJIT_ROOT ${WALRUS_THIRD_PARTY_ROOT}/sljit) -SET (GCUTIL_ROOT ${WALRUS_THIRD_PARTY_ROOT}/GCutil) +SET (WALRUS_SLJIT_ROOT ${WALRUS_THIRD_PARTY_ROOT}/sljit) +SET (WALRUS_GCUTIL_ROOT ${WALRUS_THIRD_PARTY_ROOT}/GCutil) ####################################################### # FLAGS FOR TARGET @@ -27,8 +27,8 @@ SET (WALRUS_DEFINITIONS # CMake already consumes CXXFLAGS and LDFLAGS when initializing its cache. # Keep only the legacy explicit flag lists here to avoid applying environment # flags twice or overriding configuration-specific optimization flags. -SET (CXXFLAGS_FROM_ENV ${WALRUS_CXXFLAGS_FROM_EXTERNAL}) -SET (LDFLAGS_FROM_ENV ${WALRUS_LDFLAGS_FROM_EXTERNAL}) +SET (WALRUS_EXTERNAL_CXXFLAGS ${WALRUS_CXXFLAGS_FROM_EXTERNAL}) +SET (WALRUS_EXTERNAL_LDFLAGS ${WALRUS_LDFLAGS_FROM_EXTERNAL}) ####################################################### # FLAGS FOR ADDITIONAL FUNCTION @@ -48,8 +48,8 @@ SET (WALRUS_DEFINITIONS_TEST -DWALRUS_ENABLE_TEST) ####################################################### # FLAGS FOR MEMORY PROFILING ####################################################### -SET (PROFILER_FLAGS) +SET (WALRUS_PROFILER_FLAGS) IF (WALRUS_VALGRIND) - SET (PROFILER_FLAGS ${PROFILER_FLAGS} -DWALRUS_VALGRIND) + SET (WALRUS_PROFILER_FLAGS ${WALRUS_PROFILER_FLAGS} -DWALRUS_VALGRIND) ENDIF() diff --git a/build/target.cmake b/build/target.cmake index faac0fbc4..504bd6413 100644 --- a/build/target.cmake +++ b/build/target.cmake @@ -14,21 +14,21 @@ SET (WALRUS_BUILD_32BIT OFF) SET (WALRUS_BUILD_64BIT OFF) # clang-cl defines ${CMAKE_CXX_COMPILER_ID} "Clang" and ${CMAKE_CXX_COMPILER_FRONTEND_VARIANT} "MSVC" -SET (COMPILER_CLANG_CL OFF) +SET (WALRUS_COMPILER_CLANG_CL OFF) IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") IF (DEFINED CMAKE_CXX_COMPILER_FRONTEND_VARIANT) IF (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") - SET (COMPILER_CLANG_CL ON) + SET (WALRUS_COMPILER_CLANG_CL ON) ENDIF() ENDIF() ENDIF() # Default options per compiler -IF (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR COMPILER_CLANG_CL) +IF (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR WALRUS_COMPILER_CLANG_CL) SET (WALRUS_CXXFLAGS /std:c++14 /fp:strict /Zc:__cplusplus /EHs /source-charset:utf-8 /D_CRT_SECURE_NO_WARNINGS /DGC_NOT_DLL /D_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING /wd4244 /wd4267 /wd4805 /wd4018 /wd4172) SET (WALRUS_CXXFLAGS_RELEASE /O2 /Oy-) SET (WALRUS_THIRDPARTY_CFLAGS /D_CRT_SECURE_NO_WARNINGS /DGC_NOT_DLL /Oy- /wd4146 /EHs) - IF (COMPILER_CLANG_CL) + IF (WALRUS_COMPILER_CLANG_CL) SET (WALRUS_CXXFLAGS ${WALRUS_CXXFLAGS} /EHs -Wno-invalid-offsetof -Wno-inline-new-delete -fintegrated-cc1) ENDIF() diff --git a/build/walrus.cmake b/build/walrus.cmake index 0458275d9..e5a58bd76 100644 --- a/build/walrus.cmake +++ b/build/walrus.cmake @@ -1,12 +1,12 @@ SET (WALRUS_INCDIRS ${WALRUS_INCDIRS} ${WALRUS_ROOT}/src/ - ${SLJIT_ROOT}/sljit_src/ - ${GCUTIL_ROOT}/include/ + ${WALRUS_SLJIT_ROOT}/sljit_src/ + ${WALRUS_GCUTIL_ROOT}/include/ ) # Select configuration flags at build time for single- and multi-config generators. -IF (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR COMPILER_CLANG_CL) +IF (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR WALRUS_COMPILER_CLANG_CL) STRING (REPLACE "/O2" "/O1" WALRUS_CXXFLAGS_MINSIZEREL "${WALRUS_CXXFLAGS_RELEASE}") ELSE() STRING (REPLACE "-O2" "-Os" WALRUS_CXXFLAGS_MINSIZEREL "${WALRUS_CXXFLAGS_RELEASE}") @@ -56,28 +56,32 @@ SET (WALRUS_SRC_LIST ) # Dependencies must be linkable into shared Walrus libraries too. -SET (CMAKE_POSITION_INDEPENDENT_CODE ON) SET (WALRUS_THIRDPARTY_CFLAGS ${WALRUS_THIRDPARTY_CFLAGS} ${WALRUS_CXXFLAGS_SHAREDLIB}) -IF (WALRUS_GC) - # GCUTIL +FUNCTION (WALRUS_ADD_GCUTIL) SET (GCUTIL_CFLAGS ${WALRUS_THIRDPARTY_CFLAGS}) IF (WALRUS_SMALL_CONFIG) SET (GCUTIL_CFLAGS ${GCUTIL_CFLAGS} -DSMALL_CONFIG -DMAX_HEAP_SECTS=512) ENDIF() SET (GCUTIL_BUILD_SHARED_LIBS ${WALRUS_BUILD_GC_SHARED_LIBS}) + SET (COMPILER_CLANG_CL ${WALRUS_COMPILER_CLANG_CL}) ADD_SUBDIRECTORY (${WALRUS_ROOT}/third_party/GCutil ${CMAKE_CURRENT_BINARY_DIR}/third_party/GCutil) - SET (WALRUS_LIBRARIES ${WALRUS_LIBRARIES} gc-lib) - SET (WALRUS_DEFINITIONS ${WALRUS_DEFINITIONS} -DENABLE_GC) +ENDFUNCTION() +IF (WALRUS_GC) + WALRUS_ADD_GCUTIL() + LIST (APPEND WALRUS_LIBRARIES gc-lib) + LIST (APPEND WALRUS_DEFINITIONS -DENABLE_GC) ENDIF() # wabt -SET (WABT_ARCH ${WALRUS_ARCH}) -SET (WABT_CXX_FLAGS ${WALRUS_THIRDPARTY_CFLAGS} ${WALRUS_CONFIG_CXXFLAGS}) - -SET (WABT_DEFINITIONS ${WALRUS_DEFINITIONS}) -SET (WITH_EXCEPTIONS TRUE) -ADD_SUBDIRECTORY (${WALRUS_ROOT}/third_party/wabt ${CMAKE_CURRENT_BINARY_DIR}/third_party/wabt) +FUNCTION (WALRUS_ADD_WABT) + SET (WABT_ARCH ${WALRUS_ARCH}) + SET (WABT_CXX_FLAGS ${WALRUS_THIRDPARTY_CFLAGS} ${WALRUS_CONFIG_CXXFLAGS}) + SET (WABT_DEFINITIONS ${WALRUS_DEFINITIONS}) + SET (WABT_WITH_EXCEPTIONS ON) + ADD_SUBDIRECTORY (${WALRUS_ROOT}/third_party/wabt ${CMAKE_CURRENT_BINARY_DIR}/third_party/wabt) +ENDFUNCTION() +WALRUS_ADD_WABT() SET (WALRUS_LIBRARIES ${WALRUS_LIBRARIES} wabt) IF (WALRUS_WASI) @@ -104,26 +108,26 @@ IF (WALRUS_WASI) ENDIF() # BUILD -INCLUDE_DIRECTORIES (${WALRUS_INCDIRS}) IF (WALRUS_BUILD_SHARED_LIBS) ADD_LIBRARY (${WALRUS_TARGET} SHARED ${WALRUS_SRC_LIST} ${WALRUS_ROOT}/src/api/wasm.cpp) ELSE() ADD_LIBRARY (${WALRUS_TARGET} STATIC ${WALRUS_SRC_LIST} ${WALRUS_ROOT}/src/api/wasm.cpp) ENDIF() -TARGET_LINK_LIBRARIES (${WALRUS_TARGET} PRIVATE ${WALRUS_LIBRARIES} ${WALRUS_LDFLAGS} ${LDFLAGS_FROM_ENV}) +TARGET_LINK_LIBRARIES (${WALRUS_TARGET} PRIVATE ${WALRUS_LIBRARIES} ${WALRUS_LDFLAGS} ${WALRUS_EXTERNAL_LDFLAGS}) IF (WALRUS_BUILD_SHARED_LIBS AND WALRUS_HOST STREQUAL "android") TARGET_LINK_LIBRARIES (${WALRUS_TARGET} PRIVATE -shared) ENDIF() -TARGET_INCLUDE_DIRECTORIES (${WALRUS_TARGET} PUBLIC ${WALRUS_ROOT}/src/api/) +SET_TARGET_PROPERTIES (${WALRUS_TARGET} PROPERTIES POSITION_INDEPENDENT_CODE ON) +TARGET_INCLUDE_DIRECTORIES (${WALRUS_TARGET} PRIVATE ${WALRUS_INCDIRS} PUBLIC ${WALRUS_ROOT}/src/api/) TARGET_COMPILE_DEFINITIONS (${WALRUS_TARGET} PRIVATE ${WALRUS_DEFINITIONS}) -TARGET_COMPILE_OPTIONS (${WALRUS_TARGET} PRIVATE ${WALRUS_CONFIG_CXXFLAGS} ${WALRUS_CXXFLAGS} ${CXXFLAGS_FROM_ENV}) +TARGET_COMPILE_OPTIONS (${WALRUS_TARGET} PRIVATE ${WALRUS_CONFIG_CXXFLAGS} ${WALRUS_CXXFLAGS} ${WALRUS_EXTERNAL_CXXFLAGS}) IF (WALRUS_ENABLE_SHELL) # The shell uses internal C++ APIs, which the wasm-c-api shared library # deliberately hides. Reuse the core sources for a shared-library build. IF (WALRUS_BUILD_SHARED_LIBS) ADD_EXECUTABLE (walrus_shell ${WALRUS_SRC_LIST} ${WALRUS_ROOT}/src/shell/Shell.cpp) - TARGET_LINK_LIBRARIES (walrus_shell PRIVATE ${WALRUS_LIBRARIES} ${WALRUS_LDFLAGS} ${LDFLAGS_FROM_ENV}) + TARGET_LINK_LIBRARIES (walrus_shell PRIVATE ${WALRUS_LIBRARIES} ${WALRUS_LDFLAGS} ${WALRUS_EXTERNAL_LDFLAGS}) ELSE() ADD_EXECUTABLE (walrus_shell ${WALRUS_ROOT}/src/shell/Shell.cpp) TARGET_LINK_LIBRARIES (walrus_shell PRIVATE ${WALRUS_TARGET}) @@ -138,9 +142,9 @@ IF (WALRUS_ENABLE_SHELL) # Slash-prefixed MSVC options are treated as paths by TARGET_LINK_LIBRARIES. SET_PROPERTY (TARGET walrus_shell APPEND_STRING PROPERTY LINK_FLAGS " ${WALRUS_SHELL_LDFLAGS}") ENDIF() - TARGET_INCLUDE_DIRECTORIES (walrus_shell PRIVATE ${WALRUS_ROOT}/third_party/wabt/include ${CMAKE_CURRENT_BINARY_DIR}/third_party/wabt/include) + TARGET_INCLUDE_DIRECTORIES (walrus_shell PRIVATE ${WALRUS_INCDIRS} ${WALRUS_ROOT}/third_party/wabt/include ${CMAKE_CURRENT_BINARY_DIR}/third_party/wabt/include) TARGET_COMPILE_DEFINITIONS (walrus_shell PRIVATE ${WALRUS_DEFINITIONS}) - TARGET_COMPILE_OPTIONS (walrus_shell PRIVATE ${WALRUS_CONFIG_CXXFLAGS} ${WALRUS_CXXFLAGS} ${WALRUS_CXXFLAGS_SHELL} ${CXXFLAGS_FROM_ENV} ${PROFILER_FLAGS}) + TARGET_COMPILE_OPTIONS (walrus_shell PRIVATE ${WALRUS_CONFIG_CXXFLAGS} ${WALRUS_CXXFLAGS} ${WALRUS_CXXFLAGS_SHELL} ${WALRUS_EXTERNAL_CXXFLAGS} ${WALRUS_PROFILER_FLAGS}) IF (WALRUS_WASI_NN AND WASI_NN_BACKEND STREQUAL "nntrainer") TARGET_INCLUDE_DIRECTORIES (walrus_shell PRIVATE ${nntrainer_SOURCE_DIR}/api/ ${nntrainer_SOURCE_DIR}/api/ccapi/include/) TARGET_LINK_LIBRARIES (walrus_shell PRIVATE ${WALRUS_THIRD_PARTY_ROOT}/nntrainer/libnntrainer.so ${WALRUS_THIRD_PARTY_ROOT}/nntrainer/libccapi-nntrainer.so) @@ -148,10 +152,10 @@ IF (WALRUS_ENABLE_SHELL) ENDIF() IF (WALRUS_BUILD_API_TESTS) - function(c_api_example NAME) + function(WALRUS_C_API_EXAMPLE NAME) set(EXENAME wasm-c-api-${NAME}) add_executable(${EXENAME} ${WALRUS_THIRD_PARTY_ROOT}/wasm-c-api/example/${NAME}.c) - if (COMPILER_IS_MSVC) + if (CMAKE_C_COMPILER_ID STREQUAL "MSVC" OR WALRUS_COMPILER_CLANG_CL) set_target_properties(${EXENAME} PROPERTIES COMPILE_FLAGS "-wd4311") else () set_target_properties(${EXENAME} PROPERTIES COMPILE_FLAGS "-std=gnu11 -Wno-pointer-to-int-cast -g3") @@ -160,17 +164,17 @@ IF (WALRUS_BUILD_API_TESTS) target_link_libraries(${EXENAME} ${WALRUS_TARGET}) endfunction() - c_api_example(callback) -#c_api_example(finalize) - c_api_example(global) - c_api_example(hello) -#c_api_example(hostref) - c_api_example(multi) - c_api_example(memory) - c_api_example(reflect) -#c_api_example(serialize) -#c_api_example(start) - c_api_example(table) -#c_api_example(trap) -#c_api_example(threads) + WALRUS_C_API_EXAMPLE(callback) +#WALRUS_C_API_EXAMPLE(finalize) + WALRUS_C_API_EXAMPLE(global) + WALRUS_C_API_EXAMPLE(hello) +#WALRUS_C_API_EXAMPLE(hostref) + WALRUS_C_API_EXAMPLE(multi) + WALRUS_C_API_EXAMPLE(memory) + WALRUS_C_API_EXAMPLE(reflect) +#WALRUS_C_API_EXAMPLE(serialize) +#WALRUS_C_API_EXAMPLE(start) + WALRUS_C_API_EXAMPLE(table) +#WALRUS_C_API_EXAMPLE(trap) +#WALRUS_C_API_EXAMPLE(threads) ENDIF() diff --git a/test/cmake/isolation/CMakeLists.txt b/test/cmake/isolation/CMakeLists.txt new file mode 100644 index 000000000..bdc070c4d --- /dev/null +++ b/test/cmake/isolation/CMakeLists.txt @@ -0,0 +1,76 @@ +cmake_minimum_required(VERSION 2.8.12...4.0) +project(WalrusIsolation C CXX) + +get_filename_component(WALRUS_ISOLATION_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../.." ABSOLUTE) +# Parent settings deliberately differ from Walrus defaults. +set(CMAKE_EXPORT_COMPILE_COMMANDS OFF CACHE BOOL "Parent preference" FORCE) +set(CMAKE_POSITION_INDEPENDENT_CODE OFF) +set(CMAKE_CXX_STANDARD 17) +set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS -DPARENT_DIRECTORY_OPTION=1) +set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS PARENT_DIRECTORY_DEFINITION=1) +set_property(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPARENT_C_FLAG=1") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPARENT_CXX_FLAG=1") +set(WALRUS_ISOLATION_VARIABLES CMAKE_BUILD_TYPE CMAKE_C_FLAGS CMAKE_CXX_FLAGS + CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_MODULE_PATH + CMAKE_CXX_STANDARD CMAKE_CXX_STANDARD_REQUIRED CMAKE_CXX_EXTENSIONS + CMAKE_POSITION_INDEPENDENT_CODE CMAKE_EXPORT_COMPILE_COMMANDS) +foreach(NAME ${WALRUS_ISOLATION_VARIABLES}) + set(WALRUS_ISOLATION_BEFORE_${NAME} "${${NAME}}") +endforeach() +set(WALRUS_ISOLATION_PROPERTIES COMPILE_OPTIONS COMPILE_DEFINITIONS + INCLUDE_DIRECTORIES LINK_DIRECTORIES) +foreach(NAME ${WALRUS_ISOLATION_PROPERTIES}) + get_directory_property(WALRUS_ISOLATION_BEFORE_${NAME} ${NAME}) +endforeach() +get_property(WALRUS_ISOLATION_CACHE_BEFORE GLOBAL PROPERTY CACHE_VARIABLES) + +add_subdirectory("${WALRUS_ISOLATION_ROOT}" walrus) + +foreach(NAME ${WALRUS_ISOLATION_VARIABLES}) + if (NOT "${${NAME}}" STREQUAL "${WALRUS_ISOLATION_BEFORE_${NAME}}") + message(FATAL_ERROR "Walrus changed parent variable ${NAME}") + endif () +endforeach() +# A normal-variable shadow must not hide a modified shared cache entry. +get_property(WALRUS_ISOLATION_CACHE_BUILD_TYPE CACHE CMAKE_BUILD_TYPE PROPERTY VALUE) +if (NOT "${WALRUS_ISOLATION_CACHE_BUILD_TYPE}" STREQUAL "${WALRUS_ISOLATION_BEFORE_CMAKE_BUILD_TYPE}") + message(FATAL_ERROR "Walrus changed the shared CMAKE_BUILD_TYPE cache") +endif () +foreach(DIRECTORY "${WALRUS_ISOLATION_ROOT}" + "${WALRUS_ISOLATION_ROOT}/third_party/wabt" + "${WALRUS_ISOLATION_ROOT}/third_party/uvwasi" + "${WALRUS_ISOLATION_ROOT}/third_party/GCutil") + foreach(NAME ${WALRUS_ISOLATION_VARIABLES}) + if (NOT NAME MATCHES "^CMAKE_BUILD_TYPE$") + get_directory_property(ACTUAL DIRECTORY "${DIRECTORY}" DEFINITION ${NAME}) + if (NOT "${ACTUAL}" STREQUAL "${WALRUS_ISOLATION_BEFORE_${NAME}}") + message(FATAL_ERROR "Directory changed ${NAME} in ${DIRECTORY}: ${ACTUAL}") + endif () + endif () + endforeach() + foreach(NAME ${WALRUS_ISOLATION_PROPERTIES}) + get_directory_property(ACTUAL DIRECTORY "${DIRECTORY}" ${NAME}) + if (NOT "${ACTUAL}" STREQUAL "${WALRUS_ISOLATION_BEFORE_${NAME}}") + message(FATAL_ERROR "Directory-scoped ${NAME} in ${DIRECTORY}: ${ACTUAL}") + endif () + endforeach() +endforeach() +get_property(WALRUS_ISOLATION_CACHE_AFTER GLOBAL PROPERTY CACHE_VARIABLES) +foreach(NAME ${WALRUS_ISOLATION_CACHE_AFTER}) + list(FIND WALRUS_ISOLATION_CACHE_BEFORE "${NAME}" EXISTED) + if (EXISTED EQUAL -1 AND NAME MATCHES "^(USE_(ASAN|MSAN|LSAN|UBSAN)|ASAN|WERROR|WITH_EXCEPTIONS|WITH_WASI|HAVE_(ALLOCA_H|UNISTD_H|SNPRINTF|STRCASECMP|WIN32_VT100|SYS_TYPES_H|STDINT_H|STDDEF_H|SSIZE_T)|SSIZE_T|SIZEOF_SIZE_T|HAS_UBSAN_RECOVER_(BARE|ALL))$") + message(FATAL_ERROR "Unprefixed dependency cache variable: ${NAME}") + endif () +endforeach() + +add_executable(walrus_isolation_c sentinel.c) +add_executable(walrus_isolation_cxx sentinel.cpp) +foreach(TARGET walrus_isolation_c walrus_isolation_cxx) + get_target_property(PIC ${TARGET} POSITION_INDEPENDENT_CODE) + if (PIC) + message(FATAL_ERROR "Walrus enabled PIC on an unrelated target") + endif () +endforeach() +add_custom_target(walrus-isolation DEPENDS walrus_isolation_c walrus_isolation_cxx) +message(STATUS "Walrus parent, directory and cache isolation checks passed") diff --git a/test/cmake/isolation/sentinel.c b/test/cmake/isolation/sentinel.c new file mode 100644 index 000000000..685935378 --- /dev/null +++ b/test/cmake/isolation/sentinel.c @@ -0,0 +1,10 @@ +#ifndef PARENT_C_FLAG +#error Parent C flags were lost +#endif +#if defined(WALRUS) || defined(ENABLE_GC) || defined(ENABLE_WASI) || defined(__STDC_LIMIT_MACROS) +#error Private library definitions reached an unrelated target +#endif +#if !defined(PARENT_DIRECTORY_OPTION) || !defined(PARENT_DIRECTORY_DEFINITION) +#error Parent directory settings were lost +#endif +int main(void) { return 0; } diff --git a/test/cmake/isolation/sentinel.cpp b/test/cmake/isolation/sentinel.cpp new file mode 100644 index 000000000..0eb73c64f --- /dev/null +++ b/test/cmake/isolation/sentinel.cpp @@ -0,0 +1,10 @@ +#ifndef PARENT_CXX_FLAG +#error Parent C++ flags were lost +#endif +#if defined(WALRUS) || defined(ENABLE_GC) || defined(ENABLE_WASI) || defined(__STDC_LIMIT_MACROS) +#error Private library definitions reached an unrelated target +#endif +#if !defined(PARENT_DIRECTORY_OPTION) || !defined(PARENT_DIRECTORY_DEFINITION) +#error Parent directory settings were lost +#endif +int main() { return 0; } diff --git a/third_party/uvwasi/CMakeLists.txt b/third_party/uvwasi/CMakeLists.txt index a76134ee7..d7b9c097c 100644 --- a/third_party/uvwasi/CMakeLists.txt +++ b/third_party/uvwasi/CMakeLists.txt @@ -3,9 +3,6 @@ project(uvwasi C) set(UVWASI_DIR ${PROJECT_SOURCE_DIR}/uvwasi) -# Point CMake at any custom modules we may ship -list(APPEND CMAKE_MODULE_PATH "${UVWASI_DIR}/cmake") - # This can be a commit hash or tag set(LIBUV_VERSION v1.47.0) @@ -22,15 +19,10 @@ if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU") if (UVWASI_BUILD_X86) # set x86 build flag - add_compile_options( -m32 ) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") + list(APPEND uvwasi_cflags -m32) endif() endif() -if(APPLE) - set(CMAKE_MACOSX_RPATH ON) -endif() - if(CMAKE_SYSTEM_NAME STREQUAL "Linux") list(APPEND uvwasi_defines _GNU_SOURCE _POSIX_C_SOURCE=200112) endif() @@ -43,25 +35,49 @@ if (CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU") endif () endif () -# Old CMake can use a system libuv; newer CMake can fetch the pinned version. +# Resolve pkg-config libraries to full paths instead of modifying directory +# search paths. A legacy x86 override on a 64-bit toolchain must build libuv +# for x86 too; it cannot use the host's system library. +set(UVWASI_USE_SYSTEM_LIBUV ON) +if (UVWASI_BUILD_X86 AND CMAKE_SIZEOF_VOID_P EQUAL 8) + set(UVWASI_USE_SYSTEM_LIBUV OFF) +endif () +if (CMAKE_CROSSCOMPILING AND "$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "" + AND "$ENV{PKG_CONFIG_SYSROOT_DIR}" STREQUAL "") + # Host pkg-config defaults are unsuitable for a cross-compilation target. + set(UVWASI_USE_SYSTEM_LIBUV OFF) +endif () find_package(PkgConfig QUIET) -if (PKG_CONFIG_FOUND) - pkg_check_modules(LIBUV QUIET libuv>=1.34) +if (PKG_CONFIG_FOUND AND UVWASI_USE_SYSTEM_LIBUV) + pkg_check_modules(UVWASI_SYSTEM_LIBUV QUIET libuv>=1.34) endif () -if (LIBUV_FOUND) - link_directories(${LIBUV_LIBRARY_DIRS}) - list(APPEND uvwasi_cflags ${LIBUV_CFLAGS_OTHER}) +if (UVWASI_USE_SYSTEM_LIBUV AND UVWASI_SYSTEM_LIBUV_FOUND) + set(UVWASI_LIBUV_INCLUDE_DIRS ${UVWASI_SYSTEM_LIBUV_INCLUDE_DIRS}) + set(UVWASI_LIBUV_LIBRARIES) + foreach(LIBRARY ${UVWASI_SYSTEM_LIBUV_LIBRARIES}) + find_library(UVWASI_LIBUV_${LIBRARY} NAMES ${LIBRARY} + HINTS ${UVWASI_SYSTEM_LIBUV_LIBRARY_DIRS}) + if (NOT UVWASI_LIBUV_${LIBRARY}) + message(FATAL_ERROR "Cannot find libuv dependency: ${LIBRARY}") + endif () + list(APPEND UVWASI_LIBUV_LIBRARIES ${UVWASI_LIBUV_${LIBRARY}}) + endforeach() + list(APPEND uvwasi_cflags ${UVWASI_SYSTEM_LIBUV_CFLAGS_OTHER}) else () if (CMAKE_VERSION VERSION_LESS 3.14) - message(FATAL_ERROR "WASI on CMake older than 3.14 requires system libuv (pkg-config libuv), or WALRUS_WASI=OFF") + message(FATAL_ERROR "WASI on CMake older than 3.14 requires system libuv for the target architecture (pkg-config libuv), or WALRUS_WASI=OFF") endif () include(FetchContent) FetchContent_Declare(libuv GIT_REPOSITORY https://github.com/libuv/libuv.git GIT_TAG ${LIBUV_VERSION}) FetchContent_MakeAvailable(libuv) - set(LIBUV_INCLUDE_DIRS ${libuv_SOURCE_DIR}/include) - set(LIBUV_LIBRARIES uv_a) + set_target_properties(uv_a PROPERTIES POSITION_INDEPENDENT_CODE ON) + if (UVWASI_BUILD_X86) + set_property(TARGET uv_a APPEND PROPERTY COMPILE_OPTIONS -m32) + endif () + set(UVWASI_LIBUV_INCLUDE_DIRS ${libuv_SOURCE_DIR}/include) + set(UVWASI_LIBUV_LIBRARIES uv_a) endif () ## uvwasi source code files. @@ -77,19 +93,31 @@ set(uvwasi_sources ${UVWASI_DIR}/src/wasi_serdes.c ) -# ASAN Support -option(ASAN "Enable code asan" OFF) -if(ASAN AND CMAKE_C_COMPILER_ID MATCHES "AppleClang|GNU|Clang") - set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") - set (CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") -endif() +# Keep ASAN as a read-only legacy alias; only the prefixed option is cached. +set(_uvwasi_asan_default OFF) +if (DEFINED ASAN) + set(_uvwasi_asan_default ${ASAN}) +elseif (DEFINED WALRUS_ASAN) + set(_uvwasi_asan_default ${WALRUS_ASAN}) +endif () +if (DEFINED UVWASI_ASAN) + set(UVWASI_ASAN "${UVWASI_ASAN}" CACHE BOOL "Enable uvwasi AddressSanitizer") +endif () +option(UVWASI_ASAN "Enable uvwasi AddressSanitizer" ${_uvwasi_asan_default}) +if (UVWASI_ASAN AND CMAKE_C_COMPILER_ID MATCHES "AppleClang|GNU|Clang") + list(APPEND uvwasi_cflags -fno-omit-frame-pointer -fsanitize=address) +endif () ## Static library target. add_library(uvwasi_a STATIC ${uvwasi_sources}) +set_target_properties(uvwasi_a PROPERTIES POSITION_INDEPENDENT_CODE ON) target_compile_definitions(uvwasi_a PRIVATE ${uvwasi_defines}) target_compile_options(uvwasi_a PRIVATE ${uvwasi_cflags}) -target_include_directories(uvwasi_a PUBLIC ${UVWASI_DIR}/include ${LIBUV_INCLUDE_DIRS}) -target_link_libraries(uvwasi_a PRIVATE ${LIBUV_LIBRARIES}) +target_include_directories(uvwasi_a PUBLIC ${UVWASI_DIR}/include ${UVWASI_LIBUV_INCLUDE_DIRS}) +target_link_libraries(uvwasi_a PRIVATE ${UVWASI_LIBUV_LIBRARIES}) +if (UVWASI_ASAN AND CMAKE_C_COMPILER_ID MATCHES "AppleClang|GNU|Clang") + target_link_libraries(uvwasi_a PRIVATE -fsanitize=address) +endif () message(STATUS "summary of uvwasi build options: @@ -99,10 +127,10 @@ message(STATUS "summary of uvwasi build options: C compiler: ${CMAKE_C_COMPILER} CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS} - LibUV libraries: ${LIBUV_LIBRARIES} - LibUV includes: ${LIBUV_INCLUDE_DIRS} + LibUV libraries: ${UVWASI_LIBUV_LIBRARIES} + LibUV includes: ${UVWASI_LIBUV_INCLUDE_DIRS} Debug logging: ${UVWASI_DEBUG_LOG} Code coverage: ${CODE_COVERAGE} - ASAN: ${ASAN} + ASAN: ${UVWASI_ASAN} Build tests: ${UVWASI_BUILD_TESTS} ") diff --git a/third_party/wabt/CMakeLists.txt b/third_party/wabt/CMakeLists.txt index a6ce1abf6..52a9ae7fc 100644 --- a/third_party/wabt/CMakeLists.txt +++ b/third_party/wabt/CMakeLists.txt @@ -16,80 +16,94 @@ cmake_minimum_required(VERSION 2.8.12...4.0) project(WABT C CXX) -set(PROJECT_VERSION 1.0.30) -include(GNUInstallDirs) - -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -if (CMAKE_VERSION VERSION_LESS 3.1 AND NOT MSVC) - add_compile_options(-std=c++11) -endif () - -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -# Check if wabt is being used directly or via add_subdirectory, FetchContent, etc +set(WABT_VERSION_STRING 1.0.30) set(WABT_MASTER_PROJECT OFF) if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) set(WABT_MASTER_PROJECT ON) -endif() - -# By default use the project version as the version string -set(WABT_VERSION_STRING "${PROJECT_VERSION}") - -option(USE_ASAN "Use address sanitizer" OFF) -option(USE_MSAN "Use memory sanitizer" OFF) -option(USE_LSAN "Use leak sanitizer" OFF) -option(USE_UBSAN "Use undefined behavior sanitizer" OFF) -option(WERROR "Build with warnings as errors" OFF) -# WASI support is still a work in progress. -# Only a handful of syscalls are supported at this point. -option(WITH_WASI "Build WASI support via uvwasi" OFF) +endif () +# Read legacy inputs without adding unprefixed options to the shared cache. +function(wabt_option NAME LEGACY HELP DEFAULT) + if (DEFINED ${NAME}) + set(${NAME} "${${NAME}}" CACHE BOOL "${HELP}") + elseif (DEFINED ${LEGACY}) + set(${NAME} "${${LEGACY}}" CACHE BOOL "${HELP}") + endif () + option(${NAME} "${HELP}" ${DEFAULT}) +endfunction() +wabt_option(WABT_USE_ASAN USE_ASAN "Use address sanitizer" OFF) +wabt_option(WABT_USE_MSAN USE_MSAN "Use memory sanitizer" OFF) +wabt_option(WABT_USE_LSAN USE_LSAN "Use leak sanitizer" OFF) +wabt_option(WABT_USE_UBSAN USE_UBSAN "Use undefined behavior sanitizer" OFF) +wabt_option(WABT_WERROR WERROR "Build WABT with warnings as errors" OFF) +wabt_option(WABT_WITH_EXCEPTIONS WITH_EXCEPTIONS "Enable C++ exceptions in WABT" OFF) + +set(WABT_COMPILE_OPTIONS) +set(WABT_COMPILE_DEFINITIONS ${WABT_DEFINITIONS}) +set(WABT_CXX_ONLY_OPTIONS) if (MSVC) - set(COMPILER_IS_CLANG 0) - set(COMPILER_IS_GNU 0) - set(COMPILER_IS_MSVC 1) + set(WABT_COMPILER_IS_CLANG 0) + set(WABT_COMPILER_IS_GNU 0) + set(WABT_COMPILER_IS_MSVC 1) elseif (CMAKE_C_COMPILER_ID MATCHES "Clang") - set(COMPILER_IS_CLANG 1) - set(COMPILER_IS_GNU 0) - set(COMPILER_IS_MSVC 0) + set(WABT_COMPILER_IS_CLANG 1) + set(WABT_COMPILER_IS_GNU 0) + set(WABT_COMPILER_IS_MSVC 0) elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU") - set(COMPILER_IS_CLANG 0) - set(COMPILER_IS_GNU 1) - set(COMPILER_IS_MSVC 0) + set(WABT_COMPILER_IS_CLANG 0) + set(WABT_COMPILER_IS_GNU 1) + set(WABT_COMPILER_IS_MSVC 0) elseif (CMAKE_SYSTEM_NAME STREQUAL "Emscripten") - set(COMPILER_IS_CLANG 1) - set(COMPILER_IS_GNU 0) - set(COMPILER_IS_MSVC 0) + set(WABT_COMPILER_IS_CLANG 1) + set(WABT_COMPILER_IS_GNU 0) + set(WABT_COMPILER_IS_MSVC 0) else () - set(COMPILER_IS_CLANG 0) - set(COMPILER_IS_GNU 0) - set(COMPILER_IS_MSVC 0) -endif () - -include(CheckIncludeFile) -include(CheckSymbolExists) - -check_include_file("alloca.h" HAVE_ALLOCA_H) -check_include_file("unistd.h" HAVE_UNISTD_H) -check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF) -check_symbol_exists(strcasecmp "strings.h" HAVE_STRCASECMP) - -if (WIN32) - check_symbol_exists(ENABLE_VIRTUAL_TERMINAL_PROCESSING "windows.h" HAVE_WIN32_VT100) + set(WABT_COMPILER_IS_CLANG 0) + set(WABT_COMPILER_IS_GNU 0) + set(WABT_COMPILER_IS_MSVC 0) endif () -include(CheckTypeSize) -check_type_size(ssize_t SSIZE_T) -check_type_size(size_t SIZEOF_SIZE_T) - -configure_file(src/config.h.in include/wabt/config.h @ONLY) - -include_directories(${WABT_SOURCE_DIR} ${WABT_BINARY_DIR}) +# Prefix cached probe results. Generic names needed by CheckTypeSize and +# config.h are confined to this function, so other projects cannot reuse them. +function(wabt_configure_header) + if (WABT_ARCH STREQUAL "x86" AND (WABT_COMPILER_IS_GNU OR WABT_COMPILER_IS_CLANG)) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -m32") + endif () + include(CheckIncludeFile) + include(CheckSymbolExists) + check_include_file("alloca.h" WABT_HAVE_ALLOCA_H) + check_include_file("unistd.h" WABT_HAVE_UNISTD_H) + check_symbol_exists(snprintf "stdio.h" WABT_HAVE_SNPRINTF) + check_symbol_exists(strcasecmp "strings.h" WABT_HAVE_STRCASECMP) + if (WIN32) + check_symbol_exists(ENABLE_VIRTUAL_TERMINAL_PROCESSING "windows.h" WABT_HAVE_WIN32_VT100) + endif () + check_include_file("sys/types.h" WABT_HAVE_SYS_TYPES_H) + check_include_file("stdint.h" WABT_HAVE_STDINT_H) + check_include_file("stddef.h" WABT_HAVE_STDDEF_H) + set(HAVE_SYS_TYPES_H ${WABT_HAVE_SYS_TYPES_H}) + set(HAVE_STDINT_H ${WABT_HAVE_STDINT_H}) + set(HAVE_STDDEF_H ${WABT_HAVE_STDDEF_H}) + include(CheckTypeSize) + check_type_size(ssize_t WABT_SSIZE_T) + check_type_size(size_t WABT_SIZEOF_SIZE_T) + foreach(NAME ALLOCA_H UNISTD_H SNPRINTF STRCASECMP WIN32_VT100) + set(HAVE_${NAME} "${WABT_HAVE_${NAME}}") + endforeach() + set(HAVE_SSIZE_T ${HAVE_WABT_SSIZE_T}) + set(SIZEOF_SIZE_T ${WABT_SIZEOF_SIZE_T}) + foreach(NAME CLANG GNU MSVC) + set(COMPILER_IS_${NAME} ${WABT_COMPILER_IS_${NAME}}) + endforeach() + set(WITH_EXCEPTIONS ${WABT_WITH_EXCEPTIONS}) + configure_file(${WABT_SOURCE_DIR}/src/config.h.in + ${WABT_BINARY_DIR}/include/wabt/config.h @ONLY) +endfunction() +wabt_configure_header() -if (COMPILER_IS_MSVC) - if (WERROR) - add_definitions(-WX) +if (WABT_COMPILER_IS_MSVC) + if (WABT_WERROR) + list(APPEND WABT_COMPILE_OPTIONS -WX) endif () # disable warning C4018: signed/unsigned mismatch @@ -97,87 +111,74 @@ if (COMPILER_IS_MSVC) # seems to not like float compare w/ HUGE_VALF; bug? # disable warnings C4267 and C4244: conversion/truncation from larger to smaller type. # disable warning C4800: implicit conversion from larger int to bool - add_definitions(-W3 -wd4018 -wd4056 -wd4756 -wd4267 -wd4244 -wd4800 -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS) + list(APPEND WABT_COMPILE_OPTIONS -W3 -wd4018 -wd4056 -wd4267 -wd4244 -wd4800) + list(APPEND WABT_COMPILE_DEFINITIONS _CRT_SECURE_NO_WARNINGS _SCL_SECURE_NO_WARNINGS) # multi-core build. - add_definitions("/MP") + list(APPEND WABT_COMPILE_OPTIONS /MP) else () - if (WERROR) - add_definitions(-Werror) + if (WABT_WERROR) + list(APPEND WABT_COMPILE_OPTIONS -Werror) endif () # disable -Wunused-parameter: this is really common when implementing # interfaces, etc. # disable -Wpointer-arith: this is a GCC extension, and doesn't work in MSVC. - add_definitions( + list(APPEND WABT_COMPILE_OPTIONS -Wall -Wextra -Wno-unused-parameter -Wpointer-arith -Wuninitialized ) - set(CMAKE_CXX_EXTENSIONS OFF) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wold-style-cast") + list(APPEND WABT_CXX_ONLY_OPTIONS -Wold-style-cast) - if (NOT WITH_EXCEPTIONS) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions") + if (NOT WABT_WITH_EXCEPTIONS) + list(APPEND WABT_CXX_ONLY_OPTIONS -fno-exceptions) endif () # Need to define __STDC_*_MACROS because C99 specifies that C++ shouldn't # define format (e.g. PRIu64) or limit (e.g. UINT32_MAX) macros without the # definition, and some libcs (e.g. glibc2.17 and earlier) follow that. - add_definitions(-D__STDC_LIMIT_MACROS=1 -D__STDC_FORMAT_MACROS=1) + list(APPEND WABT_COMPILE_DEFINITIONS __STDC_LIMIT_MACROS=1 __STDC_FORMAT_MACROS=1) if (MINGW OR CYGWIN) # On MINGW, _POSIX_C_SOURCE is needed to ensure we use mingw printf # instead of the VC runtime one. - add_definitions(-D_POSIX_C_SOURCE=200809L) + list(APPEND WABT_COMPILE_DEFINITIONS _POSIX_C_SOURCE=200809L) endif() - if (COMPILER_IS_GNU) + if (WABT_COMPILER_IS_GNU) # disable -Wclobbered: it seems to be guessing incorrectly about a local # variable being clobbered by longjmp. - add_definitions(-Wno-clobbered) + list(APPEND WABT_COMPILE_OPTIONS -Wno-clobbered) endif () endif () -set(USE_SANITIZER FALSE) - -function(sanitizer NAME FLAGS) +set(WABT_SANITIZER_OPTIONS) +macro(wabt_sanitizer NAME) if (${NAME}) - if (USE_SANITIZER) - message(FATAL_ERROR "Only one sanitizer allowed") + if (WABT_SANITIZER_OPTIONS) + message(FATAL_ERROR "Only one WABT sanitizer is allowed") endif () - set(USE_SANITIZER TRUE PARENT_SCOPE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}" PARENT_SCOPE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}" PARENT_SCOPE) + list(APPEND WABT_SANITIZER_OPTIONS ${ARGN}) endif () -endfunction() -sanitizer(USE_ASAN "-fsanitize=address") -sanitizer(USE_MSAN "-fsanitize=memory") -sanitizer(USE_LSAN "-fsanitize=leak") - -if (USE_UBSAN) - # -fno-sanitize-recover was deprecated, see if we are compiling with a newer - # clang that requires -fno-sanitize-recover=all. - set(UBSAN_BLACKLIST ${WABT_SOURCE_DIR}/ubsan.blacklist) +endmacro() +wabt_sanitizer(WABT_USE_ASAN -fsanitize=address) +wabt_sanitizer(WABT_USE_MSAN -fsanitize=memory) +wabt_sanitizer(WABT_USE_LSAN -fsanitize=leak) +if (WABT_USE_UBSAN) include(CheckCXXCompilerFlag) - check_cxx_compiler_flag("-fsanitize=undefined -fno-sanitize-recover -Wall -Werror" HAS_UBSAN_RECOVER_BARE) - if (HAS_UBSAN_RECOVER_BARE) - sanitizer(USE_UBSAN "-fsanitize=undefined -fno-sanitize-recover -fsanitize-blacklist=${UBSAN_BLACKLIST}") - endif () - check_cxx_compiler_flag("-fsanitize=undefined -fno-sanitize-recover=all -Wall -Werror" HAS_UBSAN_RECOVER_ALL) - # If we already setup UBSAN recover bare, setting it up again here will be an error. - if (NOT USE_SANITIZER AND HAS_UBSAN_RECOVER_ALL) - sanitizer(USE_UBSAN "-fsanitize=undefined -fno-sanitize-recover=all -fsanitize-blacklist=${UBSAN_BLACKLIST}") - endif () - if (NOT USE_SANITIZER) - message(FATAL_ERROR "UBSAN is not supported") + check_cxx_compiler_flag("-fsanitize=undefined -fno-sanitize-recover=all" WABT_HAS_UBSAN_RECOVER_ALL) + if (WABT_HAS_UBSAN_RECOVER_ALL) + wabt_sanitizer(WABT_USE_UBSAN -fsanitize=undefined -fno-sanitize-recover=all) + else () + check_cxx_compiler_flag("-fsanitize=undefined -fno-sanitize-recover" WABT_HAS_UBSAN_RECOVER_BARE) + if (NOT WABT_HAS_UBSAN_RECOVER_BARE) + message(FATAL_ERROR "UBSAN is not supported") + endif () + wabt_sanitizer(WABT_USE_UBSAN -fsanitize=undefined -fno-sanitize-recover) endif () endif () -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${WABT_SOURCE_DIR}/cmake) - -add_custom_target(everything) - set(WABT_LIBRARY_SRC src/binary-reader-logging.cc src/binary-reader.cc @@ -212,7 +213,7 @@ set(WABT_LIBRARY_SRC src/wast-parser.cc ) -if (COMPILER_IS_MSVC) +if (WABT_COMPILER_IS_MSVC) set(WABT_CXX_FLAGS_INTERNAL ${WABT_CXX_FLAGS_INTERNAL} /fp:strict /Oy-) else () if (WABT_ARCH STREQUAL "x86") @@ -221,10 +222,35 @@ else () endif () endif() -add_compile_options(${WABT_CXX_FLAGS_INTERNAL}) -add_compile_options(${WABT_CXX_FLAGS}) - - add_library(wabt STATIC ${WABT_LIBRARY_SRC}) -target_include_directories(wabt PUBLIC ${PROJECT_SOURCE_DIR}/include "$") -TARGET_COMPILE_DEFINITIONS (wabt PRIVATE ${WABT_DEFINITIONS}) +set_target_properties(wabt PROPERTIES + POSITION_INDEPENDENT_CODE ON + CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF) +if (CMAKE_VERSION VERSION_LESS 3.1 AND NOT WABT_COMPILER_IS_MSVC) + list(APPEND WABT_CXX_ONLY_OPTIONS -std=c++11) +endif () +if (CMAKE_VERSION VERSION_LESS 3.3) + # COMPILE_LANGUAGE expressions were added in 3.3. Older CMake needs + # C++-only options on this target's C++ source files instead. + string(REPLACE ";" " " WABT_CXX_SOURCE_FLAGS "${WABT_CXX_ONLY_OPTIONS}") + foreach(SOURCE ${WABT_LIBRARY_SRC}) + if (SOURCE MATCHES "\\.cc$") + set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "${WABT_CXX_SOURCE_FLAGS}") + endif () + endforeach() +else () + foreach(FLAG ${WABT_CXX_ONLY_OPTIONS}) + target_compile_options(wabt PRIVATE "$<$:${FLAG}>") + endforeach() +endif () +target_compile_options(wabt PRIVATE ${WABT_COMPILE_OPTIONS} + ${WABT_CXX_FLAGS_INTERNAL} ${WABT_CXX_FLAGS} ${WABT_SANITIZER_OPTIONS}) +target_compile_definitions(wabt PRIVATE ${WABT_COMPILE_DEFINITIONS}) +target_include_directories(wabt PRIVATE ${WABT_SOURCE_DIR} ${WABT_BINARY_DIR} + PUBLIC ${WABT_SOURCE_DIR}/include "$") +# Static-library users need the sanitizer runtime when linking, but unrelated +# targets must not inherit sanitizer compile flags. +target_link_libraries(wabt PRIVATE ${WABT_SANITIZER_OPTIONS}) +if (WABT_MASTER_PROJECT) + add_custom_target(everything DEPENDS wabt) +endif ()