summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArshia001 <Arshia001@users.noreply.github.com>2023-09-13 18:06:37 +0400
committerGitHub <noreply@github.com>2023-09-13 18:06:37 +0400
commit714ee237db6111c0963891803c736969db3441d2 (patch)
tree2f64b9835fb8adaed6194d05ee2f21d1cbe1fed4
parentbe7a653b6abc5297574dc3586c880ec1b86c54c2 (diff)
parent060a8da29bc2721e3fca7926ea10c03f20403b0e (diff)
Merge pull request #19 from SanderVocke/main
Github Actions Workflow for building a C/C++ sysroot with CI tests.
-rw-r--r--.github/workflows/build_cxx_sysroot.yml120
-rw-r--r--.github/workflows/files/clang-wasix.cmake_toolchain31
-rw-r--r--.github/workflows/main.yml2
-rw-r--r--README.md20
-rw-r--r--libc-top-half/musl/include/sched.h3
-rw-r--r--test/wasix/c_pthreads/CMakeLists.txt4
-rw-r--r--test/wasix/c_pthreads/main.c26
-rw-r--r--test/wasix/c_pthreads/test.sh11
-rw-r--r--test/wasix/cpp_atomic/CMakeLists.txt4
-rw-r--r--test/wasix/cpp_atomic/main.cpp12
-rw-r--r--test/wasix/cpp_atomic/test.sh9
-rw-r--r--test/wasix/cpp_executable/CMakeLists.txt4
-rw-r--r--test/wasix/cpp_executable/main.cpp3
-rw-r--r--test/wasix/cpp_executable/test.sh9
-rw-r--r--test/wasix/cpp_iostream/CMakeLists.txt4
-rw-r--r--test/wasix/cpp_iostream/main.cpp6
-rw-r--r--test/wasix/cpp_iostream/test.sh9
-rw-r--r--test/wasix/cpp_threads/CMakeLists.txt4
-rw-r--r--test/wasix/cpp_threads/main.cpp14
-rw-r--r--test/wasix/cpp_threads/test.sh11
-rwxr-xr-xtest/wasix/run_tests.sh32
21 files changed, 335 insertions, 3 deletions
diff --git a/.github/workflows/build_cxx_sysroot.yml b/.github/workflows/build_cxx_sysroot.yml
new file mode 100644
index 0000000..54beed2
--- /dev/null
+++ b/.github/workflows/build_cxx_sysroot.yml
@@ -0,0 +1,120 @@
+name: Build C/C++ Sysroot
+
+on:
+ push:
+ branches: [ "main" ]
+ pull_request:
+ branches: [ "main" ]
+
+permissions:
+ contents: read
+ checks: write
+
+jobs:
+ build_cxx_sysroot:
+ runs-on: ubuntu-latest
+ container:
+ image: archlinux:base-devel
+ options: --user root --workdir /
+ steps:
+ - name: Update and install dependencies
+ run: |
+ pacman -Syu --noconfirm
+ pacman -Sy --noconfirm coreutils nodejs npm wget git cmake ninja llvm clang rsync make lld wasmer cargo
+
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ submodules: true
+
+ - name: Build
+ run: |
+ git config --global --add safe.directory $(pwd)
+ ./build32.sh
+ rm -rf /opt/wasix-sysroot
+ cp -r sysroot /opt/wasix-sysroot
+ cp .github/workflows/files/clang-wasix.cmake_toolchain /opt/wasix-sysroot/clang-wasix.cmake_toolchain
+
+ - name: Determine LLVM revision
+ run: |
+ export LLVM_TAG=$(echo "llvmorg-$(llvm-ar --version | grep -i "LLVM version" | sed -r 's/.*version ([0-9\.]+).*/\1/')")
+ echo "LLVM tag: $LLVM_TAG"
+ echo "LLVM_REV=$(git ls-remote --tags https://github.com/llvm/llvm-project.git $LLVM_TAG | sed -r 's/([^ \t]*).*/\1/')" | tee -a $GITHUB_ENV
+ echo "LLVM_TAG=$LLVM_TAG" | tee -a $GITHUB_ENV
+
+ - name: Cache LLVM
+ uses: actions/cache@v3
+ if: ${{ !env.ACT }}
+ with:
+ path: llvm-project
+ key: llvm-${{ env.LLVM_REV }}
+
+ - name: Checkout LLVM
+ run: |
+ if [ ! -d "llvm-project" ]; then git clone https://github.com/llvm/llvm-project.git; fi
+ cd llvm-project
+ git fetch origin refs/tags/${{ env.LLVM_TAG }}
+ if [ "$(git rev-parse ${{ env.LLVM_TAG }})" != "$(git rev-parse HEAD)" ]; then echo "Checkout ($(git rev-parse ${{ env.LLVM_TAG }}) != $(git rev-parse HEAD))" && git reset --hard ${{ env.LLVM_TAG }} && echo "checked out $(git rev-parse HEAD)"; fi
+
+ - name: Build and install compiler_rt builtins
+ run: |
+ mkdir -p build-compiler-rt-builtins
+ cd build-compiler-rt-builtins
+ cmake --fresh -DCOMPILER_RT_BAREMETAL_BUILD=On -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCOMPILER_RT_OS_DIR=wasm32-wasi -DCOMPILER_RT_DEFAULT_TARGET_ONLY:BOOL=ON -DCMAKE_TOOLCHAIN_FILE=/opt/wasix-sysroot/clang-wasix.cmake_toolchain -DCMAKE_SYSROOT=/opt/wasix-sysroot -DCMAKE_INSTALL_PREFIX=/opt/wasix-sysroot ../llvm-project/compiler-rt/lib/builtins
+ cmake --build . --target install --parallel 4
+ export CLANG_MAJOR_VERSION=$(clang --version | grep -i "clang version" | sed -r 's/.*version ([0-9]+).*/\1/')
+ mkdir -p /usr/lib/clang/$CLANG_MAJOR_VERSION/lib/wasi
+ cp /opt/wasix-sysroot/lib/wasm32-wasi/libclang_rt.builtins-wasm32.a /usr/lib/clang/$CLANG_MAJOR_VERSION/lib/wasi/libclang_rt.builtins-wasm32.a
+
+ - name: Build and install LLVM libc++
+ run: >
+ mkdir -p build-libcxx &&
+ cd build-libcxx &&
+ cmake
+ --fresh
+ -DCMAKE_TOOLCHAIN_FILE=/opt/wasix-sysroot/clang-wasix.cmake_toolchain
+ -DCMAKE_SYSROOT=/opt/wasix-sysroot
+ -DCMAKE_INSTALL_PREFIX=/opt/wasix-sysroot
+ -DCXX_SUPPORTS_CXX11=ON
+ -DLIBCXX_ENABLE_THREADS:BOOL=ON
+ -DLIBCXX_HAS_PTHREAD_API:BOOL=ON
+ -DLIBCXX_HAS_EXTERNAL_THREAD_API:BOOL=OFF
+ -DLIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY:BOOL=OFF
+ -DLIBCXX_HAS_WIN32_THREAD_API:BOOL=OFF
+ -DCMAKE_BUILD_TYPE=RelWithDebugInfo
+ -DLIBCXX_ENABLE_SHARED:BOOL=OFF
+ -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY:BOOL=OFF
+ -DLIBCXX_ENABLE_EXCEPTIONS:BOOL=OFF
+ -DLIBCXX_ENABLE_FILESYSTEM:BOOL=OFF
+ -DLIBCXX_CXX_ABI=libcxxabi
+ -DLIBCXX_HAS_MUSL_LIBC:BOOL=ON
+ -DLIBCXX_ABI_VERSION=2
+ -DLIBCXXABI_ENABLE_EXCEPTIONS:BOOL=OFF
+ -DLIBCXXABI_ENABLE_SHARED:BOOL=OFF
+ -DLIBCXXABI_SILENT_TERMINATE:BOOL=ON
+ -DLIBCXXABI_ENABLE_THREADS:BOOL=ON
+ -DLIBCXXABI_HAS_PTHREAD_API:BOOL=ON
+ -DLIBCXXABI_HAS_EXTERNAL_THREAD_API:BOOL=OFF
+ -DLIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY:BOOL=OFF
+ -DLIBCXXABI_HAS_WIN32_THREAD_API:BOOL=OFF
+ -DLIBCXXABI_ENABLE_PIC:BOOL=OFF
+ -DCMAKE_C_COMPILER_WORKS=ON
+ -DCMAKE_CXX_COMPILER_WORKS=ON
+ -DLLVM_COMPILER_CHECKED=ON
+ -DUNIX:BOOL=ON
+ -DLIBCXX_LIBDIR_SUFFIX=/wasm32-wasi
+ -DLIBCXXABI_LIBDIR_SUFFIX=/wasm32-wasi
+ -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi"
+ ../llvm-project/runtimes
+ && cmake --build . --target install --parallel 4
+
+ - name: Upload sysroot
+ if: ${{ !env.ACT }}
+ uses: actions/upload-artifact@v2
+ with:
+ name: wasix-sysroot
+ path: /opt/wasix-sysroot
+
+ - name: Run WASIX tests
+ run: |
+ TOOLCHAIN=/opt/wasix-sysroot/clang-wasix.cmake_toolchain ./test/wasix/run_tests.sh
diff --git a/.github/workflows/files/clang-wasix.cmake_toolchain b/.github/workflows/files/clang-wasix.cmake_toolchain
new file mode 100644
index 0000000..f0807e7
--- /dev/null
+++ b/.github/workflows/files/clang-wasix.cmake_toolchain
@@ -0,0 +1,31 @@
+# Cmake toolchain description file for the Makefile for WASI
+cmake_minimum_required(VERSION 3.5.0)
+
+set(COMPILE_FLAGS "-O2 -matomics -mbulk-memory -mmutable-globals -pthread -mthread-model posix -ftls-model=local-exec -fno-trapping-math -D_WASI_EMULATED_MMAN -D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_PROCESS_CLOCKS -fno-exceptions")
+set(LINK_FLAGS "-lwasi-emulated-mman -lwasi-emulated-process-clocks -lwasi-emulated-getpid -fno-exceptions -Wl,--shared-memory -Wl,--max-memory=4294967296 -Wl,--import-memory -Wl,--export-dynamic -Wl,--export=__heap_base -Wl,--export=__stack_pointer -Wl,--export=__data_end -Wl,--export=__wasm_init_tls -Wl,--export=__wasm_signal -Wl,--export=__tls_size -Wl,--export=__tls_align -Wl,--export=__tls_base")
+
+set(CMAKE_SYSTEM_NAME WASI) # Generic for now, to not trigger a Warning
+set(CMAKE_SYSTEM_VERSION 1)
+set(CMAKE_SYSTEM_PROCESSOR wasm32)
+set(CMAKE_C_COMPILER_ID Clang)
+set(triple wasm32-wasmer-wasi)
+set(CMAKE_C_COMPILER_TARGET ${triple})
+set(CMAKE_CXX_COMPILER_TARGET ${triple})
+set(CMAKE_ASM_COMPILER_TARGET ${triple})
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILE_FLAGS}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILE_FLAGS}")
+set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} ${LINK_FLAGS}")
+set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LINK_FLAGS}")
+set(CMAKE_${lang}_COMPILE_OPTIONS_SYSROOT "--sysroot=")
+
+set(CMAKE_C_COMPILER clang)
+set(CMAKE_CXX_COMPILER clang++)
+set(CMAKE_LINKER wasm-ld)
+set(CMAKE_AR llvm-ar)
+
+# Don't look in the sysroot for executables to run during the build
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+# Only look in the sysroot (not in the host paths) for the rest
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) \ No newline at end of file
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 2af8a5b..f73a3e7 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -1,5 +1,5 @@
name: CI
-on: [push, pull_request]
+on: workflow_dispatch # This is the wasi-libc CI build, not for wasix-libc
jobs:
buildlibc:
diff --git a/README.md b/README.md
index 4cea390..6b1817d 100644
--- a/README.md
+++ b/README.md
@@ -47,6 +47,26 @@ Major bug fixes and/or zero day vulnerabilities will be addressed promptly here
with careful consideration for resolving issues without compromising the
long-term support goal.
+# Installation
+
+A pre-built sysroot suitable for C/C++ is released in this repository.
+
+To build from source, have a look at the `build_cxx_sysroot.yml` script and
+replicate its build steps.
+
+# Usage
+
+For building CMake projects, a toolchain file is included in the released sysroot
+at `wasix-sysroot/clang-wasm.cmake_toolchain`. In addition to specifying the
+toolchain:
+
+* `wasm-ld` is needed for linking. It is usually available in your system's `LLVM`
+ linker package. It should be in the `PATH`.
+* `CMAKE_TOOLCHAIN_FILE` and `CMAKE_SYSROOT` should both be set by you.
+
+The WASIX-specific tests and script in `test/wasix` can serve as examples for how
+to set this up.
+
# WASI Libc
WASI Libc is a libc for WebAssembly programs built on top of WASI system calls.
diff --git a/libc-top-half/musl/include/sched.h b/libc-top-half/musl/include/sched.h
index 3d3fbe8..8c12e94 100644
--- a/libc-top-half/musl/include/sched.h
+++ b/libc-top-half/musl/include/sched.h
@@ -81,9 +81,8 @@ int clone (int (*)(void *), void *, int, void *, ...);
int unshare(int);
int setns(int, int);
-void *memcpy(void *__restrict, const void *__restrict, size_t);
+#include <__functions_memcpy.h>
int memcmp(const void *, const void *, size_t);
-void *memset (void *, int, size_t);
void *calloc(size_t, size_t);
void free(void *);
diff --git a/test/wasix/c_pthreads/CMakeLists.txt b/test/wasix/c_pthreads/CMakeLists.txt
new file mode 100644
index 0000000..de21e61
--- /dev/null
+++ b/test/wasix/c_pthreads/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required (VERSION 3.5.0)
+project (basic_executable)
+
+add_executable(main main.c) \ No newline at end of file
diff --git a/test/wasix/c_pthreads/main.c b/test/wasix/c_pthreads/main.c
new file mode 100644
index 0000000..ba5d49a
--- /dev/null
+++ b/test/wasix/c_pthreads/main.c
@@ -0,0 +1,26 @@
+
+#include <pthread.h>
+#include <stdio.h>
+
+void *thread(void *ptr)
+{
+ long type = (long)ptr;
+ fprintf(stdout,"thread %ld\n", type);
+ return ptr;
+}
+
+int main(int argc, char **argv)
+{
+ pthread_t thread1, thread2;
+ int thr = 1;
+ int thr2 = 2;
+ pthread_create(&thread1, NULL, *thread, (void*)thr);
+ pthread_create(&thread2, NULL, *thread, (void*)thr2);
+
+ pthread_join(thread1,NULL);
+ pthread_join(thread2,NULL);
+
+ fprintf(stdout, "threads joined\n");
+
+ return 0;
+} \ No newline at end of file
diff --git a/test/wasix/c_pthreads/test.sh b/test/wasix/c_pthreads/test.sh
new file mode 100644
index 0000000..caf5767
--- /dev/null
+++ b/test/wasix/c_pthreads/test.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+tmpfile=$(mktemp)
+wasmer run --verbose --enable-all ./main > $tmpfile
+RESULT=$?
+if [ "$RESULT" != "0" ]; then
+ echo "Test failed: different exit code ($RESULT vs. 0)" > /dev/stderr
+ exit 1
+fi
+
+echo "c_pthreads test passed" \ No newline at end of file
diff --git a/test/wasix/cpp_atomic/CMakeLists.txt b/test/wasix/cpp_atomic/CMakeLists.txt
new file mode 100644
index 0000000..94ec92f
--- /dev/null
+++ b/test/wasix/cpp_atomic/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required (VERSION 3.5.0)
+project (basic_executable)
+
+add_executable(main main.cpp) \ No newline at end of file
diff --git a/test/wasix/cpp_atomic/main.cpp b/test/wasix/cpp_atomic/main.cpp
new file mode 100644
index 0000000..a3c3fd0
--- /dev/null
+++ b/test/wasix/cpp_atomic/main.cpp
@@ -0,0 +1,12 @@
+#include <atomic>
+#include <stdio.h>
+
+std::atomic<int> a;
+std::atomic<int> b;
+
+int main(int argc, char** argv) {
+ a = 10;
+ b = a.load();
+ fprintf(stdout, "%d\n", b.load());
+ return 0;
+} \ No newline at end of file
diff --git a/test/wasix/cpp_atomic/test.sh b/test/wasix/cpp_atomic/test.sh
new file mode 100644
index 0000000..f14bd18
--- /dev/null
+++ b/test/wasix/cpp_atomic/test.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+wasmer run --verbose --enable-all ./main
+RESULT=$?
+if [ "$RESULT" != "0" ]; then
+ echo "Test failed: different exit code ($RESULT vs. 0)" > /dev/stderr
+ exit 1
+fi
+echo "cpp_atomic test passed" \ No newline at end of file
diff --git a/test/wasix/cpp_executable/CMakeLists.txt b/test/wasix/cpp_executable/CMakeLists.txt
new file mode 100644
index 0000000..94ec92f
--- /dev/null
+++ b/test/wasix/cpp_executable/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required (VERSION 3.5.0)
+project (basic_executable)
+
+add_executable(main main.cpp) \ No newline at end of file
diff --git a/test/wasix/cpp_executable/main.cpp b/test/wasix/cpp_executable/main.cpp
new file mode 100644
index 0000000..96aef32
--- /dev/null
+++ b/test/wasix/cpp_executable/main.cpp
@@ -0,0 +1,3 @@
+int main(int argc, char** argv) {
+ return 123;
+} \ No newline at end of file
diff --git a/test/wasix/cpp_executable/test.sh b/test/wasix/cpp_executable/test.sh
new file mode 100644
index 0000000..e67e4c6
--- /dev/null
+++ b/test/wasix/cpp_executable/test.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+wasmer run --verbose --enable-all ./main
+RESULT=$?
+if [ "$RESULT" != "123" ]; then
+ echo "Test failed: different exit code ($RESULT vs. 123)" > /dev/stderr
+ exit 1
+fi
+echo "cpp_executable test passed" \ No newline at end of file
diff --git a/test/wasix/cpp_iostream/CMakeLists.txt b/test/wasix/cpp_iostream/CMakeLists.txt
new file mode 100644
index 0000000..94ec92f
--- /dev/null
+++ b/test/wasix/cpp_iostream/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required (VERSION 3.5.0)
+project (basic_executable)
+
+add_executable(main main.cpp) \ No newline at end of file
diff --git a/test/wasix/cpp_iostream/main.cpp b/test/wasix/cpp_iostream/main.cpp
new file mode 100644
index 0000000..f19bd5e
--- /dev/null
+++ b/test/wasix/cpp_iostream/main.cpp
@@ -0,0 +1,6 @@
+#include <iostream>
+
+int main(int argc, char** argv) {
+ std::cout << "Hello, world!\n";
+ return 0;
+} \ No newline at end of file
diff --git a/test/wasix/cpp_iostream/test.sh b/test/wasix/cpp_iostream/test.sh
new file mode 100644
index 0000000..0fcb58b
--- /dev/null
+++ b/test/wasix/cpp_iostream/test.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+wasmer run --verbose --enable-all ./main
+RESULT=$?
+if [ "$RESULT" != "0" ]; then
+ echo "Test failed: different exit code ($RESULT vs. 0)" > /dev/stderr
+ exit 1
+fi
+echo "cpp_iostream test passed" \ No newline at end of file
diff --git a/test/wasix/cpp_threads/CMakeLists.txt b/test/wasix/cpp_threads/CMakeLists.txt
new file mode 100644
index 0000000..94ec92f
--- /dev/null
+++ b/test/wasix/cpp_threads/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required (VERSION 3.5.0)
+project (basic_executable)
+
+add_executable(main main.cpp) \ No newline at end of file
diff --git a/test/wasix/cpp_threads/main.cpp b/test/wasix/cpp_threads/main.cpp
new file mode 100644
index 0000000..8f750ba
--- /dev/null
+++ b/test/wasix/cpp_threads/main.cpp
@@ -0,0 +1,14 @@
+#include <string>
+#include <thread>
+#include <stdio.h>
+
+using namespace std;
+
+void task1(string msg) {
+ printf("task1 says: %s\n", msg.c_str());
+}
+
+int main() {
+ thread t1(task1, "Hello World!");
+ t1.join();
+} \ No newline at end of file
diff --git a/test/wasix/cpp_threads/test.sh b/test/wasix/cpp_threads/test.sh
new file mode 100644
index 0000000..a5bfdea
--- /dev/null
+++ b/test/wasix/cpp_threads/test.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+tmpfile=$(mktemp)
+wasmer run --verbose --enable-all ./main > $tmpfile
+RESULT=$?
+if [ "$RESULT" != "0" ]; then
+ echo "Test failed: different exit code ($RESULT vs. 0)" > /dev/stderr
+ exit 1
+fi
+
+echo "cpp_threads test passed" \ No newline at end of file
diff --git a/test/wasix/run_tests.sh b/test/wasix/run_tests.sh
new file mode 100755
index 0000000..3337a95
--- /dev/null
+++ b/test/wasix/run_tests.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
+BUILD_DIR=$SCRIPT_DIR/../../test-builds
+TESTS=
+STATUS=0
+FAILED_TESTS=""
+PASSED_TESTS=""
+
+if [ ! -z "${@:1}" ]; then
+ TESTS=${@:1}
+else
+ TESTS=$(cd $SCRIPT_DIR && ls -d */)
+fi
+
+for test in $TESTS; do
+ mkdir -p ${BUILD_DIR}/${test}
+ cd ${BUILD_DIR}/${test}
+ cmake --fresh -DCMAKE_MAKE_PROGRAM=make -DCMAKE_TOOLCHAIN_FILE=$TOOLCHAIN -DCMAKE_SYSROOT=/opt/wasix-sysroot $SCRIPT_DIR/${test}
+ cmake --build . --target all
+ bash $SCRIPT_DIR/${test}/test.sh
+ RESULT=$?
+ if [ $RESULT -eq 0 ]; then
+ PASSED_TESTS="$PASSED_TESTS $test"
+ else
+ FAILED_TESTS="$FAILED_TESTS $test"
+ STATUS=1
+ fi
+done
+
+echo "Passed tests: $PASSED_TESTS"
+echo "Failed tests: $FAILED_TESTS"
+exit $STATUS