diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8055b5b..7489419 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -39,7 +39,20 @@ jobs: 0-cache-macos-latest if: matrix.os == 'macos-latest' - name: Install wasmtime for tests - run: curl -f -L --retry 5 https://wasmtime.dev/install.sh | bash -s -- --version v8.0.1 + # TODO: switch to Wasmtime 17 once it's released, which will include https://github.com/bytecodealliance/wasmtime/pull/7750 + run: | + curl -f -L --retry 5 https://wasmtime.dev/install.sh | bash -s -- --version dev + ~/.wasmtime/bin/wasmtime --version + curl -f -L --retry 5 -o ~/.wasmtime/bin/wasi_snapshot_preview1.command.wasm https://github.com/bytecodealliance/wasmtime/releases/download/v16.0.0/wasi_snapshot_preview1.command.wasm + if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then + curl -f -OL --retry 5 https://github.com/bytecodealliance/wasm-tools/releases/download/wasm-tools-1.0.54/wasm-tools-1.0.54-x86_64-linux.tar.gz + tar xf wasm-tools-1.0.54-x86_64-linux.tar.gz + cp wasm-tools-1.0.54-x86_64-linux/wasm-tools ~/.wasmtime/bin/ + else + curl -f -OL --retry 5 https://github.com/bytecodealliance/wasm-tools/releases/download/wasm-tools-1.0.54/wasm-tools-1.0.54-x86_64-macos.tar.gz + tar xf wasm-tools-1.0.54-x86_64-macos.tar.gz + cp wasm-tools-1.0.54-x86_64-macos/wasm-tools ~/.wasmtime/bin/ + fi - uses: actions/checkout@v3 with: fetch-depth: 0 @@ -59,7 +72,7 @@ jobs: run: NINJA_FLAGS=-v make package LLVM_CMAKE_FLAGS=-DLLVM_CCACHE_BUILD=ON shell: bash - name: Run the testsuite - run: NINJA_FLAGS=-v make check RUNTIME=~/.wasmtime/bin/wasmtime + run: NINJA_FLAGS=-v make check RUNTIME=~/.wasmtime/bin/wasmtime ADAPTER=~/.wasmtime/bin/wasi_snapshot_preview1.command.wasm WASM_TOOLS=~/.wasmtime/bin/wasm-tools - name: Upload artifacts uses: actions/upload-artifact@v1 with: diff --git a/Makefile b/Makefile index fd705b3..76d4281 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,7 @@ default: build check: CC="clang --sysroot=$(BUILD_PREFIX)/share/wasi-sysroot" \ CXX="clang++ --sysroot=$(BUILD_PREFIX)/share/wasi-sysroot -fno-exceptions" \ - PATH="$(PATH_PREFIX)/bin:$$PATH" tests/run.sh "$(BUILD_PREFIX)" "$(RUNTIME)" + PATH="$(PATH_PREFIX)/bin:$$PATH" tests/run.sh "$(BUILD_PREFIX)" "$(RUNTIME)" "$(ADAPTER)" "$(WASM_TOOLS)" clean: rm -rf build $(DESTDIR) @@ -108,6 +108,13 @@ build/llvm.BUILT: touch build/llvm.BUILT build/wasi-libc.BUILT: build/compiler-rt.BUILT + $(MAKE) -C $(ROOT_DIR)/src/wasi-libc \ + CC=$(BUILD_PREFIX)/bin/clang \ + AR=$(BUILD_PREFIX)/bin/llvm-ar \ + NM=$(BUILD_PREFIX)/bin/llvm-nm \ + SYSROOT=$(BUILD_PREFIX)/share/wasi-sysroot \ + WASI_SNAPSHOT=preview2 \ + default libc_so $(MAKE) -C $(ROOT_DIR)/src/wasi-libc \ CC=$(BUILD_PREFIX)/bin/clang \ AR=$(BUILD_PREFIX)/bin/llvm-ar \ @@ -196,11 +203,21 @@ LIBCXX_CMAKE_FLAGS = \ build/libcxx.BUILT: build/llvm.BUILT build/wasi-libc.BUILT # Do the build. + mkdir -p build/libcxx-preview2 + cd build/libcxx-preview2 && cmake -G Ninja $(call LIBCXX_CMAKE_FLAGS,OFF,ON) \ + -DCMAKE_SYSROOT=$(BUILD_PREFIX)/share/wasi-sysroot \ + -DCMAKE_C_FLAGS="$(DEBUG_PREFIX_MAP) $(EXTRA_CFLAGS) --target=wasm32-wasi-preview2" \ + -DCMAKE_CXX_FLAGS="$(DEBUG_PREFIX_MAP) $(EXTRA_CXXFLAGS) --target=wasm32-wasi-preview2" \ + -DLIBCXX_LIBDIR_SUFFIX=$(ESCAPE_SLASH)/wasm32-wasi-preview2 \ + -DLIBCXXABI_LIBDIR_SUFFIX=$(ESCAPE_SLASH)/wasm32-wasi-preview2 \ + -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ + $(LLVM_PROJ_DIR)/runtimes + ninja $(NINJA_FLAGS) -C build/libcxx-preview2 mkdir -p build/libcxx cd build/libcxx && cmake -G Ninja $(call LIBCXX_CMAKE_FLAGS,OFF,ON) \ -DCMAKE_SYSROOT=$(BUILD_PREFIX)/share/wasi-sysroot \ - -DCMAKE_C_FLAGS="$(DEBUG_PREFIX_MAP) $(EXTRA_CFLAGS)" \ - -DCMAKE_CXX_FLAGS="$(DEBUG_PREFIX_MAP) $(EXTRA_CXXFLAGS)" \ + -DCMAKE_C_FLAGS="$(DEBUG_PREFIX_MAP) $(EXTRA_CFLAGS) --target=wasm32-wasi" \ + -DCMAKE_CXX_FLAGS="$(DEBUG_PREFIX_MAP) $(EXTRA_CXXFLAGS) --target=wasm32-wasi" \ -DLIBCXX_LIBDIR_SUFFIX=$(ESCAPE_SLASH)/wasm32-wasi \ -DLIBCXXABI_LIBDIR_SUFFIX=$(ESCAPE_SLASH)/wasm32-wasi \ -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ @@ -209,16 +226,22 @@ build/libcxx.BUILT: build/llvm.BUILT build/wasi-libc.BUILT mkdir -p build/libcxx-threads cd build/libcxx-threads && cmake -G Ninja $(call LIBCXX_CMAKE_FLAGS,ON,OFF) \ -DCMAKE_SYSROOT=$(BUILD_PREFIX)/share/wasi-sysroot \ - -DCMAKE_C_FLAGS="$(DEBUG_PREFIX_MAP) -pthread $(EXTRA_CFLAGS)" \ - -DCMAKE_CXX_FLAGS="$(DEBUG_PREFIX_MAP) -pthread $(EXTRA_CXXFLAGS)" \ + -DCMAKE_C_FLAGS="$(DEBUG_PREFIX_MAP) -pthread $(EXTRA_CFLAGS) --target=wasm32-wasi-threads" \ + -DCMAKE_CXX_FLAGS="$(DEBUG_PREFIX_MAP) -pthread $(EXTRA_CXXFLAGS) --target=wasm32-wasi-threads" \ -DLIBCXX_LIBDIR_SUFFIX=$(ESCAPE_SLASH)/wasm32-wasi-threads \ -DLIBCXXABI_LIBDIR_SUFFIX=$(ESCAPE_SLASH)/wasm32-wasi-threads \ -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ $(LLVM_PROJ_DIR)/runtimes ninja $(NINJA_FLAGS) -C build/libcxx-threads # Do the install. + DESTDIR=$(DESTDIR) ninja $(NINJA_FLAGS) -C build/libcxx-preview2 install + mv $(BUILD_PREFIX)/share/wasi-sysroot/include/c++ $(BUILD_PREFIX)/share/wasi-sysroot/include/wasm32-wasi-preview2/ DESTDIR=$(DESTDIR) ninja $(NINJA_FLAGS) -C build/libcxx install + mv $(BUILD_PREFIX)/share/wasi-sysroot/include/c++ $(BUILD_PREFIX)/share/wasi-sysroot/include/wasm32-wasi/ DESTDIR=$(DESTDIR) ninja $(NINJA_FLAGS) -C build/libcxx-threads install + mv $(BUILD_PREFIX)/share/wasi-sysroot/include/c++ $(BUILD_PREFIX)/share/wasi-sysroot/include/wasm32-wasi-threads/ + # As of this writing, `clang++` will ignore the above include dirs unless this one also exists: + mkdir -p $(BUILD_PREFIX)/share/wasi-sysroot/include/c++/v1 touch build/libcxx.BUILT build/config.BUILT: diff --git a/src/wasi-libc b/src/wasi-libc index c5264e2..925ad6d 160000 --- a/src/wasi-libc +++ b/src/wasi-libc @@ -1 +1 @@ -Subproject commit c5264e2bbe532994d06b039005f2af91bedcc1a6 +Subproject commit 925ad6d75899397d26b9f09a6f195dbf5eb35814 diff --git a/tests/general/abort.c.wasm32-wasi-preview2.stderr.expected b/tests/general/abort.c.wasm32-wasi-preview2.stderr.expected new file mode 100644 index 0000000..26fe376 --- /dev/null +++ b/tests/general/abort.c.wasm32-wasi-preview2.stderr.expected @@ -0,0 +1,6 @@ +Error: failed to run main module `abort.c.---.wasm` + +Caused by: + 0: failed to invoke `run` function + 1: error while executing at wasm backtrace: + 2: wasm trap: wasm `unreachable` instruction executed diff --git a/tests/general/assert-fail.c.wasm32-wasi-preview2.stderr.expected b/tests/general/assert-fail.c.wasm32-wasi-preview2.stderr.expected new file mode 100644 index 0000000..3702431 --- /dev/null +++ b/tests/general/assert-fail.c.wasm32-wasi-preview2.stderr.expected @@ -0,0 +1,7 @@ +Assertion failed: false (assert-fail.c: main: 5) +Error: failed to run main module `assert-fail.c.---.wasm` + +Caused by: + 0: failed to invoke `run` function + 1: error while executing at wasm backtrace: + 2: wasm trap: wasm `unreachable` instruction executed diff --git a/tests/general/sigabrt.c.wasm32-wasi-preview2.stderr.expected b/tests/general/sigabrt.c.wasm32-wasi-preview2.stderr.expected new file mode 100644 index 0000000..f437a82 --- /dev/null +++ b/tests/general/sigabrt.c.wasm32-wasi-preview2.stderr.expected @@ -0,0 +1,6 @@ +raising SIGABRT... +Program received fatal signal: Aborted +Error: failed to run main module `sigabrt.c.---.wasm` + +Caused by: + 0: failed to invoke `run` function diff --git a/tests/run.sh b/tests/run.sh index 36bcda5..62d05e9 100755 --- a/tests/run.sh +++ b/tests/run.sh @@ -23,8 +23,17 @@ wasi_sdk="$1" # Determine the wasm runtime to use, if one is provided. if [ $# -gt 1 ]; then runwasi="$2" + if [ $# -gt 3 ]; then + adapter="$3" + wasm_tools="$4" + else + adapter="" + wasm_tools="" + fi else runwasi="" + adapter="" + wasm_tools="" fi testdir=$(dirname $0) @@ -35,34 +44,37 @@ echo $CC echo $CXX echo "SDK: $wasi_sdk" -cd $testdir/compile-only -for options in -O0 -O2 "-O2 -flto"; do - echo "===== Testing compile-only with $options =====" - for file in *.c; do - echo "Testing compile-only $file..." - ../testcase.sh "" "$CC" "$options" "$file" +for target in wasm32-wasi wasm32-wasi-threads wasm32-wasi-preview2; do + echo "===== Testing target $target =====" + cd $testdir/compile-only + for options in -O0 -O2 "-O2 -flto"; do + echo "===== Testing compile-only with $options =====" + for file in *.c; do + echo "Testing compile-only $file..." + ../testcase.sh "$target" "" "" "" "$CC" "$options" "$file" + done + for file in *.cc; do + echo "Testing compile-only $file..." + ../testcase.sh "$target" "" "" "" "$CXX" "$options" "$file" + done done - for file in *.cc; do - echo "Testing compile-only $file..." - ../testcase.sh "" "$CXX" "$options" "$file" + cd - >/dev/null + + cd $testdir/general + for options in -O0 -O2 "-O2 -flto"; do + echo "===== Testing with $options =====" + for file in *.c; do + echo "Testing $file..." + ../testcase.sh "$target" "$runwasi" "$adapter" "$wasm_tools" "$CC" "$options" "$file" + done + for file in *.cc; do + echo "Testing $file..." + ../testcase.sh "$target" "$runwasi" "$adapter" "$wasm_tools" "$CXX" "$options" "$file" + done done + cd - >/dev/null done -cd - >/dev/null - -cd $testdir/general -for options in -O0 -O2 "-O2 -flto"; do - echo "===== Testing with $options =====" - for file in *.c; do - echo "Testing $file..." - ../testcase.sh "$runwasi" "$CC" "$options" "$file" - done - for file in *.cc; do - echo "Testing $file..." - ../testcase.sh "$runwasi" "$CXX" "$options" "$file" - done -done -cd - >/dev/null - + # Test cmake build system for wasi-sdk test_cmake() { local option diff --git a/tests/testcase.sh b/tests/testcase.sh index 38db9a3..d7368e0 100755 --- a/tests/testcase.sh +++ b/tests/testcase.sh @@ -6,16 +6,20 @@ set -ueo pipefail # Command-line parsing; this script is meant to be run from a higher-level # script, so don't do anything fancy. -runwasi="$1" -compiler="$2" -options="$3" -input="$4" +target="$1" +runwasi="$2" +adapter="$3" +wasm_tools="$4" +compiler="$5" +options="$6" +input="$7" # Compile names for generated files. wasm="$input.$options.wasm" stdout_observed="$input.$options.stdout.observed" stderr_observed="$input.$options.stderr.observed" exit_status_observed="$input.$options.exit_status.observed" +run_args="" # Optionally load compiler options from a file. if [ -e "$input.options" ]; then @@ -24,16 +28,27 @@ else file_options= fi +if [ "$target" == "wasm32-wasi-threads" ]; then + pthread_options="-pthread" +else + pthread_options= +fi + echo "Testing $input..." # Compile the testcase. -$compiler $options $file_options "$input" -o "$wasm" +$compiler --target=$target $pthread_options $options $file_options "$input" -o "$wasm" # If we don't have a runwasi command, we're just doing compile-only testing. if [ "$runwasi" == "" ]; then exit 0 fi +if [ "$target" == "wasm32-wasi-preview2" -a -n "$adapter" -a -n "$wasm_tools" ]; then + "$wasm_tools" component new --adapt "$adapter" "$wasm" -o "$wasm" + run_args="--wasm component-model" +fi + # Determine the input file to write to stdin. if [ -e "$input.stdin" ]; then stdin="$input.stdin" @@ -59,7 +74,7 @@ fi # Run the test, capturing stdout, stderr, and the exit status. exit_status=0 -"$runwasi" $env $dir "$wasm" $dirarg \ +"$runwasi" $run_args $env $dir "$wasm" $dirarg \ < "$stdin" \ > "$stdout_observed" \ 2> "$stderr_observed" \ @@ -68,7 +83,11 @@ echo $exit_status > "$exit_status_observed" # Determine the reference files to compare with. if [ -e "$input.stdout.expected" ]; then - stdout_expected="$input.stdout.expected" + if [ -e "$input.$target.stdout.expected" ]; then + stdout_expected="$input.$target.stdout.expected" + else + stdout_expected="$input.stdout.expected" + fi # Apply output filters. if [ -e "$input.stdout.expected.filter" ]; then @@ -80,8 +99,13 @@ if [ -e "$input.stdout.expected" ]; then else stdout_expected="/dev/null" fi + if [ -e "$input.stderr.expected" ]; then - stderr_expected="$input.stderr.expected" + if [ -e "$input.$target.stderr.expected" ]; then + stderr_expected="$input.$target.stderr.expected" + else + stderr_expected="$input.stderr.expected" + fi # Apply output filters. if [ -e "$input.stderr.expected.filter" ]; then