Skip to content

ci(edriver): static musl build for x86_64 and aarch64 #51

ci(edriver): static musl build for x86_64 and aarch64

ci(edriver): static musl build for x86_64 and aarch64 #51

Workflow file for this run

# driver ci build
name: CI - edriver
on:
push:
branches: ["**"]
paths:
- "plugins/edriver/**"
- "SDK/rust/**"
- ".github/workflows/ci-edriver.yaml"
pull_request:
paths:
- "plugins/edriver/**"
- "SDK/rust/**"
- ".github/workflows/ci-edriver.yaml"
jobs:
edriver:
name: "Build and test edriver / ${{ matrix.arch }}"
runs-on: ${{ matrix.runner }}
container:
image: ${{ matrix.container }}
strategy:
fail-fast: false
matrix:
include:
- arch: x86_64
runner: ubuntu-latest
target: x86_64-unknown-linux-musl
# Ubuntu + musl-gcc + vendored-libelf (--without-zstd).
# elfutils ./configure needs argp/fts/obstack, which are absent from
# musl libc. We pre-build them (argp-standalone, musl-fts,
# musl-obstack) using musl-gcc and install to /usr/lib/x86_64-linux-musl
# before running `cargo build`, so configure finds them.
container: ubuntu:24.04
cc: musl-gcc
lib_path: ""
extra_cflags: "-I/usr/include -I/usr/include/x86_64-linux-gnu"
cargo_extra_features: ",vendored-libelf"
rustflags: "-C target-feature=+crt-static"
- arch: aarch64
runner: ubuntu-24.04-arm
target: aarch64-unknown-linux-musl
# Same approach as x86_64. ubuntu:24.04 on arm64 supports JS
# actions; Alpine ARM64 does not (no Node.js ARM64 in Alpine).
container: ubuntu:24.04
cc: musl-gcc
lib_path: ""
extra_cflags: "-I/usr/include -I/usr/include/aarch64-linux-gnu"
cargo_extra_features: ",vendored-libelf"
rustflags: "-C target-feature=+crt-static"
steps:
- name: Install build dependencies
env:
DEBIAN_FRONTEND: noninteractive
run: |
apt-get update -qq
apt-get install -y --no-install-recommends \
bash curl git ca-certificates \
build-essential linux-headers-generic \
clang llvm \
libelf-dev zlib1g-dev \
musl-tools musl-dev \
protobuf-compiler \
pkg-config \
autoconf automake libtool autopoint flex bison gawk
- name: Git checkout
uses: actions/checkout@v4
with:
submodules: true
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
components: rustfmt
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: ${{ matrix.arch }}-cargo-edriver-v8-${{ hashFiles('plugins/edriver/Cargo.lock') }}
restore-keys: ${{ matrix.arch }}-cargo-edriver-v8-
# elfutils ./configure (invoked by libbpf-sys vendored-libelf build.rs)
# runs with CC=musl-gcc. musl libc lacks argp_parse, fts_close, and
# _obstack_free, causing configure to abort. We pre-build the three
# void-linux musl-compat shims (identical to Alpine's argp-standalone,
# musl-fts-dev, musl-obstack-dev packages) and install the .a + headers
# into musl-gcc's default sysroot search path so configure finds them.
- name: Build musl compat libs (argp / fts / obstack)
run: |
set -eux
ARCH=$(uname -m) # x86_64 or aarch64
MUSL_LIB=/usr/lib/${ARCH}-linux-musl
MUSL_INC=/usr/include/${ARCH}-linux-musl
# 1. argp-standalone – provides argp_parse
git clone --depth=1 https://github.com/ericonr/argp-standalone /tmp/argp-standalone
cd /tmp/argp-standalone
autoreconf -fiv
CC=musl-gcc ./configure --enable-static --disable-shared \
--prefix=/usr --libdir=${MUSL_LIB} --includedir=${MUSL_INC}
make -j$(nproc) && make install
# 2. musl-fts – provides fts_close (NetBSD implementation)
git clone --depth=1 https://github.com/void-linux/musl-fts /tmp/musl-fts
cd /tmp/musl-fts
./bootstrap.sh
CC=musl-gcc ./configure --enable-static --disable-shared \
--prefix=/usr --libdir=${MUSL_LIB} --includedir=${MUSL_INC}
make -j$(nproc) && make install
# 3. musl-obstack – provides _obstack_free (from gcc libiberty)
git clone --depth=1 https://github.com/void-linux/musl-obstack /tmp/musl-obstack
cd /tmp/musl-obstack
./bootstrap.sh
CC=musl-gcc ./configure --enable-static --disable-shared \
--prefix=/usr --libdir=${MUSL_LIB} --includedir=${MUSL_INC}
make -j$(nproc) && make install
- name: Verify toolchain
run: |
which protoc && protoc --version
which clang && clang --version | head -1
- name: Build
run: |
export PROTOC=$(which protoc)
cd plugins/edriver && make build
env:
PLATFORM: ${{ matrix.arch }}
LIBBPF_SYS_LIBRARY_PATH: ${{ matrix.lib_path }}
# musl-gcc -nostdinc: re-add system includes for vendored libbpf.
LIBBPF_SYS_EXTRA_CFLAGS: ${{ matrix.extra_cflags }}
CC_x86_64_unknown_linux_musl: ${{ matrix.cc }}
CC_aarch64_unknown_linux_musl: ${{ matrix.cc }}
CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER: ${{ matrix.cc }}
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER: ${{ matrix.cc }}
RUSTFLAGS: ${{ matrix.rustflags }}
CARGO_EXTRA_FEATURES: ${{ matrix.cargo_extra_features }}
- name: Test
run: |
export PROTOC=$(which protoc)
cd plugins/edriver && make test
env:
PLATFORM: ${{ matrix.arch }}
LIBBPF_SYS_LIBRARY_PATH: ${{ matrix.lib_path }}
LIBBPF_SYS_EXTRA_CFLAGS: ${{ matrix.extra_cflags }}
CC_x86_64_unknown_linux_musl: ${{ matrix.cc }}
CC_aarch64_unknown_linux_musl: ${{ matrix.cc }}
CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER: ${{ matrix.cc }}
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER: ${{ matrix.cc }}
RUSTFLAGS: ${{ matrix.rustflags }}
CARGO_EXTRA_FEATURES: ${{ matrix.cargo_extra_features }}