From deb6cb834a8e04d4aad91e72cb6841108ce76b76 Mon Sep 17 00:00:00 2001 From: Jakub Panek Date: Mon, 5 Feb 2024 23:27:53 +0000 Subject: [PATCH] wip: add support for xx-dnf Signed-off-by: Jakub Panek --- .github/workflows/build.yml | 9 -- docker-bake.hcl | 12 +- src/Dockerfile | 82 +++++++++++--- src/test-cargo.bats | 3 + src/test-dnf.bats | 215 ++++++++++++++++++++++++++++++++++++ src/test_helper.bash | 83 ++++++++++---- src/xx-apk | 4 + src/xx-apt | 4 + src/xx-cargo | 29 ++++- src/xx-cc | 33 +++++- src/xx-common | 55 +++++++++ src/xx-dnf | 187 +++++++++++++++++++++++++++++++ src/xx-verify | 13 +-- 13 files changed, 669 insertions(+), 60 deletions(-) create mode 100755 src/test-dnf.bats create mode 100755 src/xx-common create mode 100755 src/xx-dnf diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a8b0e3d..f6ec8a2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -149,20 +149,11 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Test - if: ${{ matrix.typ != 'rhel' }} uses: docker/bake-action@v4 with: targets: test set: | test-${{ matrix.typ }}.args.TEST_BASE_IMAGE=${{ matrix.image }} - - - name: Test (info) - if: ${{ matrix.typ == 'rhel' }} - uses: docker/bake-action@v4 - with: - targets: test-info - set: | - test-${{ matrix.typ }}.args.TEST_BASE_IMAGE=${{ matrix.image }} build: runs-on: ubuntu-latest diff --git a/docker-bake.hcl b/docker-bake.hcl index e320636..b842a1a 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -7,7 +7,7 @@ variable "TEST_BASE_TYPE" { } variable "TEST_BASE_IMAGE" { - default = TEST_BASE_TYPE == "alpine" ? "alpine:3.19" : TEST_BASE_TYPE == "debian" ? "debian:bookworm" : null + default = TEST_BASE_TYPE == "alpine" ? "alpine:3.19" : TEST_BASE_TYPE == "debian" ? "debian:bookworm" : TEST_BASE_TYPE == "rhel" ? "fedora:39" : null } variable "DEV_SDK_PLATFORM" { @@ -41,7 +41,7 @@ target "test-rhel" { inherits = ["test-src"] args = { TEST_BASE_TYPE = "rhel" - TEST_BASE_IMAGE = "fedora:35" + TEST_BASE_IMAGE = "fedora:40" } } @@ -55,6 +55,7 @@ group "test" { "test-info", "test-apk", "test-apt", + "test-dnf", "test-verify", "test-clang", "test-go", @@ -77,6 +78,11 @@ target "test-apt" { target = "test-apt" } +target "test-dnf" { + inherits = ["test-base"] + target = "test-dnf" +} + target "test-verify" { inherits = ["test-base"] target = "test-verify" @@ -356,4 +362,4 @@ target "sigtool" { "linux/arm64", "linux/arm/v7", ] -} \ No newline at end of file +} diff --git a/src/Dockerfile b/src/Dockerfile index 5fb5d76..cd106e4 100644 --- a/src/Dockerfile +++ b/src/Dockerfile @@ -10,7 +10,12 @@ COPY xx-* /out/ RUN ln -s xx-cc /out/xx-clang && \ ln -s xx-cc /out/xx-clang++ && \ ln -s xx-cc /out/xx-c++ && \ - ln -s xx-apt /out/xx-apt-get + ln -s xx-apt /out/xx-apt-get && \ + ln -s xx-dnf /out/xx-yum && \ + ln -s xx-dnf /out/xx-microdnf && \ + ln -s xx-dnf /out/xx-dnf5 && \ + ln -s xx-dnf /out/xx-dnf4 && \ + ln -s xx-dnf /out/xx-dnf-3 # xx builds the xx image FROM scratch AS xx @@ -34,27 +39,72 @@ RUN --mount=type=cache,target=/pkg-cache \ WORKDIR /work FROM ${TEST_BASE_IMAGE} AS test-base-rhel -RUN <> /etc/dnf/dnf.conf + ;; +esac + +cmd_exists() { + command -v $1 >/dev/null 2>/dev/null +} + +get_dnf() { + if cmd_exists dnf; then + echo dnf + elif cmd_exists yum; then + echo yum + elif cmd_exists dnf5; then + echo dnf5 + elif cmd_exists dnf4; then + echo dnf4 + elif cmd_exists dnf-3; then + echo dnf-3 + elif cmd_exists microdnf; then + echo microdnf + else + echo "No supported package manager found" + exit 1 + fi +} + +arg0="$(get_dnf)" + +$arg0 makecache || true + +if ! $arg0 install -y epel-release; then if . /etc/os-release 2>/dev/null; then case "$ID" in - fedora) ;; - rocky) - dnf install -y epel-release - ;; + fedora|rocky) ;; *) - yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-${VERSION:0:1}.noarch.rpm - yum update -y + $arg0 install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-${VERSION:0:1}.noarch.rpm + $arg0 update -y ;; esac fi fi -if command -v dnf >/dev/null 2>/dev/null; then - dnf install -y bats vim -else - yum install -y bats vim -fi + +$arg0 install -y bats vim EOT WORKDIR /work @@ -83,6 +133,10 @@ FROM test-base AS test-apk COPY test-apk.bats . RUN --mount=type=cache,target=/pkg-cache,sharing=locked [ ! -f /etc/alpine-release ] || ./test-apk.bats +FROM test-base AS test-dnf +COPY test-dnf.bats . +RUN --mount=type=cache,target=/pkg-cache,sharing=locked [ ! -f /etc/system-release ] || ./test-dnf.bats + FROM test-base AS test-verify COPY test-verify.bats . RUN --mount=type=cache,target=/pkg-cache,sharing=locked ./test-verify.bats diff --git a/src/test-cargo.bats b/src/test-cargo.bats index 9244cea..ade5fd5 100755 --- a/src/test-cargo.bats +++ b/src/test-cargo.bats @@ -111,6 +111,9 @@ testHelloCargoRustup() { debian | ubuntu) add cargo ;; + fedora) + add cargo + ;; esac } diff --git a/src/test-dnf.bats b/src/test-dnf.bats new file mode 100755 index 0000000..19cc542 --- /dev/null +++ b/src/test-dnf.bats @@ -0,0 +1,215 @@ +#!/usr/bin/env bats + +load 'assert' + +@test "no_cmd" { + run xx-dnf + assert_output --partial "usage: dnf [options] COMMAND" +} + +@test "native" { + run xx-dnf info file + assert_success + assert_line "Name : file" + + run xx-dnf info glibc-devel + assert_success + assert_line "Name : glibc-devel" + + run xx-dnf info gcc + assert_success + assert_line "Name : gcc" +} + +@test "essentials" { + run xx-dnf info xx-c-essentials + assert_success + + run xx-dnf info xx-cxx-essentials + assert_success +} + +@test "amd64" { + export TARGETARCH=amd64 + if ! xx-info is-cross; then skip; fi + + run xx-dnf info file + assert_success + assert_line "Architecture : x86_64" + + run xx-dnf info glibc-devel + assert_success + assert_line "Architecture : x86_64" + + export XX_dnf_PREFER_CROSS=1 + run xx-dnf info glibc-devel + assert_success + assert_line "Package: glibc-devel-amd64-cross" + unset XX_dnf_PREFER_CROSS + + run xx-dnf info gcc + assert_success + assert_line "Architecture : x86_64" +} + +@test "arm64" { + export TARGETARCH=arm64 + if ! xx-info is-cross; then return; fi + + run xx-dnf info file + assert_success + assert_line "Architecture : aarch64" + + run xx-dnf info glibc-devel + assert_success + assert_line "Architecture : aarch64" + + export XX_dnf_PREFER_CROSS=1 + run xx-dnf info glibc-devel + assert_success + assert_line "Name: glibc-devel-arm64-cross" + unset XX_dnf_PREFER_CROSS + + run xx-dnf info gcc + assert_success + assert_line "Architecture : aarch64" +} + +@test "arm" { + export TARGETARCH=arm + if ! xx-info is-cross; then return; fi + + run xx-dnf info file + assert_success + assert_line "Package: file:armhf" + + run xx-dnf info libc6-dev + assert_success + assert_line "Package: libc6-dev:armhf" + + export XX_dnf_PREFER_CROSS=1 + run xx-dnf info libc6-dev + assert_success + assert_line "Package: libc6-dev-armhf-cross" + unset XX_dnf_PREFER_CROSS + + run xx-dnf info gcc + assert_success + assert_line "Package: gcc-arm-linux-gnueabihf" +} + +@test "armv6" { + export TARGETARCH=arm + export TARGETVARIANT=v6 + if ! xx-info is-cross; then return; fi + if [ "$(xx-info vendor)" = "ubuntu" ]; then skip; fi + + run xx-dnf info file + assert_success + assert_line "Package: file:armel" + + run xx-dnf info libc6-dev + assert_success + assert_line "Package: libc6-dev:armel" + + export XX_dnf_PREFER_CROSS=1 + run xx-dnf info libc6-dev + assert_success + assert_line "Package: libc6-dev-armel-cross" + unset XX_dnf_PREFER_CROSS + + run xx-dnf info gcc + assert_success + assert_line "Package: gcc-arm-linux-gnueabi" + unset TARGETVARIANT +} + +@test "s390x" { + export TARGETARCH=s390x + if ! xx-info is-cross; then return; fi + + run xx-dnf info file + assert_success + assert_line "Package: file:s390x" + + run xx-dnf info libc6-dev + assert_success + assert_line "Package: libc6-dev:s390x" + + export XX_dnf_PREFER_CROSS=1 + run xx-dnf info libc6-dev + assert_success + assert_line "Package: libc6-dev-s390x-cross" + unset XX_dnf_PREFER_CROSS + + run xx-dnf info gcc + assert_success + assert_line "Package: gcc-s390x-linux-gnu" +} + +@test "ppc64le" { + export TARGETARCH=ppc64le + if ! xx-info is-cross; then return; fi + + run xx-dnf info file + assert_success + assert_line "Package: file:ppc64le" + + run xx-dnf info libc6-dev + assert_success + assert_line "Package: libc6-dev:ppc64le" + + export XX_dnf_PREFER_CROSS=1 + run xx-dnf info libc6-dev + assert_success + assert_line "Package: libc6-dev-ppc64le-cross" + unset XX_dnf_PREFER_CROSS + + # buster has no gcc package for arm64 + if [ "$(uname -m)" == "aarch64" ] && [ "$(cat /etc/debian_version | cut -d. -f 1)" = "10" ]; then + return + fi + + run xx-dnf info gcc + assert_success + assert_line "Package: gcc-powerpc64le-linux-gnu" +} + +@test "386" { + export TARGETARCH=386 + if ! xx-info is-cross; then return; fi + + run xx-dnf info file + assert_success + assert_line "Package: file:i386" + + run xx-dnf info libc6-dev + assert_success + assert_line "Package: libc6-dev:i386" + + export XX_dnf_PREFER_CROSS=1 + run xx-dnf info libc6-dev + assert_success + assert_line "Package: libc6-dev-i386-cross" + unset XX_dnf_PREFER_CROSS + + run xx-dnf info gcc + assert_success + assert_line "Package: gcc-i686-linux-gnu" +} + +@test "skip-nolinux" { + export TARGETOS="darwin" + export TARGETARCH="amd64" + run xx-dnf install foo + assert_success + unset TARGETOS + unset TARGETARCH +} + +@test "checkpkg" { + run dnf info wget2 + assert_success + run dnf info wget2-notexist + assert_failure +} diff --git a/src/test_helper.bash b/src/test_helper.bash index 68c620e..465d4b0 100644 --- a/src/test_helper.bash +++ b/src/test_helper.bash @@ -1,35 +1,78 @@ #!/usr/bin/env bash +pkg() { + case "${op}" in + add | install) + alpine_op="add" + op="install" + apt_opts="--no-install-recommends" + ;; + del | remove) + alpine_op="del" + op="remove" + apt_opts="--autoremove" + ;; + *) + printf "Unknown op" + exit 1 + ;; + esac + + case "${xx}" in + true) xx="xx-" ;; + *) xx="" ;; + esac + + . /etc/os-release + # Little magic using asterisk matching with 'case' + # ID_LIKE exists on OSes that derive from other, e.g.: + # - Debian: ID_LIKE="" ID="debian" + # - Ubuntu: ID_LIKE="debian" ID="ubuntu" + # - Fedora: ID_LIKE="" ID="fedora" + # - Redhat: ID_LIKE="fedora" ID="rhel" + case "${ID_LIKE}${ID}" in + alpine | chimera | adelie) + if [ "${op}" = "install" ]; then + ${xx}apk ${alpine_op} "$@" + else + ${xx}apk ${alpine_op} "$@" 2>/dev/null || true + fi + ;; + debian*) + if [ "${op}" = "install" ]; then + xxrun ${xx}apt ${op} -y ${apt_opts} "$@" + else + xxrun ${xx}apt ${op} -y ${apt_opts} "$@" 2>/dev/null || true + fi + ;; + fedora*) + if [ "${op}" = "install" ]; then + xxrun ${xx}dnf ${op} -y "$@" + else + xxrun ${xx}dnf ${op} -y "$@" 2>/dev/null || true + fi + ;; + *) + printf "Unknown OS:\n\t%s\n\t%s" "${ID}" "${ID_LIKE}" + exit 1 + ;; + esac +} + add() { - if [ -f /etc/alpine-release ]; then - apk add "$@" - else - xxrun apt install -y --no-install-recommends "$@" - fi + op="add" pkg "$@" } del() { - if [ -f /etc/alpine-release ]; then - apk del "$@" 2>/dev/null || true - else - xxrun apt remove --autoremove -y "$@" 2>/dev/null || true - fi + op="del" pkg "$@" } xxadd() { - if [ -f /etc/alpine-release ]; then - xx-apk add "$@" - else - xxrun xx-apt install -y --no-install-recommends "$@" - fi + op="add" xx="true" pkg "$@" } xxdel() { - if [ -f /etc/alpine-release ]; then - xx-apk del "$@" 2>/dev/null || true - else - xxrun xx-apt remove -y --autoremove "$@" 2>/dev/null || true - fi + op="del" xx="true" pkg "$@" } xxrun() { diff --git a/src/xx-apk b/src/xx-apk index efc1f7e..038c649 100755 --- a/src/xx-apk +++ b/src/xx-apk @@ -2,6 +2,10 @@ set -e +# shellcheck source=./xx-common +. "$(command -v xx-common)" + +flock_setup if [ -z "$XX_APK_NOLOCK" ]; then lock="/var/lock/xx-apk" exec 9>$lock diff --git a/src/xx-apt b/src/xx-apt index 0fc79ff..a9b3b07 100755 --- a/src/xx-apt +++ b/src/xx-apt @@ -2,6 +2,10 @@ set -e +# shellcheck source=./xx-common +. "$(command -v xx-common)" + +flock_setup if [ -z "$XX_APT_NOLOCK" ]; then lock="/var/lock/xx-apt" exec 9>$lock diff --git a/src/xx-cargo b/src/xx-cargo index 1af1b1b..f8017da 100755 --- a/src/xx-cargo +++ b/src/xx-cargo @@ -9,6 +9,10 @@ execSilent() { fi } +# shellcheck source=./xx-common +. "$(command -v xx-common)" + +flock_setup if [ -z "$XX_CARGO_NOLOCK" ]; then lock="/var/lock/xx-cargo" exec 9>$lock @@ -62,12 +66,27 @@ if [ ! -f "$done_file" ]; then if [ ! -d "$(rustc --print sysroot)/lib/rustlib/$(xx-info)" ]; then if [ -n "$rustup" ]; then execSilent rustup target add "$(xx-info)" - elif [ -f /etc/alpine-release ]; then - # XX_VENDOR overrided to match the distrib one to install packages - XX_VENDOR=$vendor execSilent xx-apk add rust-stdlib else - # XX_VENDOR overrided to match the distrib one to install packages - XX_VENDOR=$vendor execSilent xx-apt-get install -y libstd-rust-dev + . /etc/os-release + + case "${ID_LIKE}${ID}" in + alpine | adelie | chimera) + # XX_VENDOR overrided to match the distrib one to install packages + XX_VENDOR=$vendor execSilent xx-apk add rust-stdlib + ;; + fedora*) + # XX_VENDOR overrided to match the distrib one to install packages + XX_VENDOR=$vendor execSilent xx-dnf install -y rust-std-static + ;; + debian*) + # XX_VENDOR overrided to match the distrib one to install packages + XX_VENDOR=$vendor execSilent xx-apt-get install -y libstd-rust-dev + ;; + *) + echo "unknown OS" + exit 1 + ;; + esac fi fi touch "$done_file" diff --git a/src/xx-cc b/src/xx-cc index d80db3c..a6e51f8 100755 --- a/src/xx-cc +++ b/src/xx-cc @@ -37,6 +37,9 @@ installwget() { if command -v apk >/dev/null 2>/dev/null; then apk add wget >/dev/null 2>/dev/null fi + if command -v dnf >/dev/null 2>/dev/null; then + dnf install wget >/dev/null 2>/dev/null + fi } writexcrun() { @@ -300,6 +303,10 @@ if [ -f /.xx-cc-autowrap ]; then fi setup() { + # shellcheck source=./xx-common + . "$(command -v xx-common)" + + flock_setup if [ -z "$XX_CC_NOLOCK" ]; then lock="/var/lock/xx-cc" exec 9>$lock @@ -464,7 +471,20 @@ export PKG_CONFIG_LIBDIR=/${target}/usr/lib/pkgconfig/ exec pkg-config "\$@" EOT chmod +x "/usr/bin/${target}-pkg-config" + elif [ -f /etc/fedora-release ]; then + config="${config} --sysroot=/${target}/" + + if [ -n "$is_bfd" ]; then + config="${config} -Wl,-rpath-link,/${target}/usr/lib" + fi + cat <"/usr/bin/${target}-pkg-config" +#!/usr/bin/env sh +export PKG_CONFIG_SYSROOT_DIR=/${target} +export PKG_CONFIG_LIBDIR=/${target}/usr/lib/pkgconfig/ +exec pkg-config "\$@" +EOT + chmod +x "/usr/bin/${target}-pkg-config" fi elif [ ! -f "/usr/bin/${target}-pkg-config" ] && [ ! -h "/usr/bin/${target}-pkg-config" ]; then ln -s pkg-config "/usr/bin/${target}-pkg-config" @@ -530,6 +550,17 @@ EOT fi fi + if [ -f /etc/fedora-release ]; then + # if vendor is not fedora then sysroot needs to be linked to the custom vendor + fedoratriple=$(echo "$target" | sed s/-[[:alpha:]][[:alpha:]]*-/-fedora-/ | sed s/^riscv64gc-/riscv64-/) + if [ "$target" != "$fedoratriple" ]; then + # shellcheck disable=SC2044 + for f in $(find / -type d -name "$fedoratriple"); do + ln -s "$fedoratriple" "$(dirname "$f")/$target" + done + fi + fi + if [ "${targetos}" = "darwin" ]; then if ! command -v xcrun 2>/dev/null >/dev/null; then writexcrun @@ -637,7 +668,7 @@ if [ -n "${printSysroot}" ]; then setup if xx-info is-cross; then - if [ -f "/etc/alpine-release" ]; then + if [ -f "/etc/alpine-release" ] || [ -f "/etc/fedora-release" ]; then echo "/${target}/" exit 0 fi diff --git a/src/xx-common b/src/xx-common new file mode 100755 index 0000000..224732b --- /dev/null +++ b/src/xx-common @@ -0,0 +1,55 @@ +#!/usr/bin/env sh + +set -e + +cmd_exists() { + command -v "$1" >/dev/null 2>/dev/null +} + +get_dnf() { + if cmd_exists dnf; then + echo dnf + elif cmd_exists yum; then + echo yum + elif cmd_exists dnf5; then + echo dnf5 + elif cmd_exists dnf4; then + echo dnf4 + elif cmd_exists dnf-3; then + echo dnf-3 + elif cmd_exists microdnf; then + echo microdnf + else + echo "No supported package manager found" + exit 1 + fi +} + +add_package() { + if cmd_exists apk; then + apk add --no-cache "$1" >"$2" + elif cmd_exists apt; then + apt update && apt install -y "$1" + elif cmd_exists dnf; then + $(get_dnf) install -y "$1" >"$2" + else + echo >&2 "$1 not installed and no package manager not found" + exit 1 + fi +} + +flock_setup() { + if ! test -d /var/run/lock; then + mkdir -p /var/run/lock + fi + + if ! command -v flock >/dev/null 2>/dev/null; then + . /etc/os-release + case "${ID}" in + fedora) + add_package flock /dev/null + ;; + *) ;; + esac + fi +} diff --git a/src/xx-dnf b/src/xx-dnf new file mode 100755 index 0000000..7cc8993 --- /dev/null +++ b/src/xx-dnf @@ -0,0 +1,187 @@ +#!/usr/bin/env sh + +set -e + +# shellcheck source=./xx-common +. "$(command -v xx-common)" + +flock_setup +if [ -z "$XX_DNF_NOLOCK" ]; then + lock="/var/lock/xx-dnf" + exec 9>$lock + flock -x 9 + export XX_DNF_NOLOCK=1 +fi + +if [ -n "$XX_DEBUG_DNF" ]; then + set -x +fi + +unset XX_VENDOR # vendor for installing packages is always fedora + +for l in $(xx-info env); do + export "${l?}" +done + +if [ "${TARGETOS}" != "linux" ]; then + echo >&2 "skipping packages installation on ${XX_OS}" + exit 0 +fi + +arg0="$(basename "$0")" +case $arg0 in + xx-dnf) arg0="dnf" ;; + xx-yum) arg0="yum" ;; + xx-dnf5) arg0="dnf5" ;; + xx-dnf4) arg0="dnf4" ;; + xx-dnf-3) arg0="dnf-3" ;; + xx-microdnf) arg0="microdnf" ;; +esac + +if ! cmd_exists "$arg0"; then + echo "Couldn't find '${arg0}', detecting dnf..." + arg0="$(get_dnf)" + echo "Found '${arg0}'" +fi + +suffix=$XX_TRIPLE +if [ "$suffix" = "x86_64-linux-gnu" ]; then + suffix="x86-64-linux-gnu" +fi +if [ "$XX_OS" = "windows" ]; then + case "$XX_ARCH" in + amd64) suffix="mingw-w64-x86-64" ;; + 386) suffix="mingw-w64-i686" ;; + arm64) suffix="mingw-w64-aarch64" ;; + arm) suffix="mingw-w64-arm" ;; + esac +fi + +packages2= +for p in ${packages}; do + if [ "${p}" = "xx-c-essentials" ]; then + p="glibc-devel" + p="$p libgcc" + elif [ "${p}" = "xx-cxx-essentials" ]; then + p="libstdc++-devel" + fi + if [ -z "$packages2" ]; then + packages2="$p" + else + packages2="${packages2} $p" + fi +done + +for p in ${packages2}; do + n= + if [ -n "$nocross" ]; then + n=${p} + elif checkpkg "${p}-${suffix}" >/dev/null 2>/dev/null; then + n="${p}-${suffix}" + elif [ "${XX_OS}" = "linux" ] && [ -n "${XX_DNF_PREFER_CROSS}" ] && checkpkg "${p}.${XX_PKG_ARCH}-cross" >/dev/null 2>/dev/null; then + n="${p}-${XX_PKG_ARCH}-cross" + elif [ "${XX_OS}" = "linux" ]; then + n="${p}.${XX_PKG_ARCH}" + else + continue + fi + set -- "$@" "$n" +done + +setup() { + if ! xx-info is-cross; then + return + fi + done_file="/${XX_TRIPLE}/.xx-setup" + if [ -f "$done_file" ]; then + return + fi + yum_dir="/${XX_TRIPLE}/etc/yum.repos.d" + mkdir -p "$yum_dir" + + cp -r /etc/yum.repos.d/* "$yum_dir/" + + $arg0 install -y --forcearch "$(xx-info rhel-arch)" --installroot "/${XX_TRIPLE}" --releasever "${VERSION_ID}" fedora-repos + + touch "$done_file" +} + +clean() { + if ! xx-info is-cross; then + return + fi + # safety first + if [ -z "${XX_TRIPLE}" ]; then + echo >&2 "invalid triple root $XX_TRIPLE" + exit 1 + fi + rm -rf "/${XX_TRIPLE:?}" +} + +cmd() { + setup + root="/" + if xx-info is-cross; then + root="/${XX_TRIPLE}" + fi + n=$# + iscompilerrt= + isrustlib= + for a in "$@"; do + if [ $# = $n ]; then set --; fi + case "$a" in + "xx-c-essentials") + set -- "$@" glibc-devel gcc + ;; + "xx-cxx-essentials") + set -- "$@" gcc-c++ + ;; + "compiler-rt" | "compiler-rt-static") + iscompilerrt="$a" + set -- "$@" "$a" + ;; + "rust-stdlib") + set -- "$@" rust-std-static + isrustlib=1 + ;; + *) + set -- "$@" "$a" + ;; + esac + done + if [ "$#" != "0" ]; then + set -- "--installroot" "$root" "--forcearch" "$(xx-info rhel-arch)" "$@" + echo "+ $arg0 " "$@" + fi + dnf "$@" + if xx-info is-cross; then + if [ -z "$XX_DNF_KEEP_BINARIES" ]; then + rm -rf "/${XX_TRIPLE:?}/usr/bin/*" + fi + if [ -n "$iscompilerrt" ]; then + for f in $($arg0 --installroot "$root" info -qL "$iscompilerrt" | grep 'clang_rt.'); do + ff="/${f}" + if [ ! -f "${ff}" ]; then + mkdir -p "$(dirname "${ff}")" + ln -s "/$(xx-info)/${f}" "${ff}" + fi + done + fi + # rust stdlib is accessed from the real root + if [ -n "$isrustlib" ] && [ -d "$root/usr/lib/rustlib/$(xx-info)" ]; then + ln -s "$root/usr/lib/rustlib/$(xx-info)" "/usr/lib/rustlib/$(xx-info)" || true + fi + fi +} + +case "$1" in + "setup") + setup + ;; + "clean") + clean + ;; + *) + cmd "$@" + ;; +esac diff --git a/src/xx-verify b/src/xx-verify index 4951aa4..05c21a1 100755 --- a/src/xx-verify +++ b/src/xx-verify @@ -2,6 +2,10 @@ set -e +# shellcheck source=./xx-common +. "$(command -v xx-common)" + +flock_setup if [ -z "$XX_VERIFY_NOLOCK" ]; then lock="/var/lock/xx-verify" exec 9>$lock @@ -19,14 +23,7 @@ done setup() { if ! command -v file >/dev/null 2>/dev/null; then - if command -v apk >/dev/null; then - apk add --no-cache file >"$1" - elif command -v apt >/dev/null; then - apt update && apt install -y file - else - echo >&2 "file not installed and no package manager not found" - exit 1 - fi + add_package file "$1" fi }