diff --git a/.github/workflows/armhf-clang.cross b/.github/workflows/armhf-clang.cross new file mode 100644 index 00000000000..1da21afd1f6 --- /dev/null +++ b/.github/workflows/armhf-clang.cross @@ -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' diff --git a/.github/workflows/armhf-gcc.cross b/.github/workflows/armhf-gcc.cross new file mode 100644 index 00000000000..8fd2bf76708 --- /dev/null +++ b/.github/workflows/armhf-gcc.cross @@ -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' diff --git a/.github/workflows/build-test.sh b/.github/workflows/build-test.sh index 3d3a5e8bcca..784340ec450 100755 --- a/.github/workflows/build-test.sh +++ b/.github/workflows/build-test.sh @@ -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 : 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 diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 5325954031f..2596b3edb5e 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -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: '' diff --git a/.github/workflows/unit-tests.sh b/.github/workflows/unit-tests.sh index c87b7d2e9a3..f910e21691f 100755 --- a/.github/workflows/unit-tests.sh +++ b/.github/workflows/unit-tests.sh @@ -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 : 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 diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 5740d425b9a..d265c993c76 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -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) diff --git a/src/core/unit.c b/src/core/unit.c index d66f813a9a3..670f84fc15f 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2338,7 +2338,7 @@ static void retroactively_stop_dependencies(Unit *u) { void unit_start_on_termination_deps(Unit *u, UnitDependencyAtom atom) { const char *dependency_name = NULL; - JobMode job_mode; + JobMode job_mode = _JOB_MODE_INVALID; unsigned n_jobs = 0; int r; diff --git a/src/sysupdate/sysupdate-transfer.c b/src/sysupdate/sysupdate-transfer.c index 27756298fa2..bb984915926 100644 --- a/src/sysupdate/sysupdate-transfer.c +++ b/src/sysupdate/sysupdate-transfer.c @@ -1343,7 +1343,7 @@ int transfer_acquire_instance(Transfer *t, Instance *i, InstanceMetadata *f, Tra * download. */ if (!i->metadata.sha256sum_set) - return log_error_errno(r, "SHA256 checksum not known for download '%s', refusing.", i->path); + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "SHA256 checksum not known for download '%s', refusing.", i->path); digest = hexmem(i->metadata.sha256sum, sizeof(i->metadata.sha256sum)); if (!digest) diff --git a/src/test/meson.build b/src/test/meson.build index 03635c2efc7..21b1f435f46 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -547,6 +547,7 @@ executables += [ core_test_template + { 'sources' : files('test-execute.c'), 'dependencies' : common_test_dependencies, + 'type' : meson.is_cross_build() ? 'manual' : '', 'timeout' : 360, }, core_test_template + { diff --git a/src/test/test-crypto-util.c b/src/test/test-crypto-util.c index a2fd090ed3f..989905ab0f8 100644 --- a/src/test/test-crypto-util.c +++ b/src/test/test-crypto-util.c @@ -129,7 +129,7 @@ static const struct { }; TEST(digest_size) { - size_t size; + size_t size = 0; /* avoid false maybe-uninitialized warning */ FOREACH_ELEMENT(t, digest_size_table) { assert(openssl_digest_size(t->alg, &size) >= 0); diff --git a/src/ukify/test/meson.build b/src/ukify/test/meson.build index 68be54e2282..a5c7bbb37c3 100644 --- a/src/ukify/test/meson.build +++ b/src/ukify/test/meson.build @@ -12,10 +12,15 @@ if want_ukify and want_tests != 'false' args += ['--flakes'] endif + efi_addon_for_test = '' + if not meson.is_cross_build() and efi_addon.length() > 0 + efi_addon_for_test = efi_addon[0].full_path() + endif + test('test-ukify', files('test_ukify.py'), args: args, - env : test_env + {'EFI_ADDON' : efi_addon.length() > 0 ? efi_addon[0].full_path() : ''}, + env : test_env + {'EFI_ADDON' : efi_addon_for_test}, timeout : 120, suite : 'ukify', depends : efi_addon)