From 52d85d7d21aee4551a273179c40d12234951913f Mon Sep 17 00:00:00 2001 From: jucasoliveira Date: Thu, 16 Apr 2026 09:26:12 +0100 Subject: [PATCH 1/2] Fix aarch64 build failure and align CI targets with release matrix The previous approach of removing libzstd*.dylib broke llvm-config, which itself dynamically links to zstd. Instead, copy only libzstd.a to an isolated directory (/tmp/zstd-static) and point the linker there first, so it picks the static archive without disturbing LLVM tools. Also adds a post-build otool check to verify no dynamic zstd reference remains, and updates CI to test all release targets (adds ubuntu-arm and libzstd-dev, switches from os-only matrix to target-based matrix). Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/ci.yml | 16 ++++++++++----- .github/workflows/release.yml | 37 +++++++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9bc9835..422afb2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,14 +27,20 @@ env: jobs: test: - name: Test (${{ matrix.os }}) + name: Test (${{ matrix.target }}) runs-on: ${{ matrix.os }} # Limit job execution time to prevent resource abuse timeout-minutes: 30 strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + include: + - target: x86_64-unknown-linux-gnu + os: ubuntu-latest + - target: aarch64-unknown-linux-gnu + os: ubuntu-24.04-arm + - target: aarch64-apple-darwin + os: macos-latest steps: - name: Checkout repository @@ -53,7 +59,7 @@ jobs: wget -qO- https://apt.llvm.org/llvm.sh -O llvm.sh chmod +x llvm.sh sudo ./llvm.sh 18 - sudo apt-get install -y libpolly-18-dev + sudo apt-get install -y libzstd-dev libpolly-18-dev echo "LLVM_SYS_180_PREFIX=/usr/lib/llvm-18" >> $GITHUB_ENV - name: Install LLVM 18 (macOS) @@ -69,9 +75,9 @@ jobs: ~/.cargo/registry ~/.cargo/git target - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + key: ${{ matrix.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }} restore-keys: | - ${{ runner.os }}-cargo- + ${{ matrix.os }}-${{ matrix.target }}-cargo- - name: Build run: cargo build --release diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 85cf9fa..0086270 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -122,30 +122,37 @@ jobs: # Remove arm64 zstd to prevent linker from finding it sudo rm -rf /opt/homebrew/opt/zstd - # Remove dynamic zstd libs from x86_64 install so the linker uses the static archive, - # preventing a runtime dependency on libzstd.1.dylib - rm -f /usr/local/opt/zstd/lib/libzstd*.dylib + # Copy only the static zstd archive to an isolated directory. + # The linker will find libzstd.a here (no .dylib), producing a + # self-contained binary without a runtime dependency on libzstd.1.dylib. + # We cannot remove the original .dylib because llvm-config needs it. + mkdir -p /tmp/zstd-static + cp /usr/local/opt/zstd/lib/libzstd.a /tmp/zstd-static/ export MACOSX_DEPLOYMENT_TARGET=14.0 # Use x86_64 clang wrapper so the linker runs as x86_64 and picks up x86_64 libs export CARGO_TARGET_X86_64_APPLE_DARWIN_LINKER=/usr/local/bin/clang-x86_64 - # Ensure the linker sees the x86_64 zstd and llvm libs - export LIBRARY_PATH="/usr/local/opt/zstd/lib:/usr/local/opt/llvm@18/lib" - export CARGO_TARGET_X86_64_APPLE_DARWIN_RUSTFLAGS="-C link-arg=-arch -C link-arg=x86_64 -C link-arg=-L/usr/local/opt/zstd/lib -C link-arg=-L/usr/local/opt/llvm@18/lib -C link-arg=-mmacosx-version-min=14.0" + # Point to static-only dir first so linker prefers libzstd.a over the .dylib + export LIBRARY_PATH="/tmp/zstd-static:/usr/local/opt/llvm@18/lib" + export CARGO_TARGET_X86_64_APPLE_DARWIN_RUSTFLAGS="-C link-arg=-arch -C link-arg=x86_64 -C link-arg=-L/tmp/zstd-static -C link-arg=-L/usr/local/opt/llvm@18/lib -C link-arg=-mmacosx-version-min=14.0" cargo build --release --target ${{ matrix.target }} - name: Build release binary (aarch64 macOS) if: matrix.target == 'aarch64-apple-darwin' run: | - # Remove dynamic zstd libs so the linker uses the static archive, - # preventing a runtime dependency on /opt/homebrew/opt/zstd/lib/libzstd.1.dylib - rm -f /opt/homebrew/opt/zstd/lib/libzstd*.dylib + # Copy only the static zstd archive to an isolated directory. + # The linker will find libzstd.a here (no .dylib), producing a + # self-contained binary without a runtime dependency on libzstd.1.dylib. + # We cannot remove the original .dylib because llvm-config needs it. + mkdir -p /tmp/zstd-static + cp /opt/homebrew/opt/zstd/lib/libzstd.a /tmp/zstd-static/ export MACOSX_DEPLOYMENT_TARGET=14.0 - export LIBRARY_PATH="/opt/homebrew/opt/zstd/lib:/opt/homebrew/opt/llvm@18/lib" + export LIBRARY_PATH="/tmp/zstd-static:/opt/homebrew/opt/llvm@18/lib" + export CARGO_TARGET_AARCH64_APPLE_DARWIN_RUSTFLAGS="-L /tmp/zstd-static" cargo build --release --target ${{ matrix.target }} @@ -161,6 +168,16 @@ jobs: if: runner.os == 'Linux' run: strip target/${{ matrix.target }}/release/${{ matrix.artifact_name }} + - name: Verify no dynamic zstd dependency (macOS) + if: runner.os == 'macOS' + run: | + if otool -L target/${{ matrix.target }}/release/${{ matrix.artifact_name }} | grep -q libzstd; then + echo "ERROR: binary still dynamically links to libzstd" >&2 + otool -L target/${{ matrix.target }}/release/${{ matrix.artifact_name }} + exit 1 + fi + echo "OK: no dynamic zstd dependency" + - name: Strip binary (macOS) if: runner.os == 'macOS' run: strip target/${{ matrix.target }}/release/${{ matrix.artifact_name }} From b7f21b98f67248837acf46fc4f96cf4397fd3945 Mon Sep 17 00:00:00 2001 From: jucasoliveira Date: Thu, 16 Apr 2026 09:32:02 +0100 Subject: [PATCH 2/2] Add macOS targets for x86_64 and aarch64 in CI matrix --- .github/workflows/ci.yml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 422afb2..393f0ba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,12 +35,25 @@ jobs: fail-fast: false matrix: include: + - target: x86_64-apple-darwin + os: macos-latest + artifact_name: oitec + asset_name: oitec-x86_64-apple-darwin + + - target: aarch64-apple-darwin + os: macos-latest + artifact_name: oitec + asset_name: oitec-aarch64-apple-darwin + - target: x86_64-unknown-linux-gnu os: ubuntu-latest + artifact_name: oitec + asset_name: oitec-x86_64-unknown-linux-gnu + - target: aarch64-unknown-linux-gnu os: ubuntu-24.04-arm - - target: aarch64-apple-darwin - os: macos-latest + artifact_name: oitec + asset_name: oitec-aarch64-unknown-linux-gnu steps: - name: Checkout repository