ci: add build/unit-test coverage for armv7 (#42386)

arm64 hosts support running armv7 (armhf) binaries, so we can
cross compile and run the unit tests without performance issues.

armv7 (armhf) is a primary architecture on Ubuntu, so build
regressions block new version updates, and adding coverage
helps to avoid introducing regressions.
This commit is contained in:
Luca Boccassi
2026-06-02 13:15:50 +01:00
committed by GitHub
11 changed files with 153 additions and 37 deletions

21
.github/workflows/armhf-clang.cross vendored Normal file
View File

@@ -0,0 +1,21 @@
[binaries]
c = ['clang', '--target=arm-linux-gnueabihf']
cpp = ['clang++', '--target=arm-linux-gnueabihf']
ar = 'arm-linux-gnueabihf-ar'
nm = 'arm-linux-gnueabihf-nm'
strip = 'arm-linux-gnueabihf-strip'
pkgconfig = 'pkg-config'
[properties]
needs_exe_wrapper = false
pkg_config_libdir = '/usr/lib/arm-linux-gnueabihf/pkgconfig:/usr/share/pkgconfig'
c_args = ['-O2', '-pipe', '-g', '-feliminate-unused-debug-types']
c_link_args = ['-fuse-ld=bfd', '-Wl,-O1', '-Wl,--hash-style=gnu', '-Wl,--as-needed', '-Wl,-z,relro,-z,now,-z,noexecstack']
cpp_args = []
cpp_link_args = ['-fuse-ld=bfd', '-Wl,-O1', '-Wl,--hash-style=gnu', '-Wl,--as-needed', '-Wl,-z,relro,-z,now,-z,noexecstack']
[host_machine]
system = 'linux'
cpu_family = 'arm'
cpu = 'armv7'
endian = 'little'

21
.github/workflows/armhf-gcc.cross vendored Normal file
View File

@@ -0,0 +1,21 @@
[binaries]
c = 'arm-linux-gnueabihf-gcc'
cpp = 'arm-linux-gnueabihf-g++'
ar = 'arm-linux-gnueabihf-gcc-ar'
nm = 'arm-linux-gnueabihf-gcc-nm'
strip = 'arm-linux-gnueabihf-strip'
pkgconfig = 'pkg-config'
[properties]
needs_exe_wrapper = false
pkg_config_libdir = '/usr/lib/arm-linux-gnueabihf/pkgconfig:/usr/share/pkgconfig'
c_args = ['-O2', '-pipe', '-g', '-feliminate-unused-debug-types']
c_link_args = ['-fuse-ld=bfd', '-Wl,-O1', '-Wl,--hash-style=gnu', '-Wl,--as-needed', '-Wl,-z,relro,-z,now,-z,noexecstack']
cpp_args = []
cpp_link_args = ['-fuse-ld=bfd', '-Wl,-O1', '-Wl,--hash-style=gnu', '-Wl,--as-needed', '-Wl,-z,relro,-z,now,-z,noexecstack']
[host_machine]
system = 'linux'
cpu_family = 'arm'
cpu = 'armv7'
endian = 'little'

View File

@@ -19,6 +19,7 @@ ARGS=(
"-Db_ndebug=true"
"--auto-features=disabled -Dcompat-mutable-uid-boundaries=true"
)
# Packages that are always native (i.e.: tools that run on the host) go in this list
PACKAGES=(
cryptsetup-bin
expect
@@ -28,6 +29,26 @@ PACKAGES=(
isc-dhcp-client
itstool
kbd
linux-tools-generic
mold
mount
net-tools
python3-evdev
python3-jinja2
python3-lxml
python3-pefile
python3-pip
python3-pyelftools
python3-pyparsing
python3-setuptools
quota
strace
unifont
util-linux
zstd
)
# Packages that are needed for the target architecture (i.e.: libraries) go in this list
DEVEL_PACKAGES=(
libarchive-dev
libblkid-dev
libbpf-dev
@@ -47,38 +68,48 @@ PACKAGES=(
libxkbcommon-dev
libxtables-dev
libzstd-dev
linux-tools-generic
mold
mount
net-tools
python3-evdev
python3-jinja2
python3-lxml
python3-pefile
python3-pip
python3-pyelftools
python3-pyparsing
python3-setuptools
quota
strace
unifont
util-linux
zstd
)
FEATURES=()
COMPILER="${COMPILER:?}"
COMPILER_VERSION="${COMPILER_VERSION:?}"
LINKER="${LINKER:?}"
RELEASE="$(lsb_release -cs)"
CROSS_ARCH="${CROSS_ARCH:-}"
CROSS_FILE=()
if [ "$(uname -m)" = "aarch64" ] || [ "$(uname -m)" = "x86_64" ]; then
PACKAGES+=(libxen-dev)
if [[ -z "$CROSS_ARCH" ]] && [[ "$(uname -m)" =~ ^(aarch64|x86_64)$ ]]; then
DEVEL_PACKAGES+=(libxen-dev)
fi
# If CROSS_ARCH is set, append :<arch> to the packages so they get installed for the target
PACKAGES+=("${DEVEL_PACKAGES[@]/%/${CROSS_ARCH:+:$CROSS_ARCH}}")
# Note: As we use postfixed clang/gcc binaries, we need to override $AR
# as well, otherwise meson falls back to ar from binutils which
# doesn't work with LTO
if [[ "$COMPILER" == clang ]]; then
if [[ -n "$CROSS_ARCH" ]]; then
if [[ "$COMPILER" != gcc ]]; then
fatal "$CROSS_ARCH cross builds are only supported with gcc"
fi
case "$CROSS_ARCH" in
armhf)
triplet=arm-linux-gnueabihf
;;
*)
fatal "Unsupported cross architecture: $CROSS_ARCH"
;;
esac
CC="$triplet-gcc"
CXX="$triplet-g++"
AR="$triplet-gcc-ar"
CFLAGS="-Wno-maybe-uninitialized"
CXXFLAGS=""
CROSS_FILE=(--cross-file ".github/workflows/$CROSS_ARCH-gcc.cross")
FEATURES+=(-Ddbus-interfaces-dir=no -Dsbat-distro=)
PACKAGES+=("crossbuild-essential-$CROSS_ARCH")
elif [[ "$COMPILER" == clang ]]; then
CC="clang-$COMPILER_VERSION"
CXX="clang++-$COMPILER_VERSION"
AR="llvm-ar-$COMPILER_VERSION"
@@ -142,8 +173,11 @@ else
sudo sed -i "s/Types: deb/Types: deb deb-src/g" "$f"
done
fi
if [[ -n "$CROSS_ARCH" ]]; then
sudo dpkg --add-architecture "$CROSS_ARCH"
fi
sudo apt-get -y update
sudo apt-get -y build-dep systemd
sudo apt-get -y build-dep systemd ${CROSS_ARCH:+--host-architecture=$CROSS_ARCH}
sudo apt-get -y install "${PACKAGES[@]}"
# Install more or less recent meson and ninja with pip, since the distro versions don't
# always support all the features we need (like --optimization=). Since the build-dep
@@ -179,6 +213,7 @@ for args in "${ARGS[@]}"; do
-Dtests=unsafe -Dslow-tests=true -Dfuzz-tests=true --werror \
-Dnobody-group=nogroup -Ddebug=false \
"${FEATURES[@]}" \
"${CROSS_FILE[@]}" \
$args build; then
cat build/meson-logs/meson-log.txt

View File

@@ -39,6 +39,9 @@ jobs:
- env: { COMPILER: "gcc", COMPILER_VERSION: "13", LINKER: "mold" }
runner: [ ubuntu-24.04-arm ]
python-version: ''
- env: { COMPILER: "gcc", COMPILER_VERSION: "13", LINKER: "bfd", CROSS_ARCH: "armhf" }
runner: [ ubuntu-24.04-arm ]
python-version: ''
- env: { COMPILER: "clang", COMPILER_VERSION: "18", LINKER: "lld" }
runner: [ ubuntu-24.04-s390x ]
python-version: ''

View File

@@ -3,11 +3,23 @@
# shellcheck disable=SC2206
PHASES=(${@:-SETUP RUN RUN_ASAN_UBSAN CLEANUP})
# Packages that are always native (i.e.: tools that run on the host) go in this list
ADDITIONAL_DEPS=(
clang
expect
fdisk
jekyll
linux-tools-generic
python3-libevdev
python3-pip
python3-pyelftools
python3-pyparsing
python3-pytest
rpm
zstd
)
# Packages that are needed for the target architecture (i.e.: libraries) go in this list
ADDITIONAL_TARGET_DEPS=(
libbpf-dev
libfdisk-dev
libfido2-dev
@@ -18,15 +30,8 @@ ADDITIONAL_DEPS=(
libtss2-dev
libxkbcommon-dev
libzstd-dev
linux-tools-generic
python3-libevdev
python3-pip
python3-pyelftools
python3-pyparsing
python3-pytest
rpm
zstd
)
CROSS_ARCH="${CROSS_ARCH:-}"
function info() {
echo -e "\033[33;1m$1\033[0m"
@@ -48,6 +53,12 @@ if [ "$(uname -m)" = "aarch64" ] || [ "$(uname -m)" = "x86_64" ]; then
ADDITIONAL_DEPS+=(systemd-boot-efi)
fi
if [[ -n "$CROSS_ARCH" ]]; then
ADDITIONAL_DEPS+=(crossbuild-essential-$CROSS_ARCH)
fi
# Append :<arch> to the packages so they get installed for the target
ADDITIONAL_DEPS+=("${ADDITIONAL_TARGET_DEPS[@]/%/${CROSS_ARCH:+:$CROSS_ARCH}}")
# (Re)set the current oom-{score-}adj. For some reason root on GH actions is able to _decrease_
# its oom-score even after dropping all capabilities (including CAP_SYS_RESOURCE), until the
# score is explicitly changed after sudo. No idea what's going on, but it breaks
@@ -64,8 +75,11 @@ for phase in "${PHASES[@]}"; do
for f in /etc/apt/sources.list.d/*.sources; do
sed -i "s/Types: deb/Types: deb deb-src/g" "$f"
done
if [[ -n "$CROSS_ARCH" ]]; then
dpkg --add-architecture "$CROSS_ARCH"
fi
apt-get -y update
apt-get -y build-dep systemd
apt-get -y build-dep systemd ${CROSS_ARCH:+--host-architecture=$CROSS_ARCH}
apt-get -y install "${ADDITIONAL_DEPS[@]}"
pip3 install -r .github/workflows/requirements.txt --require-hashes --break-system-packages
@@ -99,6 +113,14 @@ for phase in "${PHASES[@]}"; do
fi
fi
if [[ -n "$CROSS_ARCH" ]]; then
if [[ "$phase" =~ ^RUN_GCC ]]; then
MESON_ARGS+=(-Ddbus-interfaces-dir=no -Dsbat-distro= --cross-file ".github/workflows/$CROSS_ARCH-gcc.cross")
elif [[ "$phase" =~ ^RUN_CLANG ]]; then
MESON_ARGS+=(-Dbpf-framework=disabled -Dbootloader=disabled -Defi=false -Ddbus-interfaces-dir=no -Dsbat-distro= --cross-file ".github/workflows/$CROSS_ARCH-clang.cross")
fi
fi
# On ppc64le the workers are slower and some slow tests time out
MESON_TEST_ARGS=()
if [[ "$(uname -m)" != "x86_64" ]] && [[ "$(uname -m)" != "aarch64" ]]; then

View File

@@ -16,7 +16,7 @@ jobs:
build:
runs-on: ${{ matrix.runner }}
concurrency:
group: ${{ github.workflow }}-${{ matrix.run_phase }}-${{ github.ref }}-${{ matrix.runner }}
group: ${{ github.workflow }}-${{ matrix.run_phase }}-${{ matrix.cross_arch || 'native' }}-${{ github.ref }}-${{ matrix.runner }}
cancel-in-progress: true
strategy:
fail-fast: false
@@ -27,6 +27,9 @@ jobs:
- run_phase: GCC
- run_phase: GCC
runner: ubuntu-24.04-arm
- run_phase: GCC
runner: ubuntu-24.04-arm
cross_arch: armhf
- run_phase: GCC
runner: ubuntu-24.04-ppc64le
- run_phase: GCC
@@ -34,10 +37,15 @@ jobs:
- run_phase: CLANG
- run_phase: CLANG
runner: ubuntu-24.04-arm
- run_phase: CLANG
runner: ubuntu-24.04-arm
cross_arch: armhf
- run_phase: CLANG
runner: ubuntu-24.04-ppc64le
- run_phase: CLANG
runner: ubuntu-24.04-s390x
env:
CROSS_ARCH: ${{ matrix.cross_arch || '' }}
steps:
- name: Repository checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
@@ -50,9 +58,9 @@ jobs:
sudo sed -i '/^XDG_/d' /etc/environment
# Pass only specific env variables through sudo, to avoid having
# the already existing XDG_* stuff on the "other side"
sudo --preserve-env=GITHUB_ACTIONS,CI .github/workflows/unit-tests.sh SETUP
sudo --preserve-env=GITHUB_ACTIONS,CI,CROSS_ARCH .github/workflows/unit-tests.sh SETUP
- name: Build & test
run: sudo --preserve-env=GITHUB_ACTIONS,CI .github/workflows/unit-tests.sh RUN_${{ matrix.run_phase }}
run: sudo --preserve-env=GITHUB_ACTIONS,CI,CROSS_ARCH .github/workflows/unit-tests.sh RUN_${{ matrix.run_phase }}
build-musl:
name: Build & test (musl, postmarketOS)