From 79ef484392d6500384a5f67ab65db2fc778f4743 Mon Sep 17 00:00:00 2001 From: ObserverOfTime Date: Sat, 20 Sep 2025 09:38:54 +0300 Subject: [PATCH] ci: cross-compile without cross-rs --- .github/scripts/cross.sh | 3 - .github/scripts/make.sh | 9 -- .github/scripts/tree-sitter.sh | 9 -- .github/workflows/build.yml | 243 ++++++++++++++--------------- .github/workflows/wasm_exports.yml | 6 +- 5 files changed, 116 insertions(+), 154 deletions(-) delete mode 100755 .github/scripts/cross.sh delete mode 100755 .github/scripts/make.sh delete mode 100755 .github/scripts/tree-sitter.sh diff --git a/.github/scripts/cross.sh b/.github/scripts/cross.sh deleted file mode 100755 index de1d4e94..00000000 --- a/.github/scripts/cross.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -eu - -exec docker run --rm -v /home/runner:/home/runner -w "$PWD" "$CROSS_IMAGE" "$@" diff --git a/.github/scripts/make.sh b/.github/scripts/make.sh deleted file mode 100755 index 175074f9..00000000 --- a/.github/scripts/make.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -eu - -tree_sitter="$ROOT"/target/"$TARGET"/release/tree-sitter - -if [[ $BUILD_CMD == cross ]]; then - cross.sh make CC="$CC" AR="$AR" "$@" -else - exec make "$@" -fi diff --git a/.github/scripts/tree-sitter.sh b/.github/scripts/tree-sitter.sh deleted file mode 100755 index 125a2d92..00000000 --- a/.github/scripts/tree-sitter.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -eu - -tree_sitter="$ROOT"/target/"$TARGET"/release/tree-sitter - -if [[ $BUILD_CMD == cross ]]; then - cross.sh "$CROSS_RUNNER" "$tree_sitter" "$@" -else - exec "$tree_sitter" "$@" -fi diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d0135df8..62b45485 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,10 +1,5 @@ name: Build & Test -env: - CARGO_TERM_COLOR: always - RUSTFLAGS: "-D warnings" - CROSS_DEBUG: 1 - on: workflow_call: inputs: @@ -31,39 +26,41 @@ jobs: - windows-x86 - macos-arm64 - macos-x64 + - wasm32 include: # When adding a new `target`: # 1. Define a new platform alias above - # 2. Add a new record to the matrix map in `cli/npm/install.js` - - { platform: linux-arm64 , target: aarch64-unknown-linux-gnu , os: ubuntu-24.04-arm , features: wasm } - - { platform: linux-arm , target: armv7-unknown-linux-gnueabihf , os: ubuntu-latest , use-cross: true } - - { platform: linux-x64 , target: x86_64-unknown-linux-gnu , os: ubuntu-22.04 , features: wasm } - - { platform: linux-x86 , target: i686-unknown-linux-gnu , os: ubuntu-latest , use-cross: true } - - { platform: linux-powerpc64 , target: powerpc64-unknown-linux-gnu , os: ubuntu-latest , use-cross: true } - - { platform: windows-arm64 , target: aarch64-pc-windows-msvc , os: windows-latest } - - { platform: windows-x64 , target: x86_64-pc-windows-msvc , os: windows-latest , features: wasm } - - { platform: windows-x86 , target: i686-pc-windows-msvc , os: windows-latest } - - { platform: macos-arm64 , target: aarch64-apple-darwin , os: macos-latest , features: wasm } - - { platform: macos-x64 , target: x86_64-apple-darwin , os: macos-13 , features: wasm } - - { platform: wasm32 , target: wasm32-unknown-unknown , os: ubuntu-latest , no-run: true } + # 2. Add a new record to the matrix map in `crates/cli/npm/install.js` + - { platform: linux-arm64 , target: aarch64-unknown-linux-gnu , os: ubuntu-24.04-arm } + - { platform: linux-arm , target: armv7-unknown-linux-gnueabihf , os: ubuntu-24.04-arm } + - { platform: linux-x64 , target: x86_64-unknown-linux-gnu , os: ubuntu-24.04 } + - { platform: linux-x86 , target: i686-unknown-linux-gnu , os: ubuntu-24.04 } + - { platform: linux-powerpc64 , target: powerpc64-unknown-linux-gnu , os: ubuntu-24.04 } + - { platform: windows-arm64 , target: aarch64-pc-windows-msvc , os: windows-11-arm } + - { platform: windows-x64 , target: x86_64-pc-windows-msvc , os: windows-2025 } + - { platform: windows-x86 , target: i686-pc-windows-msvc , os: windows-2025 } + - { platform: macos-arm64 , target: aarch64-apple-darwin , os: macos-15 } + - { platform: macos-x64 , target: x86_64-apple-darwin , os: macos-13 } + - { platform: wasm32 , target: wasm32-unknown-unknown , os: ubuntu-24.04 } - # Cross compilers for C library - - { platform: linux-arm64 , cc: aarch64-linux-gnu-gcc , ar: aarch64-linux-gnu-ar } - - { platform: linux-arm , cc: arm-linux-gnueabihf-gcc , ar: arm-linux-gnueabihf-ar } - - { platform: linux-x86 , cc: i686-linux-gnu-gcc , ar: i686-linux-gnu-ar } - - { platform: linux-powerpc64 , cc: powerpc64-linux-gnu-gcc , ar: powerpc64-linux-gnu-ar } + # Extra features + - { platform: linux-arm64 , features: wasm } + - { platform: linux-x64 , features: wasm } + - { platform: macos-arm64 , features: wasm } + - { platform: macos-x64 , features: wasm } - # Prevent race condition (see #2041) - - { platform: windows-x64 , rust-test-threads: 1 } - - { platform: windows-x86 , rust-test-threads: 1 } + # Cross-compilation + - { platform: linux-arm , cross: true } + - { platform: linux-x86 , cross: true } + - { platform: linux-powerpc64 , cross: true } - # Can't natively run CLI on Github runner's host - - { platform: windows-arm64 , no-run: true } + # Compile-only + - { platform: wasm32 , no-run: true } env: - BUILD_CMD: cargo - SUFFIX: ${{ contains(matrix.target, 'windows') && '.exe' || '' }} + CARGO_TERM_COLOR: always + RUSTFLAGS: -D warnings defaults: run: @@ -73,11 +70,28 @@ jobs: - name: Checkout repository uses: actions/checkout@v5 - - name: Read Emscripten version - run: printf 'EMSCRIPTEN_VERSION=%s\n' "$(> $GITHUB_ENV + - name: Set up environment + run: | + printf 'EMSCRIPTEN_VERSION=%s\n' "$(> $GITHUB_ENV + + if [[ '${{ matrix.platform }}' =~ ^windows ]]; then + # Prevent race condition (see #2041) + printf 'RUST_TEST_THREADS=1\n' >> $GITHUB_ENV + elif [[ '${{ matrix.cross }}' == true ]]; then + for target in armv7-unknown-linux-gnueabihf i686-unknown-linux-gnu powerpc64-unknown-linux-gnu; do + camel_target=${target//-/_}; target_cc=${target/-unknown/} + printf 'CC_%s=%s\n' "$camel_target" "${target_cc/v7/}-gcc" + printf 'AR_%s=%s\n' "$camel_target" "${target_cc/v7/}-ar" + printf 'CARGO_TARGET_%s_LINKER=%s\n' "${camel_target^^}" "${target_cc/v7/}-gcc" + done >> $GITHUB_ENV + { + printf 'CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUNNER=qemu-arm -L /usr/arm-linux-gnueabihf\n' + printf 'CARGO_TARGET_POWERPC64_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc64 -L /usr/powerpc64-linux-gnu\n' + } >> $GITHUB_ENV + fi - name: Install Emscripten - if: ${{ !matrix.no-run && !matrix.use-cross }} + if: contains(matrix.features, 'wasm') uses: mymindstorm/setup-emsdk@v14 with: version: ${{ env.EMSCRIPTEN_VERSION }} @@ -87,63 +101,35 @@ jobs: with: target: ${{ matrix.target }} - - name: Install cross - if: ${{ matrix.use-cross }} + - name: Install cross-compilation toolchain + if: matrix.cross run: | - if [ ! -x "$(command -v cross)" ]; then - # TODO: Remove 'RUSTFLAGS=""' once https://github.com/cross-rs/cross/issues/1561 is resolved - RUSTFLAGS="" cargo install cross --git https://github.com/cross-rs/cross + sudo apt-get update -qy + if [[ $PLATFORM == linux-arm ]]; then + sudo apt-get install -qy {binutils,gcc}-arm-linux-gnueabihf qemu-user + elif [[ $PLATFORM == linux-x86 ]]; then + sudo apt-get install -qy {binutils,gcc}-i686-linux-gnu + elif [[ $PLATFORM == linux-powerpc64 ]]; then + sudo apt-get install -qy {binutils,gcc}-powerpc64-linux-gnu qemu-user fi - - - name: Configure cross - if: ${{ matrix.use-cross }} - run: | - printf '%s\n' > Cross.toml \ - '[target.${{ matrix.target }}]' \ - 'image = "ghcr.io/cross-rs/${{ matrix.target }}:edge"' \ - '[build]' \ - 'pre-build = [' \ - ' "dpkg --add-architecture $CROSS_DEB_ARCH",' \ - ' "curl -fsSL https://deb.nodesource.com/setup_22.x | bash -",' \ - ' "apt-get update && apt-get -y install libssl-dev nodejs"' \ - ']' - cat - Cross.toml <<< 'Cross.toml:' - printf '%s\n' >> $GITHUB_ENV \ - "CROSS_CONFIG=$PWD/Cross.toml" \ - "CROSS_IMAGE=ghcr.io/cross-rs/${{ matrix.target }}:edge" - - - name: Set up environment env: - RUST_TEST_THREADS: ${{ matrix.rust-test-threads }} - USE_CROSS: ${{ matrix.use-cross }} - TARGET: ${{ matrix.target }} - CC: ${{ matrix.cc }} - AR: ${{ matrix.ar }} - run: | - PATH="$PWD/.github/scripts:$PATH" - printf '%s/.github/scripts\n' "$PWD" >> $GITHUB_PATH + PLATFORM: ${{ matrix.platform }} - printf '%s\n' >> $GITHUB_ENV \ - 'TREE_SITTER=tree-sitter.sh' \ - "TARGET=$TARGET" \ - "ROOT=$PWD" - - [[ -n $RUST_TEST_THREADS ]] && \ - printf 'RUST_TEST_THREADS=%s\n' "$RUST_TEST_THREADS" >> $GITHUB_ENV - - [[ -n $CC ]] && printf 'CC=%s\n' "$CC" >> $GITHUB_ENV - [[ -n $AR ]] && printf 'AR=%s\n' "$AR" >> $GITHUB_ENV - - if [[ $USE_CROSS == true ]]; then - printf 'BUILD_CMD=cross\n' >> $GITHUB_ENV - runner=$(cross.sh bash -c "env | sed -n 's/^CARGO_TARGET_.*_RUNNER=//p'") - [[ -n $runner ]] && printf 'CROSS_RUNNER=%s\n' "$runner" >> $GITHUB_ENV - fi + - name: Install MinGW and Clang (Windows x64 MSYS2) + if: matrix.platform == 'windows-x64' + uses: msys2/setup-msys2@v2 + with: + update: true + install: | + mingw-w64-x86_64-toolchain + mingw-w64-x86_64-clang + mingw-w64-x86_64-make + mingw-w64-x86_64-cmake # TODO: Remove RUSTFLAGS="--cap-lints allow" once we use a wasmtime release that addresses # the `mismatched-lifetime-syntaxes` lint - name: Build wasmtime library (Windows x64 MSYS2) - if: ${{ !matrix.use-cross && contains(matrix.features, 'wasm') && matrix.platform == 'windows-x64' }} + if: contains(matrix.features, 'wasm') && matrix.platform == 'windows-x64' run: | mkdir -p target WASMTIME_VERSION=$(cargo metadata --format-version=1 --locked --features wasm | \ @@ -159,21 +145,10 @@ jobs: printf 'CMAKE_PREFIX_PATH=%s\n' "$PWD/artifacts" >> $GITHUB_ENV env: WASMTIME_REPO: https://github.com/bytecodealliance/wasmtime - RUSTFLAGS: "--cap-lints allow" - - - name: Install MinGW and Clang (Windows x64 MSYS2) - if: ${{ matrix.platform == 'windows-x64' }} - uses: msys2/setup-msys2@v2 - with: - update: true - install: | - mingw-w64-x86_64-toolchain - mingw-w64-x86_64-clang - mingw-w64-x86_64-make - mingw-w64-x86_64-cmake + RUSTFLAGS: ${{ env.RUSTFLAGS }} --cap-lints allow - name: Build C library (Windows x64 MSYS2 CMake) - if: ${{ matrix.platform == 'windows-x64' }} + if: matrix.platform == 'windows-x64' shell: msys2 {0} run: | cmake -G Ninja -S . -B build/static \ @@ -183,7 +158,6 @@ jobs: -DTREE_SITTER_FEATURE_WASM=$WASM \ -DCMAKE_C_COMPILER=clang cmake --build build/static - rm -rf build/static cmake -G Ninja -S . -B build/shared \ -DBUILD_SHARED_LIBS=ON \ @@ -192,14 +166,17 @@ jobs: -DTREE_SITTER_FEATURE_WASM=$WASM \ -DCMAKE_C_COMPILER=clang cmake --build build/shared - rm -rf build/shared + rm -rf \ + build/{static,shared} \ + "${CMAKE_PREFIX_PATH}/artifacts" \ + target/wasmtime-${WASMTIME_VERSION} env: WASM: ${{ contains(matrix.features, 'wasm') && 'ON' || 'OFF' }} # TODO: Remove RUSTFLAGS="--cap-lints allow" once we use a wasmtime release that addresses # the `mismatched-lifetime-syntaxes` lint - name: Build wasmtime library - if: ${{ !matrix.use-cross && contains(matrix.features, 'wasm') }} + if: contains(matrix.features, 'wasm') run: | mkdir -p target WASMTIME_VERSION=$(cargo metadata --format-version=1 --locked --features wasm | \ @@ -215,16 +192,27 @@ jobs: printf 'CMAKE_PREFIX_PATH=%s\n' "$PWD/artifacts" >> $GITHUB_ENV env: WASMTIME_REPO: https://github.com/bytecodealliance/wasmtime - RUSTFLAGS: "--cap-lints allow" + RUSTFLAGS: ${{ env.RUSTFLAGS }} --cap-lints allow - name: Build C library (make) - if: ${{ runner.os != 'Windows' }} - run: make.sh -j CFLAGS="$CFLAGS" + if: runner.os != 'Windows' + run: | + if [[ $PLATFORM == linux-arm ]]; then + CC=arm-linux-gnueabihf-gcc; AR=arm-linux-gnueabihf-ar + elif [[ $PLATFORM == linux-x86 ]]; then + CC=i686-linux-gnu-gcc; AR=i686-linux-gnu-ar + elif [[ $PLATFORM == linux-powerpc64 ]]; then + CC=powerpc64-linux-gnu-gcc; AR=powerpc64-linux-gnu-ar + else + CC=gcc; AR=ar + fi + make -j CFLAGS="$CFLAGS" CC=$CC AR=$AR env: + PLATFORM: ${{ matrix.platform }} CFLAGS: -g -Werror -Wall -Wextra -Wshadow -Wpedantic -Werror=incompatible-pointer-types - name: Build C library (CMake) - if: ${{ !matrix.use-cross }} + if: "!matrix.cross" run: | cmake -S . -B build/static \ -DBUILD_SHARED_LIBS=OFF \ @@ -240,12 +228,11 @@ jobs: -DTREE_SITTER_FEATURE_WASM=$WASM cmake --build build/shared --verbose env: - CC: ${{ contains(matrix.target, 'linux') && 'clang' || '' }} + CC: ${{ contains(matrix.platform, 'linux') && 'clang' || '' }} WASM: ${{ contains(matrix.features, 'wasm') && 'ON' || 'OFF' }} - - name: Build wasm library - # No reason to build on the same Github runner hosts many times - if: ${{ !matrix.no-run && !matrix.use-cross }} + - name: Build Wasm library + if: contains(matrix.features, 'wasm') shell: bash run: | cd lib/binding_web @@ -256,56 +243,52 @@ jobs: npm run build:debug - name: Check no_std builds - if: ${{ !matrix.no-run && inputs.run-test }} + if: inputs.run-test && !matrix.no-run + working-directory: lib shell: bash - run: | - cd lib - $BUILD_CMD check --no-default-features --target=${{ matrix.target }} + run: cargo check --no-default-features --target='${{ matrix.target }}' - name: Build target - run: | - PACKAGE="" - if [[ "${{ matrix.target }}" == "wasm32-unknown-unknown" ]]; then - PACKAGE="-p tree-sitter" - fi - $BUILD_CMD build --release --target=${{ matrix.target }} --features=${{ matrix.features }} $PACKAGE + run: cargo build --release --target='${{ matrix.target }}' --features='${{ matrix.features }}' $PACKAGE + env: + PACKAGE: ${{ matrix.platform == 'wasm32' && '-p tree-sitter' || '' }} - name: Cache fixtures id: cache - if: ${{ !matrix.no-run && inputs.run-test }} + if: inputs.run-test && !matrix.no-run uses: ./.github/actions/cache - name: Fetch fixtures - if: ${{ !matrix.no-run && inputs.run-test }} - run: $BUILD_CMD run -p xtask --target=${{ matrix.target }} -- fetch-fixtures + if: inputs.run-test && !matrix.no-run + run: cargo run -p xtask --target='${{ matrix.target }}' -- fetch-fixtures - name: Generate fixtures - if: ${{ !matrix.no-run && inputs.run-test && steps.cache.outputs.cache-hit != 'true' }} - run: $BUILD_CMD run -p xtask --target=${{ matrix.target }} -- generate-fixtures + if: inputs.run-test && !matrix.no-run && steps.cache.outputs.cache-hit != 'true' + run: cargo run -p xtask --target='${{ matrix.target }}' -- generate-fixtures - name: Generate Wasm fixtures - if: ${{ !matrix.no-run && !matrix.use-cross && inputs.run-test && steps.cache.outputs.cache-hit != 'true' }} - run: $BUILD_CMD run -p xtask --target=${{ matrix.target }} -- generate-fixtures --wasm + if: inputs.run-test && !matrix.no-run && contains(matrix.features, 'wasm') && steps.cache.outputs.cache-hit != 'true' + run: cargo run -p xtask --target='${{ matrix.target }}' -- generate-fixtures --wasm - name: Run main tests - if: ${{ !matrix.no-run && inputs.run-test }} - run: $BUILD_CMD test --target=${{ matrix.target }} --features=${{ matrix.features }} + if: inputs.run-test && !matrix.no-run + run: cargo test --target='${{ matrix.target }}' --features='${{ matrix.features }}' - - name: Run wasm tests - if: ${{ !matrix.no-run && !matrix.use-cross && inputs.run-test }} - run: $BUILD_CMD run -p xtask --target=${{ matrix.target }} -- test-wasm + - name: Run Wasm tests + if: inputs.run-test && !matrix.no-run && contains(matrix.features, 'wasm') + run: cargo run -p xtask --target='${{ matrix.target }}' -- test-wasm - name: Upload CLI artifact - if: ${{ matrix.platform != 'wasm32' }} + if: "!matrix.no-run" uses: actions/upload-artifact@v4 with: name: tree-sitter.${{ matrix.platform }} - path: target/${{ matrix.target }}/release/tree-sitter${{ env.SUFFIX }} + path: target/${{ matrix.target }}/release/tree-sitter${{ contains(matrix.target, 'windows') && '.exe' || '' }} if-no-files-found: error retention-days: 7 - name: Upload Wasm artifacts - if: ${{ matrix.platform == 'linux-x64' }} + if: matrix.platform == 'linux-x64' uses: actions/upload-artifact@v4 with: name: tree-sitter.wasm diff --git a/.github/workflows/wasm_exports.yml b/.github/workflows/wasm_exports.yml index ee28e8ea..d04e1052 100644 --- a/.github/workflows/wasm_exports.yml +++ b/.github/workflows/wasm_exports.yml @@ -1,4 +1,4 @@ -name: Check WASM Exports +name: Check Wasm Exports on: pull_request: @@ -33,9 +33,9 @@ jobs: env: CFLAGS: -g -Werror -Wall -Wextra -Wshadow -Wpedantic -Werror=incompatible-pointer-types - - name: Build WASM Library + - name: Build Wasm Library working-directory: lib/binding_web run: npm ci && npm run build:debug - - name: Check WASM exports + - name: Check Wasm exports run: cargo xtask check-wasm-exports