From ce154a252db4281880f9329019b7fea72578022e Mon Sep 17 00:00:00 2001 From: jubianchi Date: Wed, 6 Jan 2021 21:21:03 +0100 Subject: [PATCH] chore: Build Wasmer on musl Closes #1482 Closes #1766 --- .cargo/config.toml | 2 +- .github/workflows/main.yaml | 114 ++++++++++++++++++++++++++++++------ Makefile | 55 ++++++++++------- bors.toml | 1 + lib/c-api/build.rs | 17 +++++- lib/c-api/tests/.gitignore | 5 ++ 6 files changed, 153 insertions(+), 41 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 5ae061b86c3..db3ecd9c0de 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,4 +1,4 @@ [target.'cfg(target_os = "linux")'] rustflags = [ - "-C", "link-arg=-Wl,-E" + "-C", "link-arg=-Wl,-E", ] diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 4ad14554f3f..61726d1ed9c 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -38,7 +38,6 @@ jobs: strategy: fail-fast: false matrix: - build: [linux-x64, macos-x64, macos-arm64, windows-x64, linux-aarch64] include: - build: linux-x64 os: ubuntu-18.04 @@ -77,14 +76,15 @@ jobs: CARGO_SCCACHE_VERSION: 0.2.14-alpha.0-parity SCCACHE_AZURE_BLOB_CONTAINER: wasmerstoragesccacheblob SCCACHE_AZURE_CONNECTION_STRING: ${{ secrets.SCCACHE_AZURE_CONNECTION_STRING }} + TARGET: ${{ matrix.target }} steps: - uses: actions/checkout@v2 - name: Set up libstdc++ on Linux + if: matrix.build == 'linux-x64' run: | sudo apt-get update -y sudo apt-get install -y --allow-downgrades libstdc++6=8.4.0-1ubuntu1~18.04 sudo apt-get install --reinstall g++-8 - if: matrix.os == 'ubuntu-18.04' - name: Install Rust ${{ matrix.rust }} uses: actions-rs/toolchain@v1 with: @@ -125,7 +125,6 @@ jobs: ~/.cargo/registry ~/.cargo/git key: ${{ matrix.build }}-${{ matrix.target }}-cargo-${{ hashFiles('Cargo.lock') }}-v1 - # Install sccache - uses: actions/cache@v2 with: path: ${{ runner.tool_cache }}/cargo-sccache @@ -138,7 +137,7 @@ jobs: shell: bash - name: Setup Rust target run: | - cat << EOF > .cargo/config.toml + cat << EOF >> .cargo/config.toml [build] target = "${{ matrix.target }}" EOF @@ -172,7 +171,7 @@ jobs: - name: Test run: | make test - if: matrix.target != 'aarch64-apple-darwin' + if: matrix.build != 'macos-arm64' - name: Test C API run: | make test-capi @@ -189,9 +188,9 @@ jobs: run: | make build-wasmer - name: Build Wapm binary + if: needs.setup.outputs.DOING_RELEASE == '1' run: | make build-wapm - if: needs.setup.outputs.DOING_RELEASE == '1' - name: Install Nightly Rust for Headless uses: actions-rs/toolchain@v1 with: @@ -201,6 +200,7 @@ jobs: components: "rust-src" if: needs.setup.outputs.DOING_RELEASE == '1' - name: Build Minimal Wasmer Headless + if: needs.setup.outputs.DOING_RELEASE == '1' run: | cargo install xargo echo "" >> Cargo.toml @@ -215,12 +215,13 @@ jobs: echo "codegen-units = 1" >> Cargo.toml echo "rpath = false" >> Cargo.toml make build-wasmer-headless-minimal - if: needs.setup.outputs.DOING_RELEASE == '1' - name: Copy target binaries run: | mkdir -p target/release cp target/${{matrix.target}}/release/wasmer* target/release - cp target/${{matrix.target}}/release/libwasmer* target/release + if find target/${{matrix.target}}/release -type f -name 'libwasmer*' -maxdepth 1 | grep -q "."; then + cp target/${{matrix.target}}/release/libwasmer* target/release + fi if [ -d "wapm-cli" ]; then mkdir -p wapm-cli/target/release cp wapm-cli/target/${{matrix.target}}/release/wapm* wapm-cli/target/release @@ -242,7 +243,7 @@ jobs: make test-integration if: matrix.run_integration_tests && matrix.os != 'windows-latest' - name: Cross compile from Linux - if: matrix.os == 'ubuntu-18.04' + if: matrix.build == 'linux-x64' shell: bash run: | ls target/release @@ -289,6 +290,73 @@ jobs: if-no-files-found: error retention-days: 1 + test-docker: + name: Test on ${{ matrix.build }} + runs-on: ubuntu-latest + needs: setup + strategy: + fail-fast: false + matrix: + include: + - build: linux-musl-x64 + image: alpine:latest + rust: 1.48 + artifact_name: 'wasmer-linux-musl-amd64' + steps: + - uses: actions/checkout@v2 + + - uses: addnab/docker-run-action@v1 + with: + image: ${{ matrix.image }} + options: -v ${{ github.workspace }}:/work + run: | + set -e + + # Set up tools + apk add musl-dev curl make libtool libffi-dev gcc automake autoconf git + + # Install Rust ${{ matrix.rust }} + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > rustup.sh + sh ./rustup.sh -y + source ~/.cargo/env + rm -f ./rustup.sh + + # Set up Rust + rustup toolchain install ${{ matrix.rust }} + rustup default ${{ matrix.rust }} + + # Change working directory + cd /work + + # Test + make test + + # Test C API + make test-capi + + # Build C API + make build-capi + + # Build Wasmer binary + make build-wasmer + + # Build Wapm binary + make build-wapm + + # Dist + make distribution + + # Run integration tests + export WASMER_DIR=`pwd`/package + make test-integration + - name: Upload Artifacts + uses: actions/upload-artifact@v2 + with: + name: ${{ matrix.artifact_name }} + path: dist + if-no-files-found: error + retention-days: 1 + test-cross-compile-on-linux: name: Test cross-compile on linux needs: [setup, test] @@ -339,7 +407,7 @@ jobs: # wasmer run artifacts/cross/cross_compiled_from_mac/win_from_mac.wjit -- --eval "function greet(name) { return JSON.stringify('Hello, ' + name); }; print(greet('World'));" release: - needs: [setup, test, test-cross-compile-on-linux, test-cross-compile-on-mac] #, test-cross-compile-on-win] + needs: [setup, test, test-docker, test-cross-compile-on-linux, test-cross-compile-on-mac] #, test-cross-compile-on-win] runs-on: ubuntu-latest if: needs.setup.outputs.DOING_RELEASE == '1' steps: @@ -347,7 +415,6 @@ jobs: uses: actions/download-artifact@v2 with: path: artifacts - - name: Create Release id: create_release uses: actions/create-release@v1 @@ -358,7 +425,6 @@ jobs: release_name: Release ${{ needs.setup.outputs.VERSION }} draft: true prerelease: false - - name: Upload Release Asset Windows Installer uses: actions/upload-release-asset@v1 env: @@ -368,7 +434,6 @@ jobs: asset_path: artifacts/wasmer-windows-amd64/WasmerInstaller.exe asset_name: wasmer-windows.exe asset_content_type: application/vnd.microsoft.portable-executable - - name: Upload Release Asset Windows uses: actions/upload-release-asset@v1 env: @@ -378,7 +443,6 @@ jobs: asset_path: artifacts/wasmer-windows-amd64/wasmer.tar.gz asset_name: wasmer-windows-amd64.tar.gz asset_content_type: application/gzip - - name: Upload Release Asset Linux amd64 uses: actions/upload-release-asset@v1 env: @@ -388,7 +452,16 @@ jobs: asset_path: artifacts/wasmer-linux-amd64/wasmer.tar.gz asset_name: wasmer-linux-amd64.tar.gz asset_content_type: application/gzip - + - name: Upload Release Asset Linux amd64 (musl) + id: upload-release-asset-linux-musl-amd64 + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: artifacts/wasmer-linux-musl-amd64/wasmer.tar.gz + asset_name: wasmer-linux-musl-amd64.tar.gz + asset_content_type: application/gzip - name: Upload Release Asset Mac amd64 uses: actions/upload-release-asset@v1 env: @@ -398,7 +471,6 @@ jobs: asset_path: artifacts/wasmer-darwin-amd64/wasmer.tar.gz asset_name: wasmer-darwin-amd64.tar.gz asset_content_type: application/gzip - - name: Upload Release Asset Mac arm64 uses: actions/upload-release-asset@v1 env: @@ -408,7 +480,6 @@ jobs: asset_path: artifacts/wasmer-darwin-arm64/wasmer.tar.gz asset_name: wasmer-darwin-arm64.tar.gz asset_content_type: application/gzip - - name: Upload Release Asset Linux aarch64 uses: actions/upload-release-asset@v1 env: @@ -418,6 +489,15 @@ jobs: asset_path: artifacts/wasmer-linux-aarch64/wasmer.tar.gz asset_name: wasmer-linux-aarch64.tar.gz asset_content_type: application/gzip + - name: Upload Release Asset Linux (musl) amd64 + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: artifacts/wasmer-linux-musl-amd64/wasmer.tar.gz + asset_name: wasmer-linux-musl-amd64.tar.gz + asset_content_type: application/gzip audit: name: Audit diff --git a/Makefile b/Makefile index 74411b603c1..6e95482f2bb 100644 --- a/Makefile +++ b/Makefile @@ -3,11 +3,13 @@ ifneq ($(OS), Windows_NT) ARCH := $(shell uname -m) UNAME_S := $(shell uname -s) LIBC ?= $(shell ldd 2>&1 | grep -o musl | head -n1) + TARGET ?= $(CARGO_BUILD_TARGET) else # We can assume, if in windows it will likely be in x86_64 ARCH := x86_64 UNAME_S := LIBC ?= + TARGET ?= $(CARGO_BUILD_TARGET) endif # Which compilers we build. These have dependencies that may not be on the system. @@ -103,11 +105,18 @@ ifneq (, $(LIBC)) $(info C standard library: $(bold)$(green)$(LIBC)$(reset)) endif +ifneq (, $(TARGET)) +$(info Target: $(bold)$(green)$(TARGET)$(reset)) +endif + $(info Host target: $(bold)$(green)$(HOST_TARGET)$(reset)) $(info Available compilers: $(bold)$(green)${compilers}$(reset)) $(info Compilers features: $(bold)$(green)${compiler_features}$(reset)) $(info Available compilers + engines for test: $(bold)$(green)${test_compilers_engines}$(reset)) +ifneq (,$(TARGET)) + TARGET := $(TARGET)/ +endif ############ # Building # @@ -335,13 +344,13 @@ package-wapm: mkdir -p "package/bin" ifneq ($(OS), Windows_NT) if [ -d "wapm-cli" ]; then \ - cp wapm-cli/target/release/wapm package/bin/ ;\ + cp wapm-cli/target/$(TARGET)release/wapm package/bin/ ;\ echo "#!/bin/bash\nwapm execute \"\$$@\"" > package/bin/wax ;\ chmod +x package/bin/wax ;\ fi else if [ -d "wapm-cli" ]; then \ - cp wapm-cli/target/release/wapm package/bin/ ;\ + cp wapm-cli/target/$(TARGET)release/wapm package/bin/ ;\ fi ifeq ($(UNAME_S), Darwin) codesign -s - package/bin/wapm @@ -362,9 +371,9 @@ endif package-wasmer: mkdir -p "package/bin" ifeq ($(OS), Windows_NT) - cp target/release/wasmer.exe package/bin/ + cp target/$(TARGET)release/wasmer.exe package/bin/ else - cp target/release/wasmer package/bin/ + cp target/$(TARGET)release/wasmer package/bin/ ifeq ($(UNAME_S), Darwin) codesign -s - package/bin/wasmer endif @@ -377,25 +386,29 @@ package-capi: cp lib/c-api/wasmer_wasm.h* package/include cp lib/c-api/wasm.h* package/include cp lib/c-api/README.md package/include/README.md -ifeq ($(OS), Windows_NT) - cp target/release/wasmer_c_api.dll package/lib/wasmer.dll - cp target/release/wasmer_c_api.lib package/lib/wasmer.lib -else -ifeq ($(UNAME_S), Darwin) + + # Windows + if [ -f target/$(TARGET)release/wasmer_c_api.dll ]; then \ + cp target/$(TARGET)release/wasmer_c_api.dll package/lib/wasmer.dll ;\ + fi + if [ -f target/$(TARGET)release/wasmer_c_api.lib ]; then \ + cp target/$(TARGET)release/wasmer_c_api.lib package/lib/wasmer.lib ;\ + fi + + # Darwin # For some reason in macOS arm64 there are issues if we copy constantly in the install_name_tool util rm -f package/lib/libwasmer.dylib - cp target/release/libwasmer_c_api.dylib package/lib/libwasmer.dylib - cp target/release/libwasmer_c_api.a package/lib/libwasmer.a - # Fix the rpath for the dylib - install_name_tool -id "@rpath/libwasmer.dylib" package/lib/libwasmer.dylib -else - # In some cases the .so may not be available, for example when building against musl (static linking) - if [ -f target/release/libwasmer_c_api.so ]; then \ - cp target/release/libwasmer_c_api.so package/lib/libwasmer.so ;\ - fi; - cp target/release/libwasmer_c_api.a package/lib/libwasmer.a -endif -endif + if [ -f target/$(TARGET)release/libwasmer_c_api.dylib ]; then \ + cp target/$(TARGET)release/libwasmer_c_api.dylib package/lib/libwasmer.dylib ;\ + install_name_tool -id "@rpath/libwasmer.dylib" package/lib/libwasmer.dylib ;\ + fi + + if [ -f target/$(TARGET)release/libwasmer_c_api.so ]; then \ + cp target/$(TARGET)release/libwasmer_c_api.so package/lib/libwasmer.so ;\ + fi + if [ -f target/$(TARGET)release/libwasmer_c_api.a ]; then \ + cp target/$(TARGET)release/libwasmer_c_api.a package/lib/libwasmer.a ;\ + fi package-docs: build-docs build-docs-capi mkdir -p "package/docs" diff --git a/bors.toml b/bors.toml index c84a3a47f74..71ed41f6699 100644 --- a/bors.toml +++ b/bors.toml @@ -2,6 +2,7 @@ status = [ "Audit", "Code lint", "Test on linux-x64", + "Test on linux-musl-x64", "Test on linux-aarch64", "Test on macos-x64", "Test on windows-x64", diff --git a/lib/c-api/build.rs b/lib/c-api/build.rs index 9237be7fd9c..50d96f8026b 100644 --- a/lib/c-api/build.rs +++ b/lib/c-api/build.rs @@ -4,7 +4,10 @@ //! * setting `inline-c` up. use cbindgen::{Builder, Language}; -use std::{env, fs, path::PathBuf}; +use std::{ + env, fs, + path::{Path, PathBuf}, +}; const PRE_HEADER: &'static str = r#" // Define the `ARCH_X86_X64` constant. @@ -556,7 +559,17 @@ fn build_inline_c_env_vars() { } else if cfg!(target_os = "macos") { "libwasmer_c_api.dylib".to_string() } else { - "libwasmer_c_api.so".to_string() + let path = format!( + "{shared_object_dir}/{lib}", + shared_object_dir = shared_object_dir, + lib = "libwasmer_c_api.so" + ); + + if Path::new(path.as_str()).exists() { + "libwasmer_c_api.so".to_string() + } else { + "libwasmer_c_api.a".to_string() + } } ); } diff --git a/lib/c-api/tests/.gitignore b/lib/c-api/tests/.gitignore index 36e000ce2e2..58fbd3c5e8d 100644 --- a/lib/c-api/tests/.gitignore +++ b/lib/c-api/tests/.gitignore @@ -1,6 +1,11 @@ # ignore wasm-c-api binaries wasm-c-api-* test-* +wasm-c-api/example/* # Unignore files ending with `.c` (i.e. `wasm-c-api-wasi.c`) !*.c +!wasm-c-api/example/*.c +!wasm-c-api/example/*.cc +!wasm-c-api/example/*.wasm +!wasm-c-api/example/*.wat