From eac387d50335d0266aaadec477a32ecf688f3f03 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Thu, 7 Jul 2022 13:58:15 +0200 Subject: [PATCH 01/31] base: fix xx-info failing on macOS macOS doesn't have a /etc/os-release, which caused the script to fail when running on the host. Also adds detection if /etc/os-release exists. Signed-off-by: Sebastiaan van Stijn --- base/xx-info | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/base/xx-info b/base/xx-info index 9a60b769..638cc008 100755 --- a/base/xx-info +++ b/base/xx-info @@ -99,13 +99,13 @@ if [ -n "$TARGETPLATFORM" ]; then fi # detect distro vendor -# shellcheck disable=SC1091 -if . /etc/os-release 2>/dev/null; then - XX_VENDOR=$ID -fi - if [ "$TARGETOS" = "darwin" ]; then XX_VENDOR="apple" +elif [ -f /etc/os-release ]; then + # shellcheck disable=SC1091 + if . /etc/os-release 2>/dev/null; then + XX_VENDOR=$ID + fi fi vendor="" @@ -328,7 +328,7 @@ case "$1" in echo $XX_TRIPLE ;; "vendor") - echo $XX_VENDOR + echo "$XX_VENDOR" ;; "libc") # this is not abi, just the prefix echo $XX_LIBC From e7cfa85ba6f579622fa438c81457e700af291c35 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sat, 27 Aug 2022 14:06:06 +0200 Subject: [PATCH 02/31] mips archs support Signed-off-by: CrazyMax --- base/test-go.bats | 94 ++++++++++++++++++++++++++++++++++++-- base/test-info-alpine.bats | 20 ++++++++ base/test-info-common.bats | 40 ++++++++++++++++ base/test-info-debian.bats | 20 ++++++++ base/test-info-rhel.bats | 20 ++++++++ base/xx-go | 11 +++++ base/xx-info | 81 ++++++++++++++++++++++++-------- docker-bake.hcl | 63 +++++++++++++++++++++++-- 8 files changed, 323 insertions(+), 26 deletions(-) diff --git a/base/test-go.bats b/base/test-go.bats index a57d57ea..736f9fb3 100755 --- a/base/test-go.bats +++ b/base/test-go.bats @@ -18,9 +18,17 @@ testEnv() { assert_output --partial 'GOHOSTOS="'"$(TARGETOS= TARGETARCH= xx-info os)"'"' assert_output --partial 'GOHOSTARCH="'"$(TARGETOS= TARGETARCH= xx-info arch)"'"' - if [ $(xx-info arch) = "arm" ]; then - assert_output --partial 'GOARM="'"$expArm"'"' - fi + case "$(xx-info arch)" in + "arm") + assert_output --partial 'GOARM="'"$expArm"'"' + ;; + "mips64"*) + assert_output --partial 'GOMIPS64="'"$expMips"'"' + ;; + "mips"*) + assert_output --partial 'GOMIPS="'"$expMips"'"' + ;; + esac } @test "native-env" { @@ -87,6 +95,62 @@ testEnv() { testEnv } +@test "mips-env" { + export TARGETARCH=mips + expMips=hardfloat + testEnv +} + +@test "mips-softfloat-env" { + export TARGETARCH=mips + export TARGETVARIANT=softfloat + expMips=softfloat + testEnv + unset TARGETVARIANT +} + +@test "mipsle-env" { + export TARGETARCH=mipsle + expMips=hardfloat + testEnv +} + +@test "mipsle-softfloat-env" { + export TARGETARCH=mipsle + export TARGETVARIANT=softfloat + expMips=softfloat + testEnv + unset TARGETVARIANT +} + +@test "mips64-env" { + export TARGETARCH=mips64 + expMips=hardfloat + testEnv +} + +@test "mips64-softfloat-env" { + export TARGETARCH=mips64 + export TARGETVARIANT=softfloat + expMips=softfloat + testEnv + unset TARGETVARIANT +} + +@test "mips64le-env" { + export TARGETARCH=mips64le + expMips=hardfloat + testEnv +} + +@test "mips64le-softfloat-env" { + export TARGETARCH=mips64le + export TARGETVARIANT=softfloat + expMips=softfloat + testEnv + unset TARGETVARIANT +} + @test "darwin-amd64-env" { export TARGETOS=darwin export TARGETARCH=amd64 @@ -161,6 +225,30 @@ testHelloGO() { testHelloGO } +@test "mipsle-hellogo" { + export TARGETARCH=mipsle + testHelloGO +} + +@test "mipsle-softfloat-hellogo" { + export TARGETARCH=mipsle + export TARGETVARIANT=softfloat + testHelloGO + unset TARGETVARIANT +} + +@test "mips64le-hellogo" { + export TARGETARCH=mips64le + testHelloGO +} + +@test "mips64le-softfloat-hellogo" { + export TARGETARCH=mips64le + export TARGETVARIANT=softfloat + testHelloGO + unset TARGETVARIANT +} + @test "darwin-amd64-hellogo" { export TARGETARCH=amd64 export TARGETOS=darwin diff --git a/base/test-info-alpine.bats b/base/test-info-alpine.bats index 51733eb3..754a1579 100755 --- a/base/test-info-alpine.bats +++ b/base/test-info-alpine.bats @@ -67,6 +67,26 @@ load 'assert' assert_equal "riscv64" "$(TARGETPLATFORM=linux/riscv64 xx-info pkg-arch)" } +@test "mips" { + assert_equal "mips-alpine-linux-musl" "$(TARGETPLATFORM=linux/mips xx-info triple)" + assert_equal "mips" "$(TARGETPLATFORM=linux/mips xx-info pkg-arch)" +} + +@test "mipsle" { + assert_equal "mipsel-alpine-linux-musl" "$(TARGETPLATFORM=linux/mipsle xx-info triple)" + assert_equal "mipsle" "$(TARGETPLATFORM=linux/mipsle xx-info pkg-arch)" +} + +@test "mips64" { + assert_equal "mips64-alpine-linux-muslabi64" "$(TARGETPLATFORM=linux/mips64 xx-info triple)" + assert_equal "mips64" "$(TARGETPLATFORM=linux/mips64 xx-info pkg-arch)" +} + +@test "mips64le" { + assert_equal "mips64el-alpine-linux-muslabi64" "$(TARGETPLATFORM=linux/mips64le xx-info triple)" + assert_equal "mips64le" "$(TARGETPLATFORM=linux/mips64le xx-info pkg-arch)" +} + @test "darwin" { assert_equal "x86_64-apple-macos10.6" "$(TARGETPLATFORM=darwin/amd64 xx-info triple)" assert_equal "darwin" "$(TARGETPLATFORM=darwin/amd64 xx-info os)" diff --git a/base/test-info-common.bats b/base/test-info-common.bats index 05d325b5..6e51dbf2 100755 --- a/base/test-info-common.bats +++ b/base/test-info-common.bats @@ -76,6 +76,22 @@ load 'assert' assert_equal "ppc64le" "$(TARGETPLATFORM=linux/ppc64le xx-info march)" } +@test "mips" { + assert_equal "mips" "$(TARGETPLATFORM=linux/mips xx-info march)" +} + +@test "mipsle" { + assert_equal "mipsle" "$(TARGETPLATFORM=linux/mipsle xx-info march)" +} + +@test "mips64" { + assert_equal "mips64" "$(TARGETPLATFORM=linux/mips64 xx-info march)" +} + +@test "mips64le" { + assert_equal "mips64le" "$(TARGETPLATFORM=linux/mips64le xx-info march)" +} + @test "parse pair" { TARGETPAIR=linux-amd64 run xx-info os assert_success @@ -100,6 +116,30 @@ load 'assert' TARGETPAIR=linux-ppc64le run xx-info assert_success assert_output "$(TARGETPLATFORM=linux/ppc64le xx-info)" + + TARGETPAIR=linux-s390x run xx-info + assert_success + assert_output "$(TARGETPLATFORM=linux/s390x xx-info)" + + TARGETPAIR=linux-riscv64 run xx-info + assert_success + assert_output "$(TARGETPLATFORM=linux/riscv64 xx-info)" + + TARGETPAIR=linux-mips run xx-info + assert_success + assert_output "$(TARGETPLATFORM=linux/mips xx-info)" + + TARGETPAIR=linux-mipsle run xx-info + assert_success + assert_output "$(TARGETPLATFORM=linux/mipsle xx-info)" + + TARGETPAIR=linux-mips64 run xx-info + assert_success + assert_output "$(TARGETPLATFORM=linux/mips64 xx-info)" + + TARGETPAIR=linux-mips64le run xx-info + assert_success + assert_output "$(TARGETPLATFORM=linux/mips64le xx-info)" } @test "windows" { diff --git a/base/test-info-debian.bats b/base/test-info-debian.bats index ca25e8df..ddca32a4 100755 --- a/base/test-info-debian.bats +++ b/base/test-info-debian.bats @@ -69,6 +69,26 @@ fi assert_equal "riscv64" "$(TARGETPLATFORM=linux/riscv64 xx-info pkg-arch)" } +@test "mips" { + assert_equal "mips-linux-gnu" "$(TARGETPLATFORM=linux/mips xx-info triple)" + assert_equal "mips" "$(TARGETPLATFORM=linux/mips xx-info pkg-arch)" +} + +@test "mipsle" { + assert_equal "mipsel-linux-gnu" "$(TARGETPLATFORM=linux/mipsle xx-info triple)" + assert_equal "mipsel" "$(TARGETPLATFORM=linux/mipsle xx-info pkg-arch)" +} + +@test "mips64" { + assert_equal "mips64-linux-gnuabi64" "$(TARGETPLATFORM=linux/mips64 xx-info triple)" + assert_equal "mips64" "$(TARGETPLATFORM=linux/mips64 xx-info pkg-arch)" +} + +@test "mips64le" { + assert_equal "mips64el-linux-gnuabi64" "$(TARGETPLATFORM=linux/mips64le xx-info triple)" + assert_equal "mips64el" "$(TARGETPLATFORM=linux/mips64le xx-info pkg-arch)" +} + @test "sysroot" { assert_equal "/" "$(xx-info sysroot)" assert_equal "/" "$(TARGETPLATFORM=linux/amd64 xx-info sysroot)" diff --git a/base/test-info-rhel.bats b/base/test-info-rhel.bats index fa360bcd..1dff15c8 100755 --- a/base/test-info-rhel.bats +++ b/base/test-info-rhel.bats @@ -59,3 +59,23 @@ fi @test "riscv64" { assert_equal "riscv64" "$(TARGETPLATFORM=linux/riscv64 xx-info pkg-arch)" } + +@test "mips" { + assert_equal "mips-linux-gnu" "$(TARGETPLATFORM=linux/mips xx-info triple)" + assert_equal "mips" "$(TARGETPLATFORM=linux/mips xx-info pkg-arch)" +} + +@test "mipsle" { + assert_equal "mipsel-linux-gnu" "$(TARGETPLATFORM=linux/mipsle xx-info triple)" + assert_equal "mipsel" "$(TARGETPLATFORM=linux/mipsle xx-info pkg-arch)" +} + +@test "mips64" { + assert_equal "mips64-linux-gnuabi64" "$(TARGETPLATFORM=linux/mips64 xx-info triple)" + assert_equal "mips64" "$(TARGETPLATFORM=linux/mips64 xx-info pkg-arch)" +} + +@test "mips64le" { + assert_equal "mips64el-linux-gnuabi64" "$(TARGETPLATFORM=linux/mips64le xx-info triple)" + assert_equal "mips64el" "$(TARGETPLATFORM=linux/mips64le xx-info pkg-arch)" +} diff --git a/base/xx-go b/base/xx-go index 6a7fecb4..7dcb1227 100755 --- a/base/xx-go +++ b/base/xx-go @@ -27,6 +27,17 @@ if [ "$TARGETARCH" = "arm" ]; then fi fi +if [ -n "$TARGETVARIANT" ]; then + case "$TARGETARCH" in + "mips64"*) + export GOMIPS64="${TARGETVARIANT}" + ;; + "mips"*) + export GOMIPS="${TARGETVARIANT}" + ;; + esac +fi + if [ "$GOOS" = "wasi" ]; then export GOOS="js" fi diff --git a/base/xx-info b/base/xx-info index 638cc008..2f5eb8e5 100755 --- a/base/xx-info +++ b/base/xx-info @@ -79,22 +79,27 @@ if [ -n "$TARGETPLATFORM" ]; then if [ -n "$os" ] && [ -n "$arch" ]; then TARGETOS="$os" TARGETARCH="$arch" - if [ "$arch" = "arm" ]; then - case "$(echo $TARGETPLATFORM | cut -d"/" -f3)" in - "v5") - TARGETVARIANT="v5" - ;; - "v6") - TARGETVARIANT="v6" - ;; - "v8") - TARGETVARIANT="v8" - ;; - *) - TARGETVARIANT="v7" - ;; - esac - fi + case "$arch" in + "arm") + case "$(echo $TARGETPLATFORM | cut -d"/" -f3)" in + "v5") + TARGETVARIANT="v5" + ;; + "v6") + TARGETVARIANT="v6" + ;; + "v8") + TARGETVARIANT="v8" + ;; + *) + TARGETVARIANT="v7" + ;; + esac + ;; + "mips"*) + TARGETVARIANT="$(echo $TARGETPLATFORM | cut -d"/" -f3)" + ;; + esac fi fi @@ -163,6 +168,18 @@ if [ -z "$TARGETARCH" ]; then "s390x") TARGETARCH="s390x" ;; + "mips") + TARGETARCH="mips" + ;; + "mipsle") + TARGETARCH="mipsle" + ;; + "mips64") + TARGETARCH="mips64" + ;; + "mips64le") + TARGETARCH="mips64le" + ;; esac fi @@ -276,6 +293,34 @@ case "$TARGETARCH" in XX_TRIPLE="i686-w64-mingw32" fi ;; + "mips") + XX_MARCH="mips" + XX_DEBIAN_ARCH="mips" + XX_ALPINE_ARCH="mips" + XX_RHEL_ARCH="mips" + XX_TRIPLE="mips${vendor}-linux-${XX_LIBC}" + ;; + "mipsle") + XX_MARCH="mipsle" + XX_DEBIAN_ARCH="mipsel" + XX_ALPINE_ARCH="mipsle" + XX_RHEL_ARCH="mipsel" + XX_TRIPLE="mipsel${vendor}-linux-${XX_LIBC}" + ;; + "mips64") + XX_MARCH="mips64" + XX_DEBIAN_ARCH="mips64" + XX_ALPINE_ARCH="mips64" + XX_RHEL_ARCH="mips64" + XX_TRIPLE="mips64${vendor}-linux-${XX_LIBC}abi64" + ;; + "mips64le") + XX_MARCH="mips64le" + XX_DEBIAN_ARCH="mips64el" + XX_ALPINE_ARCH="mips64le" + XX_RHEL_ARCH="mips64el" + XX_TRIPLE="mips64el${vendor}-linux-${XX_LIBC}abi64" + ;; esac XX_PKG_ARCH=$TARGETARCH @@ -325,7 +370,7 @@ case "$1" in echo $XX_PKG_ARCH ;; "triple") - echo $XX_TRIPLE + echo "$XX_TRIPLE" ;; "vendor") echo "$XX_VENDOR" @@ -364,7 +409,7 @@ case "$1" in usage ;; "") - echo $XX_TRIPLE + echo "$XX_TRIPLE" ;; *) echo "unknown command $1" diff --git a/docker-bake.hcl b/docker-bake.hcl index 1f22735c..585f495d 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -63,7 +63,21 @@ group "default" { } target "_all-platforms" { - platforms = ["linux/amd64", "linux/arm64", "linux/arm", "linux/arm/v6", "linux/ppc64le", "linux/s390x", "linux/386", "linux/riscv64"] + platforms = [ + "linux/386", + "linux/amd64", + "linux/arm64", + "linux/arm/v5", + "linux/arm/v6", + "linux/arm/v7", + "linux/mips", + "linux/mipsle", + "linux/mips64", + "linux/mips64le", + "linux/ppc64le", + "linux/s390x", + "linux/riscv64" + ] } target "base" { @@ -80,14 +94,42 @@ target "sdk-extras" { context = "base" target = "sdk-extras" tags = ["${XX_REPO}:sdk-extras"] - platforms = ["linux/amd64", "linux/arm64", "linux/arm", "linux/arm/v6", "linux/ppc64le", "linux/s390x", "linux/386", "linux/riscv64", "windows/amd64", "windows/arm", "windows/386", "windows/arm64", "linux/mips64", "linux/mips64le", "darwin/amd64", "darwin/arm64", "freebsd/amd64"] + platforms = [ + "darwin/amd64", + "darwin/arm64", + "freebsd/amd64", + "linux/386", + "linux/amd64", + "linux/arm64", + "linux/arm/v5", + "linux/arm/v6", + "linux/arm/v7", + "linux/mips", + "linux/mipsle", + "linux/mips64", + "linux/mips64le", + "linux/ppc64le", + "linux/riscv64", + "linux/s390x", + "windows/386", + "windows/amd64", + "windows/arm", + "windows/arm64" + ] } target "ld64-tgz" { context = "base" target = "ld64-tgz" output = ["./ld64-tgz"] - platforms = ["linux/amd64", "linux/arm64", "linux/arm", "linux/arm/v6", "linux/386"] + platforms = [ + "linux/386", + "linux/amd64", + "linux/arm64", + "linux/arm/v5", + "linux/arm/v6", + "linux/arm/v7" + ] cache-to = ["type=inline"] } @@ -115,7 +157,12 @@ target "binutils-base" { args = { BINUTILS_VERSION = BINUTILS_VERSION } - platforms = ["linux/amd64", "linux/arm64", "linux/arm", "linux/s390x"] + platforms = [ + "linux/amd64", + "linux/arm64", + "linux/arm", + "linux/s390x" + ] cache-to = ["type=inline"] } @@ -219,7 +266,13 @@ target "ld-tgz-base" { args = { LD_VERSION = BINUTILS_VERSION } - platforms = ["linux/amd64", "linux/arm64", "linux/arm", "linux/s390x", "linux/ppc64le"] + platforms = [ + "linux/amd64", + "linux/arm64", + "linux/arm", + "linux/s390x", + "linux/ppc64le" + ] cache-to = ["type=inline"] output = ["./ld-tgz"] } From a0f02211c52ab10c6936e7ac0637c07a7f922a1b Mon Sep 17 00:00:00 2001 From: trilom Date: Sun, 11 Sep 2022 02:09:31 -0400 Subject: [PATCH 03/31] add profdata and readelf to llvm Signed-off-by: trilom --- base/xx-cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/xx-cc b/base/xx-cc index af92414c..e8c8abaa 100755 --- a/base/xx-cc +++ b/base/xx-cc @@ -539,7 +539,7 @@ EOT fi done - for f in addr2line ar as ranlib nm dlltool strip; do + for f in addr2line ar as ranlib nm dlltool strip readelf profdata; do if ! command -v "${target}-${f}" >/dev/null 2>/dev/null; then if [ -f "/usr/bin/llvm-${f}" ]; then if echo "${target}" | grep '\.' 2>/dev/null >/dev/null; then From 265931617013d0112d5efee47c2fb0f7e1a9468b Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Wed, 17 Aug 2022 03:44:20 +0200 Subject: [PATCH 04/31] ci: os update Signed-off-by: CrazyMax --- .github/workflows/build.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6cc4df3a..d70d37fd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,6 +43,10 @@ jobs: image: alpine:3.15 typ: alpine allow-failure: false + - + image: alpine:3.16 + typ: alpine + allow-failure: false - image: alpine:edge typ: alpine @@ -68,7 +72,7 @@ jobs: typ: debian allow-failure: false - - image: ubuntu:21.10 + image: ubuntu:22.04 typ: debian allow-failure: false - @@ -79,6 +83,10 @@ jobs: image: fedora:35 typ: rhel allow-failure: false + - + image: fedora:36 + typ: rhel + allow-failure: false - image: centos:7 typ: rhel @@ -95,6 +103,12 @@ jobs: - name: Checkout uses: actions/checkout@v2 + - + name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 - name: Test uses: docker/bake-action@v1 From 8df79fd2e4bc9e7671b211fcbf02bdd3d6eda638 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Fri, 9 Sep 2022 11:35:05 +0200 Subject: [PATCH 05/31] Dockerfile: set APT_MIRROR Signed-off-by: CrazyMax --- base/Dockerfile | 4 ++++ docker-bake.hcl | 1 + 2 files changed, 5 insertions(+) diff --git a/base/Dockerfile b/base/Dockerfile index 25c06cd4..f0f09dcf 100644 --- a/base/Dockerfile +++ b/base/Dockerfile @@ -25,11 +25,15 @@ RUN --mount=type=cache,target=/pkg-cache \ WORKDIR /work FROM ${TEST_BASE_IMAGE} AS test-base-debian +ARG APT_MIRROR=deb.debian.org RUN --mount=type=cache,target=/pkg-cache \ rm -rf /var/cache/apt/archives && \ ln -s /pkg-cache /var/cache/apt/archives && \ rm /etc/apt/apt.conf.d/docker-clean && \ echo 'Binary::apt::APT::Keep-Downloaded-Packages "1";' > /etc/apt/apt.conf.d/keep-downloads && \ + touch /etc/apt/sources.list && \ + sed -ri "s/(httpredir|deb).debian.org/${APT_MIRROR:-deb.debian.org}/g" /etc/apt/sources.list && \ + sed -ri "s/(security).debian.org/${APT_MIRROR:-security.debian.org}/g" /etc/apt/sources.list && \ apt update && apt install --no-install-recommends -y bats vim WORKDIR /work diff --git a/docker-bake.hcl b/docker-bake.hcl index 1f22735c..93e3b5d0 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -23,6 +23,7 @@ target "test-alpine" { target "test-debian" { inherits = ["test-base"] args = { + APT_MIRROR = "cdn-fastly.deb.debian.org" TEST_BASE_TYPE = "debian" TEST_BASE_IMAGE = "debian:bullseye" } From d926dd70747efe5496958c2db69580cf81b2c572 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Fri, 9 Sep 2022 22:26:53 +0200 Subject: [PATCH 06/31] xx-info: os-version Signed-off-by: CrazyMax --- base/test-info-common.bats | 9 +++++++++ base/xx-info | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/base/test-info-common.bats b/base/test-info-common.bats index 6e51dbf2..80d90c8a 100755 --- a/base/test-info-common.bats +++ b/base/test-info-common.bats @@ -7,6 +7,15 @@ load 'assert' assert_equal "linux" "$(xx-info os)" } +@test "os-version" { + run xx-info os-version + assert_success + if grep 'PRETTY_NAME=".*/sid"$' /etc/os-release >/dev/null 2>/dev/null; then + skip "VERSION_ID not set for unstable repo" + fi + [ "$output" != "" ] +} + @test "is-cross" { run xx-info is-cross assert_failure diff --git a/base/xx-info b/base/xx-info index 2f5eb8e5..10a88b64 100755 --- a/base/xx-info +++ b/base/xx-info @@ -13,6 +13,7 @@ : "${XX_DEBIAN_ARCH=unknown}" # https://docs.fedoraproject.org/ro/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch01s03.html : "${XX_RHEL_ARCH=unknown}" +: "${XX_OS_VERSION=unknown}" : "${XX_TRIPLE=unknown-unknown-none}" : "${XX_VENDOR=unknown}" : "${XX_LIBC=}" @@ -30,6 +31,7 @@ Commands: libc Print used libc (musl or gnu) march Print target machine architecture, uname -m os Print target operating system (linux,darwin,windows,wasi) + os-version Print operating system version pkg-arch Print either alpine-arch or debian-arch rhel-arch Print target architecture for RPM package repositories sysroot Print sysroot directory for target architecture @@ -110,6 +112,7 @@ elif [ -f /etc/os-release ]; then # shellcheck disable=SC1091 if . /etc/os-release 2>/dev/null; then XX_VENDOR=$ID + XX_OS_VERSION=$VERSION_ID fi fi @@ -354,6 +357,9 @@ case "$1" in "os") echo $TARGETOS # TODO: ;; + "os-version") + echo "$XX_OS_VERSION" + ;; "march") echo $XX_MARCH ;; @@ -380,6 +386,7 @@ case "$1" in ;; "env") echo "XX_OS=${TARGETOS}" + echo "XX_OS_VERSION=${XX_OS_VERSION}" echo "XX_ARCH=${TARGETARCH}" echo "XX_MARCH=${XX_MARCH}" echo "XX_VENDOR=${XX_VENDOR}" From ada701d39ed45f5b8f8736d3974b9211083c1079 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Sat, 28 Aug 2021 18:08:01 -0700 Subject: [PATCH 07/31] Allow custom vendor to support unknown triple in rust Signed-off-by: Tonis Tiigi --- base/xx-apk | 2 ++ base/xx-cc | 12 ++++++++++++ base/xx-info | 37 +++++++++++++++++++++---------------- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/base/xx-apk b/base/xx-apk index b563f524..956a3192 100755 --- a/base/xx-apk +++ b/base/xx-apk @@ -13,6 +13,8 @@ if [ -n "$XX_DEBUG_APK" ]; then set -x fi +unset XX_VENDOR # vendor for installing packages is always alpine + for l in $(xx-info env); do export "${l?}" done diff --git a/base/xx-cc b/base/xx-cc index e8c8abaa..ff60b1a2 100755 --- a/base/xx-cc +++ b/base/xx-cc @@ -588,6 +588,7 @@ 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" @@ -598,6 +599,17 @@ EOT ln -s "${f}" "/usr/bin/${target}.cfg" fi + if [ -f /etc/alpine-release ]; then + # if vendor is not alpine then sysroot needs to be linked to the custom vendor + alpinetriple=$(echo "$target" | sed s/-[[:alpha:]][[:alpha:]]*-/-alpine-/) + if [ "$target" != "$alpinetriple" ]; then + # shellcheck disable=SC2044 + for f in $(find / -type d -name "$alpinetriple"); do + ln -s "$alpinetriple" "$(dirname "$f")/$target" + done + fi + fi + if [ "${targetos}" = "darwin" ]; then if ! command -v xcrun 2>/dev/null >/dev/null; then writexcrun diff --git a/base/xx-info b/base/xx-info index 10a88b64..ecf3cd69 100755 --- a/base/xx-info +++ b/base/xx-info @@ -15,7 +15,7 @@ : "${XX_RHEL_ARCH=unknown}" : "${XX_OS_VERSION=unknown}" : "${XX_TRIPLE=unknown-unknown-none}" -: "${XX_VENDOR=unknown}" +: "${XX_VENDOR=}" : "${XX_LIBC=}" usage() { @@ -105,27 +105,33 @@ if [ -n "$TARGETPLATFORM" ]; then fi fi +distro="" # detect distro vendor -if [ "$TARGETOS" = "darwin" ]; then - XX_VENDOR="apple" -elif [ -f /etc/os-release ]; then - # shellcheck disable=SC1091 - if . /etc/os-release 2>/dev/null; then - XX_VENDOR=$ID - XX_OS_VERSION=$VERSION_ID - fi +# shellcheck disable=SC1091 +if . /etc/os-release 2>/dev/null; then + distro=$ID fi vendor="" -case "$XX_VENDOR" in - unknown | debian | ubuntu | rhel | fedora | centos | rocky | ol) ;; - *) +if [ -z "$XX_VENDOR" ]; then + if [ -n "$distro" ]; then + XX_VENDOR="$distro" + fi + if [ "$TARGETOS" = "darwin" ]; then + XX_VENDOR="apple" + fi + if [ -z "$XX_VENDOR" ]; then + XX_VENDOR="unknown" + fi + if [ "$XX_VENDOR" != "unknown" ] && [ "$XX_VENDOR" != "debian" ]; then vendor="-${XX_VENDOR}" - ;; -esac + fi +else + vendor="-${XX_VENDOR}" +fi if [ -z "$XX_LIBC" ]; then - if [ "$XX_VENDOR" = "alpine" ]; then + if [ "$distro" = "alpine" ]; then XX_LIBC="musl" else XX_LIBC="gnu" @@ -389,7 +395,6 @@ case "$1" in echo "XX_OS_VERSION=${XX_OS_VERSION}" echo "XX_ARCH=${TARGETARCH}" echo "XX_MARCH=${XX_MARCH}" - echo "XX_VENDOR=${XX_VENDOR}" if [ "$TARGETOS" = "linux" ]; then echo "XX_PKG_ARCH=${XX_PKG_ARCH}" fi From 50e54fac2c4518e9a0e006be489be61aa0b4c746 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Sun, 29 Aug 2021 19:35:34 -0700 Subject: [PATCH 08/31] apk: add special detection for rust library installs Signed-off-by: Tonis Tiigi --- base/xx-apk | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/base/xx-apk b/base/xx-apk index 956a3192..fcdbb9f8 100755 --- a/base/xx-apk +++ b/base/xx-apk @@ -84,6 +84,7 @@ cmd() { fi n=$# iscompilerrt= + isrustlib= for a in "$@"; do if [ $# = $n ]; then set --; fi case "$a" in @@ -97,6 +98,10 @@ cmd() { iscompilerrt=1 set -- "$@" "$a" ;; + "rust-stdlib") + set -- "$@" rust-stdlib + isrustlib=1 + ;; *) set -- "$@" "$a" ;; @@ -121,6 +126,10 @@ cmd() { 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 } From ab1effd8fee74cc82cf2a6d67538b0cfec0de505 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Tue, 31 Aug 2021 22:00:23 -0700 Subject: [PATCH 09/31] allow setting riscv64 arch to riscv64gc for rust support Signed-off-by: Tonis Tiigi --- base/test-info-alpine.bats | 7 +++++++ base/test-info-debian.bats | 4 ++++ base/xx-cc | 4 ++-- base/xx-info | 6 +++++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/base/test-info-alpine.bats b/base/test-info-alpine.bats index 754a1579..82dfaf6d 100755 --- a/base/test-info-alpine.bats +++ b/base/test-info-alpine.bats @@ -65,6 +65,13 @@ load 'assert' @test "riscv64" { assert_equal "riscv64-alpine-linux-musl" "$(TARGETPLATFORM=linux/riscv64 xx-info triple)" assert_equal "riscv64" "$(TARGETPLATFORM=linux/riscv64 xx-info pkg-arch)" + + assert_equal "riscv64gc-alpine-linux-musl" "$(TARGETPLATFORM=linux/riscv64 RISCV64_TARGET_ARCH=riscv64gc xx-info triple)" + assert_equal "riscv64" "$(TARGETPLATFORM=linux/riscv64 RISCV64_TARGET_ARCH=riscv64gc xx-info pkg-arch)" # does not change +} + +@test "custom-vendor" { + assert_equal "riscv64-unknown-linux-musl" "$(TARGETPLATFORM=linux/riscv64 XX_VENDOR=unknown xx-info triple)" } @test "mips" { diff --git a/base/test-info-debian.bats b/base/test-info-debian.bats index ddca32a4..dd752844 100755 --- a/base/test-info-debian.bats +++ b/base/test-info-debian.bats @@ -67,6 +67,10 @@ fi @test "riscv64" { assert_equal "riscv64-linux-gnu" "$(TARGETPLATFORM=linux/riscv64 xx-info triple)" assert_equal "riscv64" "$(TARGETPLATFORM=linux/riscv64 xx-info pkg-arch)" + + assert_equal "riscv64gc-linux-gnu" "$(TARGETPLATFORM=linux/riscv64 RISCV64_TARGET_ARCH=riscv64gc xx-info triple)" + assert_equal "riscv64" "$(TARGETPLATFORM=linux/riscv64 RISCV64_TARGET_ARCH=riscv64gc xx-info pkg-arch)" # does not change + assert_equal "riscv64gc-unknown-linux-gnu" "$(TARGETPLATFORM=linux/riscv64 RISCV64_TARGET_ARCH=riscv64gc XX_VENDOR=unknown xx-info triple)" } @test "mips" { diff --git a/base/xx-cc b/base/xx-cc index ff60b1a2..de93f523 100755 --- a/base/xx-cc +++ b/base/xx-cc @@ -567,7 +567,7 @@ EOT fi fi - config="--target=${target} -fuse-ld=${linker}" + config="--target=$(echo "${target}" | sed s/^riscv64gc-/riscv64-/) -fuse-ld=${linker}" if [ "${nativeTarget}" != "${target}" ]; then if [ "$targetos" = "darwin" ]; then detectMacOSSDK @@ -601,7 +601,7 @@ EOT if [ -f /etc/alpine-release ]; then # if vendor is not alpine then sysroot needs to be linked to the custom vendor - alpinetriple=$(echo "$target" | sed s/-[[:alpha:]][[:alpha:]]*-/-alpine-/) + alpinetriple=$(echo "$target" | sed s/-[[:alpha:]][[:alpha:]]*-/-alpine-/ | sed s/^riscv64gc-/riscv64-/) if [ "$target" != "$alpinetriple" ]; then # shellcheck disable=SC2044 for f in $(find / -type d -name "$alpinetriple"); do diff --git a/base/xx-info b/base/xx-info index ecf3cd69..45174b29 100755 --- a/base/xx-info +++ b/base/xx-info @@ -273,7 +273,11 @@ case "$TARGETARCH" in XX_DEBIAN_ARCH="riscv64" XX_ALPINE_ARCH="riscv64" XX_RHEL_ARCH="riscv64" - XX_TRIPLE="riscv64${vendor}-linux-${XX_LIBC}" + triplearch="riscv64" + if [ -n "$RISCV64_TARGET_ARCH" ]; then + triplearch="${RISCV64_TARGET_ARCH}" + fi + XX_TRIPLE="${triplearch}${vendor}-linux-${XX_LIBC}" ;; "ppc64le") XX_MARCH="ppc64le" From 3e9dd7f2cdeee701f53f0438e762a0e5c1a59a12 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Tue, 31 Aug 2021 23:45:05 -0700 Subject: [PATCH 10/31] add xx-cargo to simplify rust building Using xx-cargo is optional. Alternative is to install stdlib with xx-apt/xx-apk or with rustup with XX_VENDOR=unknown xx-info. Then CC, and _LINKER needs to be defined via xx-info. Signed-off-by: Tonis Tiigi --- base/xx-cargo | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100755 base/xx-cargo diff --git a/base/xx-cargo b/base/xx-cargo new file mode 100755 index 00000000..bcd6b2dd --- /dev/null +++ b/base/xx-cargo @@ -0,0 +1,83 @@ +#!/usr/bin/env sh + +set -e + +if [ -z "$XX_CARGO_NOLOCK" ]; then + lock="/var/lock/xx-cargo" + exec 9>$lock + flock -x 9 + export XX_CARGO_NOLOCK=1 +fi + +if [ -n "$XX_DEBUG_CARGO" ]; then + set -x +fi + +setuponly= +printtarget= +n=$# +for a in "$@"; do + if [ $# = $n ]; then set --; fi + case "$a" in + "--setup-target-triple") + setuponly=1 + ;; + "--print-target") + printtarget=1 + ;; + *) + set -- "$@" "$a" + ;; + esac +done + +done_file="/.xx-cargo.$(xx-info arch)" + +export RISCV64_TARGET_ARCH=riscv64gc + +rustup= +if which rustup >/dev/null 2>&1; then + rustup=1 +fi + +if [ -n "$rustup" ] || [ ! -f /etc/alpine-release ]; then + export XX_VENDOR="unknown" +fi + +if [ ! -f "$done_file" ]; then + xx-clang --setup-target-triple + if [ ! -d "$(rustc --print sysroot)/lib/rustlib/$(xx-info)" ]; then + if [ -n "$rustup" ]; then + rustup target add "$(xx-info)" 2>/dev/null >/dev/null + elif [ -f /etc/alpine-release ]; then + xx-apk add rust-stdlib 2>/dev/null >/dev/null + else + xx-apt install -y libstd-rust-dev 2>/dev/null >/dev/null + fi + fi + touch "$done_file" +fi + +export "CARGO_TARGET_$(xx-info | tr '[:lower:]' '[:upper:]' | tr - _)_LINKER=$(xx-info)-clang" +if [ -n "$XX_RUSTFLAGS" ]; then + export "CARGO_TARGET_$(xx-info | tr '[:lower:]' '[:upper:]' | tr - _)_RUSTFLAGS=$XX_RUSTFLAGS" +fi +export "CC_$(xx-info | tr - _)=$(xx-info)-clang" + +if which "qemu-$(RISCV64_TARGET_ARCH='' xx-info march)" >/dev/null 2>&1; then + export "CARGO_TARGET_$(xx-info | tr '[:lower:]' '[:upper:]' | tr - _)_RUNNER=qemu-$(RISCV64_TARGET_ARCH='' xx-info march)" + if [ -f /etc/alpine-release ]; then + export "QEMU_LD_PREFIX=/$(RISCV64_TARGET_ARCH='' xx-info)/" + else + export "QEMU_LD_PREFIX=/lib/$(RISCV64_TARGET_ARCH='' XX_VENDOR='' xx-info)/" + fi +fi + +if [ -n "$printtarget" ]; then + xx-info + exit 0 +fi + +if [ -z "$setuponly" ]; then + cargo "$@" --target="$(xx-info)" +fi From b8dde93466ab3bbb6cbd3fb53086613cf1fdeec8 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Tue, 27 Sep 2022 14:18:25 +0200 Subject: [PATCH 11/31] xx-info: fix vendor Signed-off-by: CrazyMax --- base/xx-info | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/base/xx-info b/base/xx-info index 45174b29..b45cc4e7 100755 --- a/base/xx-info +++ b/base/xx-info @@ -123,12 +123,11 @@ if [ -z "$XX_VENDOR" ]; then if [ -z "$XX_VENDOR" ]; then XX_VENDOR="unknown" fi - if [ "$XX_VENDOR" != "unknown" ] && [ "$XX_VENDOR" != "debian" ]; then - vendor="-${XX_VENDOR}" - fi -else - vendor="-${XX_VENDOR}" fi +case "$XX_VENDOR" in + debian | ubuntu | rhel | fedora | centos | rocky | ol) ;; + *) vendor="-${XX_VENDOR}" ;; +esac if [ -z "$XX_LIBC" ]; then if [ "$distro" = "alpine" ]; then @@ -399,6 +398,7 @@ case "$1" in echo "XX_OS_VERSION=${XX_OS_VERSION}" echo "XX_ARCH=${TARGETARCH}" echo "XX_MARCH=${XX_MARCH}" + echo "XX_VENDOR=${XX_VENDOR}" if [ "$TARGETOS" = "linux" ]; then echo "XX_PKG_ARCH=${XX_PKG_ARCH}" fi From 8b587809d5bc5ea6724b1ec825c44fbeb505a505 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Wed, 19 Oct 2022 14:34:47 -0700 Subject: [PATCH 12/31] github: allow debian backports error Signed-off-by: Tonis Tiigi --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d70d37fd..9b719edb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,7 +54,7 @@ jobs: - image: debian:buster-backports typ: debian - allow-failure: false + allow-failure: true - image: debian:bullseye typ: debian From 992c8a0fff6edcaed180ccaf3f70806565f40117 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sun, 30 Oct 2022 16:05:21 +0100 Subject: [PATCH 13/31] ci: add concurrency group Signed-off-by: CrazyMax --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9b719edb..f198a2f3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,9 @@ name: build +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + on: workflow_dispatch: push: From 6fafde046de1d547390f37ff78b3586ad21259c2 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sun, 30 Oct 2022 14:37:24 +0100 Subject: [PATCH 14/31] xx-cargo: allow arbitrary RISCV64_TARGET_ARCH value Signed-off-by: CrazyMax --- base/xx-cargo | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/base/xx-cargo b/base/xx-cargo index bcd6b2dd..395a6424 100755 --- a/base/xx-cargo +++ b/base/xx-cargo @@ -33,7 +33,9 @@ done done_file="/.xx-cargo.$(xx-info arch)" -export RISCV64_TARGET_ARCH=riscv64gc +if [ -z "$RISCV64_TARGET_ARCH" ]; then + export RISCV64_TARGET_ARCH=riscv64gc +fi rustup= if which rustup >/dev/null 2>&1; then @@ -79,5 +81,5 @@ if [ -n "$printtarget" ]; then fi if [ -z "$setuponly" ]; then - cargo "$@" --target="$(xx-info)" + exec cargo "$@" --target="$(xx-info)" fi From 7d24a98d5d55aac111f66399429d0eea3b966ae4 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sun, 30 Oct 2022 14:38:23 +0100 Subject: [PATCH 15/31] xx-cargo: fix vendor to install rust stdlib package Signed-off-by: CrazyMax --- base/xx-cargo | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/base/xx-cargo b/base/xx-cargo index 395a6424..ae83815c 100755 --- a/base/xx-cargo +++ b/base/xx-cargo @@ -42,6 +42,7 @@ if which rustup >/dev/null 2>&1; then rustup=1 fi +vendor=$XX_VENDOR if [ -n "$rustup" ] || [ ! -f /etc/alpine-release ]; then export XX_VENDOR="unknown" fi @@ -52,9 +53,11 @@ if [ ! -f "$done_file" ]; then if [ -n "$rustup" ]; then rustup target add "$(xx-info)" 2>/dev/null >/dev/null elif [ -f /etc/alpine-release ]; then - xx-apk add rust-stdlib 2>/dev/null >/dev/null + # XX_VENDOR overrided to match the distrib one to install packages + XX_VENDOR=$vendor xx-apk add rust-stdlib 2>/dev/null >/dev/null else - xx-apt install -y libstd-rust-dev 2>/dev/null >/dev/null + # XX_VENDOR overrided to match the distrib one to install packages + XX_VENDOR=$vendor xx-apt-get install -y libstd-rust-dev 2>/dev/null >/dev/null fi fi touch "$done_file" From 6c03d179741fcab2fbdb2d6787b520be1906de73 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sun, 30 Oct 2022 15:04:19 +0100 Subject: [PATCH 16/31] allow setting custom arch for arm for rust support Signed-off-by: CrazyMax --- base/test-info-alpine.bats | 4 ++++ base/test-info-debian.bats | 4 ++++ base/xx-cargo | 11 +++++++---- base/xx-info | 9 ++++++--- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/base/test-info-alpine.bats b/base/test-info-alpine.bats index 82dfaf6d..b01b6c7e 100755 --- a/base/test-info-alpine.bats +++ b/base/test-info-alpine.bats @@ -33,6 +33,10 @@ load 'assert' assert_equal "armv7-alpine-linux-musleabihf" "$(TARGETPLATFORM=linux/arm xx-info triple)" assert_equal "armv7" "$(TARGETPLATFORM=linux/arm xx-info pkg-arch)" assert_equal "v7" "$(TARGETPLATFORM=linux/arm/v7 xx-info variant)" + + assert_equal "arm-alpine-linux-musleabihf" "$(TARGETPLATFORM=linux/arm ARM_TARGET_ARCH=arm xx-info triple)" + assert_equal "armv7" "$(TARGETPLATFORM=linux/arm ARM_TARGET_ARCH=arm xx-info pkg-arch)" # does not change + assert_equal "v7" "$(TARGETPLATFORM=linux/arm/v7 ARM_TARGET_ARCH=arm xx-info variant)" # does not change } @test "armv6" { diff --git a/base/test-info-debian.bats b/base/test-info-debian.bats index dd752844..3654f1ed 100755 --- a/base/test-info-debian.bats +++ b/base/test-info-debian.bats @@ -35,6 +35,10 @@ fi assert_equal "arm-linux-gnueabihf" "$(TARGETPLATFORM=linux/arm xx-info triple)" assert_equal "armhf" "$(TARGETPLATFORM=linux/arm xx-info pkg-arch)" assert_equal "v7" "$(TARGETPLATFORM=linux/arm xx-info variant)" + + assert_equal "armv7-linux-gnueabihf" "$(TARGETPLATFORM=linux/arm ARM_TARGET_ARCH=armv7 xx-info triple)" + assert_equal "armhf" "$(TARGETPLATFORM=linux/arm ARM_TARGET_ARCH=armv7 xx-info pkg-arch)" # does not change + assert_equal "armv7-unknown-linux-gnueabihf" "$(TARGETPLATFORM=linux/arm ARM_TARGET_ARCH=armv7 XX_VENDOR=unknown xx-info triple)" } @test "armv6" { diff --git a/base/xx-cargo b/base/xx-cargo index ae83815c..788ed832 100755 --- a/base/xx-cargo +++ b/base/xx-cargo @@ -36,6 +36,9 @@ done_file="/.xx-cargo.$(xx-info arch)" if [ -z "$RISCV64_TARGET_ARCH" ]; then export RISCV64_TARGET_ARCH=riscv64gc fi +if [ -z "$ARM_TARGET_ARCH" ]; then + export ARM_TARGET_ARCH=armv7 +fi rustup= if which rustup >/dev/null 2>&1; then @@ -69,12 +72,12 @@ if [ -n "$XX_RUSTFLAGS" ]; then fi export "CC_$(xx-info | tr - _)=$(xx-info)-clang" -if which "qemu-$(RISCV64_TARGET_ARCH='' xx-info march)" >/dev/null 2>&1; then - export "CARGO_TARGET_$(xx-info | tr '[:lower:]' '[:upper:]' | tr - _)_RUNNER=qemu-$(RISCV64_TARGET_ARCH='' xx-info march)" +if which "qemu-$(RISCV64_TARGET_ARCH='' ARM_TARGET_ARCH='' xx-info march)" >/dev/null 2>&1; then + export "CARGO_TARGET_$(xx-info | tr '[:lower:]' '[:upper:]' | tr - _)_RUNNER=qemu-$(RISCV64_TARGET_ARCH='' ARM_TARGET_ARCH='' xx-info march)" if [ -f /etc/alpine-release ]; then - export "QEMU_LD_PREFIX=/$(RISCV64_TARGET_ARCH='' xx-info)/" + export "QEMU_LD_PREFIX=/$(RISCV64_TARGET_ARCH='' ARM_TARGET_ARCH='' xx-info)/" else - export "QEMU_LD_PREFIX=/lib/$(RISCV64_TARGET_ARCH='' XX_VENDOR='' xx-info)/" + export "QEMU_LD_PREFIX=/lib/$(RISCV64_TARGET_ARCH='' ARM_TARGET_ARCH='' XX_VENDOR='' xx-info)/" fi fi diff --git a/base/xx-info b/base/xx-info index b45cc4e7..30b72708 100755 --- a/base/xx-info +++ b/base/xx-info @@ -238,10 +238,13 @@ case "$TARGETARCH" in XX_DEBIAN_ARCH="armhf" XX_ALPINE_ARCH="armv7" XX_RHEL_ARCH="armv7hl" - XX_TRIPLE="arm${vendor}-linux-${XX_LIBC}eabihf" - if [ "$XX_VENDOR" = "alpine" ]; then - XX_TRIPLE="armv7${vendor}-linux-${XX_LIBC}eabihf" + triplearch="arm" + if [ -n "$ARM_TARGET_ARCH" ]; then + triplearch="${ARM_TARGET_ARCH}" + elif [ "$XX_VENDOR" = "alpine" ]; then + triplearch="armv7" fi + XX_TRIPLE="${triplearch}${vendor}-linux-${XX_LIBC}eabihf" if [ "$TARGETVARIANT" = "v6" ]; then XX_MARCH="armv6l" XX_DEBIAN_ARCH="armel" From ecf350ac4609ae8fa0fb72be6c028ad8ccb2b452 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Mon, 31 Oct 2022 11:05:20 +0100 Subject: [PATCH 17/31] xx-cargo: display command output on error when installing deps Signed-off-by: CrazyMax --- base/xx-cargo | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/base/xx-cargo b/base/xx-cargo index 788ed832..e08e4d11 100755 --- a/base/xx-cargo +++ b/base/xx-cargo @@ -2,6 +2,13 @@ set -e +execSilent() { + if ! cmdout=$("$@" 2>&1); then + echo "$cmdout" >&2 + exit 1 + fi +} + if [ -z "$XX_CARGO_NOLOCK" ]; then lock="/var/lock/xx-cargo" exec 9>$lock @@ -54,13 +61,13 @@ if [ ! -f "$done_file" ]; then xx-clang --setup-target-triple if [ ! -d "$(rustc --print sysroot)/lib/rustlib/$(xx-info)" ]; then if [ -n "$rustup" ]; then - rustup target add "$(xx-info)" 2>/dev/null >/dev/null + 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 xx-apk add rust-stdlib 2>/dev/null >/dev/null + XX_VENDOR=$vendor execSilent xx-apk add rust-stdlib else # XX_VENDOR overrided to match the distrib one to install packages - XX_VENDOR=$vendor xx-apt-get install -y libstd-rust-dev 2>/dev/null >/dev/null + XX_VENDOR=$vendor execSilent xx-apt-get install -y libstd-rust-dev fi fi touch "$done_file" From 2db9dfb695fe4202f1a5252d8e885af4c27c2bf9 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sun, 30 Oct 2022 15:52:39 +0100 Subject: [PATCH 18/31] xx-cargo: add tests Signed-off-by: CrazyMax --- base/Dockerfile | 2 + base/fixtures/hello_cargo/Cargo.toml | 8 ++ base/fixtures/hello_cargo/src/main.rs | 3 + base/test-cargo.bats | 144 ++++++++++++++++++++++++++ 4 files changed, 157 insertions(+) create mode 100644 base/fixtures/hello_cargo/Cargo.toml create mode 100644 base/fixtures/hello_cargo/src/main.rs create mode 100755 base/test-cargo.bats diff --git a/base/Dockerfile b/base/Dockerfile index f0f09dcf..484249e2 100644 --- a/base/Dockerfile +++ b/base/Dockerfile @@ -75,6 +75,8 @@ RUN --mount=type=cache,target=/pkg-cache \ RUN --mount=type=cache,target=/pkg-cache \ --mount=target=/root/.cache,type=cache \ [ "${TEST_CMDS:-golang}" = "${TEST_CMDS#*golang}" ] && exit 0; ./test-go.bats +RUN --mount=type=cache,target=/pkg-cache \ + [ "${TEST_CMDS:-cargo}" = "${TEST_CMDS#*cargo}" ] && exit 0; ./test-cargo.bats FROM --platform=${BUILDPLATFORM} alpine AS libtapi-base RUN apk add --no-cache git clang lld cmake make python3 bash diff --git a/base/fixtures/hello_cargo/Cargo.toml b/base/fixtures/hello_cargo/Cargo.toml new file mode 100644 index 00000000..ae9aab5a --- /dev/null +++ b/base/fixtures/hello_cargo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "hello_cargo" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/base/fixtures/hello_cargo/src/main.rs b/base/fixtures/hello_cargo/src/main.rs new file mode 100644 index 00000000..e4120e08 --- /dev/null +++ b/base/fixtures/hello_cargo/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("hello cargo"); +} diff --git a/base/test-cargo.bats b/base/test-cargo.bats new file mode 100755 index 00000000..73de90ef --- /dev/null +++ b/base/test-cargo.bats @@ -0,0 +1,144 @@ +#!/usr/bin/env bats + +load 'assert' +load 'test_helper' + +cleanPackages() { + for p in linux/amd64 linux/arm64 linux/ppc64le linux/s390x linux/386 linux/arm/v7 linux/arm/v6; do + TARGETPLATFORM=$p xxdel xx-c-essentials + root=/$(TARGETPLATFORM=$p xx-info triple) + if [ -d "$root" ] && [ "$root" != "/" ]; then + rm -rf "$root" + fi + done + del cargo rust + del pkgconfig || del pkg-config + rm -rf "$HOME/.cargo" /.xx-cargo* || true +} + +@test "nocargo" { + cleanPackages + add clang + run xx-cargo --version + assert_failure + assert_output --partial "cargo: not found" +} + +testHelloCargo() { + rm -f "/.xx-cargo.$(xx-info arch)" + run xxadd xx-c-essentials + assert_success + run xx-cargo build --verbose --color=never --manifest-path=./fixtures/hello_cargo/Cargo.toml --release --target-dir /tmp/cargobuild + assert_success + xx-verify /tmp/cargobuild/$(xx-cargo --print-target)/release/hello_cargo + if ! xx-info is-cross; then + run /tmp/cargobuild/$(xx-cargo --print-target)/release/hello_cargo + assert_success + assert_output "hello cargo" + fi + rm -rf /tmp/cargobuild +} + +testHelloCargoRustup() { + export PATH="$HOME/.cargo/bin:$PATH" + testHelloCargo +} + +@test "install-rustup" { + add clang lld curl ca-certificates + assert_success + run sh -c "curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable --no-modify-path --profile minimal" + assert_success +} + +@test "amd64-hellocargo-rustup" { + export TARGETARCH=amd64 + testHelloCargoRustup +} + +@test "arm64-hellocargo-rustup" { + export TARGETARCH=arm64 + testHelloCargoRustup +} + +@test "arm-hellocargo-rustup" { + export TARGETARCH=arm + testHelloCargoRustup +} + +@test "ppc64le-hellocargo-rustup" { + if [ -f /etc/alpine-release ]; then + skip "rust stdlib not yet available for powerpc64le-unknown-linux-musl" + fi + export TARGETARCH=ppc64le + testHelloCargoRustup +} + +@test "riscv64-hellocargo-rustup" { + if ! supportRiscVCGo; then + skip "RISC-V not supported" # rust stdlib package not available + fi + export TARGETARCH=riscv64 + testHelloCargoRustup +} + +@test "386-hellocargo-rustup" { + export TARGETARCH=386 + testHelloCargoRustup +} + +@test "uninstall-rustup" { + export PATH="$HOME/.cargo/bin:$PATH" + rustup self uninstall -y +} + +@test "install-rustpkg" { + cleanPackages + add clang lld + case "$(xx-info vendor)" in + alpine) + add cargo rust + ;; + debian | ubuntu) + add cargo + ;; + esac +} + +@test "amd64-hellocargo-rustpkg" { + export TARGETARCH=amd64 + testHelloCargo +} + +@test "arm64-hellocargo-rustpkg" { + export TARGETARCH=arm64 + testHelloCargo +} + +@test "arm-hellocargo-rustpkg" { + export TARGETARCH=arm + testHelloCargo +} + +@test "ppc64le-hellocargo-rustpkg" { + export TARGETARCH=ppc64le + testHelloCargo +} + +@test "riscv64-hellocargo-rustpkg" { + if ! supportRiscVCGo; then + skip "RISC-V not supported" # rust stdlib package not available + fi + export TARGETARCH=riscv64 + export RISCV64_TARGET_ARCH=riscv64 + testHelloCargo +} + +@test "386-hellocargo-rustpkg" { + export TARGETARCH=386 + testHelloCargo +} + +@test "clean-packages" { + cleanPackages +} From 4fae89309abd9aa06035910a5f325352535bc08c Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Mon, 31 Oct 2022 06:43:05 +0100 Subject: [PATCH 19/31] docs: refactor README Signed-off-by: CrazyMax --- README.md | 146 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 83 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index a205c4ba..3cdd7a9e 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,40 @@ -## xx - Dockerfile cross-compilation helpers +# xx - Dockerfile cross-compilation helpers + +[![CI Status](https://github.com/tonistiigi/xx/workflows/build/badge.svg)](https://github.com/tonistiigi/xx/actions?query=workflow%3Abuild) +[![Docker Pulls](https://img.shields.io/docker/pulls/tonistiigi/xx.svg?logo=docker)](https://hub.docker.com/r/tonistiigi/xx/) `xx` provides tools to support cross-compilation from Dockerfiles that understand the `--platform` flag passed in from `docker build` or `docker buildx build`. These helpers allow you to build multi-platform images from any architecture into any architecture supported by your compiler with native performance. Adding `xx` to your Dockerfile should only need minimal updates and should not require custom conditions for specific architectures. -### Dockerfile cross-compilation primer +___ + +* [Dockerfile cross-compilation primer](#dockerfile-cross-compilation-primer) +* [Installation](#installation) +* [Supported targets](#supported-targets) +* [`xx-info` - Information about the build context](#xx-info---information-about-the-build-context) + * [Parsing current target](#parsing-current-target) + * [Architecture formats](#architecture-formats) + * [Target triple](#target-triple) + * [Build context](#build-context) +* [`xx-apk`, `xx-apt`, `xx-apt-get` - Installing packages for target architecture](#xx-apk-xx-apt-xx-apt-get---installing-packages-for-target-architecture) +* [`xx-verify` - Verifying compilation results](#xx-verify---verifying-compilation-results) +* [C/C++](#cc) + * [Building on Alpine](#building-on-alpine) + * [Building on Debian](#building-on-debian) + * [Wrapping as default](#wrapping-as-default) +* [Autotools](#autotools) +* [CMake](#cmake) +* [Go / Cgo](#go--cgo) +* [External SDK support](#external-sdk-support) +* [Used by](#used-by) +* [Issues](#issues) + +## Dockerfile cross-compilation primer Cross-compilation can be achieved in Dockerfiles by using multi-stage builds and defining some of the stages to always run on the native architecture used by the builder and execute the cross-compiling compiler. By default, a Dockerfile stage started with `FROM` keyword default to the target architecture, but this can be overridden with a `FROM --platform` flag. Using [automatic platform ARGs in global scope](https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope), the platform of the cross-compiler stage can be set to `$BUILDPLATFORM` while the value of `$TARGETPLATFORM` can be passed to the compiler with an environment variable. After compilation, the resulting assets can be copied into another stage that will become the result of the build. Usually, this stage does not use `FROM --platform` so that every stage is based on the expected target architecture. -``` +```dockerfile FROM --platform=$BUILDPLATFORM alpine AS xbuild ARG TARGETPLATFORM RUN ./compile --target=$TARGETPLATFORM -o /out/myapp @@ -17,12 +43,11 @@ FROM alpine COPY --from=xbuild /out/myapp /bin ``` - -### Installation +## Installation `xx` is distributed with a Docker image `tonistiigi/xx` that contains a collection of helper scripts that read `TARGET*` environment variables to automatically configure the compilation targets. The scripts are based on Posix Shell, so they should work on top of any image but currently `xx` is expected to work on Alpine and Debian/Ubuntu based distros. In order to avoid unexpected changes, you may want to pin the image using an immutable digest. Although `xx` only contains shell scripts that are identical for every platform it is recommended to also import `xx` with `FROM --platform=$BUILDPLATFORM`, so that import commands are shared for all compilation targets. -``` +```dockerfile FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx FROM --platform=$BUILDPLATFORM alpine @@ -36,7 +61,7 @@ RUN xx-info env `xx` currently contains `xx-info`, `xx-apk`, `xx-apt-get`, `xx-cc`, `xx-c++`, `xx-clang`, `xx-clang++`, `xx-go`, `xx-verify`. `xx-clang` (and its aliases) creates additional aliases, eg. `${triple}-clang`, `${triple}-pkg-config`, on first invocation or on `xx-clang --setup-target-triple` call. -### Supported targets +## Supported targets `xx` supports building from and into Linux amd64, arm64, arm/v7, s390x, ppc64le and 386, and Alpine, Debian and Ubuntu. Risc-V is supported for Go builds and for newer distros that provide Risc-V packages like `alpine:edge` or `debian:sid`. @@ -44,18 +69,17 @@ Go builds that don't depend on system packages can additionally target MacOS and `xx-info` command also works on RHEL-style distros but no support is provided for package manager wrappers(eg. yum, dnf) there. - -### xx-info - Information about the build context +## `xx-info` - Information about the build context `xx-info` command returns normalized information about the current build context. It allows you to get various information about your build target and configuration and avoid the need for converting from one format to another in your own code. Invoking `xx-info` without any additional arguments will invoke `xx-info triple`. -#### Parsing current target +### Parsing current target - `xx-info os` - prints operating system component of TARGETPLATFORM (linux,darwin,windows,wasi) - `xx-info arch` - architecture component of TARGETPLATFORM - `xx-info variant` - variant component of TARGETPLATFORM if architecture is arm (eg. v7 -#### Architecture formats +### Architecture formats These commands return architecture names as used by specific tools to avoid conversion and tracking exceptions in your own code. E.g. arm64 repositories are called `aarch64` in Alpine, but `arm64` in Debian. `uname -m` returns `aarch64` in Linux, but `arm64` in Darwin etc. @@ -65,7 +89,7 @@ These commands return architecture names as used by specific tools to avoid conv - `xx-info rhel-arch` - Target architecture for [RPM package repositories](https://docs.fedoraproject.org/ro/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch01s03.html) - `xx-info pkg-arch` - Either alpine-arch, debian-arch or rhel-arch depending on the context -#### Target triple +### Target triple Target triple is the target format taken as input in various gcc and llvm based compilers. @@ -73,13 +97,13 @@ Target triple is the target format taken as input in various gcc and llvm based - `xx-info vendor` - Vendor component of target triple - `xx-info libc` - Used libc (musl or gnu) -#### Build context +### Build context - `xx-info is-cross` - Exit cleanly if target is not native architecture - `xx-info env` - Print XX_* variables defining target environment -``` -> xx-info env +```console +$ xx-info env XX_OS=linux XX_MARCH=x86_64 XX_VENDOR=alpine @@ -91,18 +115,17 @@ TARGETARCH=amd64 TARGETVARIANT= ``` - -### xx-apk, xx-apt, xx-apt-get - Installing packages for target architecture +## `xx-apk`, `xx-apt`, `xx-apt-get` - Installing packages for target architecture These scripts allow managing packages (most commonly installing new packages) from either Alpine or Debian repositories. They can be invoked with any arguments regular `apk` or `apt/apt-get` commands accept. If cross-compiling for non-native architectures, the repositories for the target architecture are added automatically, and packages are installed from there. On Alpine, installing packages for a different architecture under the same root is not allowed, so `xx-apk` installs packages under a secondary root `/${triple}`. These scripts are meant for installing headers and libraries that compilers may need. To avoid unnecessary garbage, the non-native binaries under `*/bin` are skipped on installation. -``` +```dockerfile # alpine ARG TARGETPLATFORM RUN xx-apk add --no-cache musl-dev zlib-dev ``` -``` +```dockerfile # debian ARG TARGETPLATFORM RUN xx-apt-get install -y libc6-dev zlib1g-dev @@ -110,17 +133,17 @@ RUN xx-apt-get install -y libc6-dev zlib1g-dev Installing two meta-libraries, `xx-c-essentials`, `xx-cxx-essentials` is also allowed that expand the minimum necessary packages for either base image. -### xx-verify - Verifying compilation results +## `xx-verify` - Verifying compilation results `xx-verify` allows verifying that the cross-compile toolchain was correctly configured and outputted binaries for the expected target platform. `xx-verify` works by calling `file` utility and comparing the expected output. Optionally `--static` option can be passed to verify that the compiler produced a static binary that can be safely copied to another Dockerfile stage without runtime libraries. If the binary does not match the expected value, `xx-verify` returns with a non-zero exit code and error message. -``` +```dockerfile ARG TARGETPLATFORM RUN xx-clang --static -o /out/myapp app.c && \ xx-verify --static /out/myapp ``` -### C/C++ +## C/C++ The recommended method for C-based build is to use `clang` via `xx-clang` wrapper. Clang is natively a cross-compiler, but in order to use it, you also need a linker, compiler-rt or libgcc, and a C library(musl or glibc). All these are available as packages in Alpine and Debian based distros. Clang and linker are binaries and should be installed for your build architecture, while libgcc and C library should be installed for your target architecture. @@ -138,12 +161,12 @@ Alias commands include: Alias commands can be called directly and always build the configuration specified by their name, even if `TARGETPLATFORM` value has changed. -#### Building on Alpine +### Building on Alpine On Alpine, there is no special package for `libgcc` so you need to install `gcc` package with `xx-apk` even though the build happens through clang. To use compiler-rt instead of `libgcc` `--rtlib` needs to be passed manually. We will probably add default detection/loading for compiler-rt in the future to simplify this part. Default libc used in Alpine is [Musl](https://www.musl-libc.org/) that can be installed with `musl-dev` package. -``` -... +```dockerfile +# ... RUN apk add clang lld # copy source ARG TARGETPLATFORM @@ -154,33 +177,33 @@ RUN xx-clang -o hello hello.c && \ Clang binary can also be called directly with `--target` flag if you want to avoid `xx-` prefixes. `--print-target-triple` is a built-in flag in clang that can be used to query to correct default value. -``` -... +```dockerfile +# ... RUN xx-apk add g++ RUN clang++ --target=$(xx-clang --print-target-triple) -o hello hello.cc ``` On the first invocation, aliases with `triple-` prefix are set up so the following also works: -``` -... +```dockerfile +# ... RUN $(xx-clang --print-target-triple)-clang -o hello hello.c ``` If you prefer aliases to be created as a separate step on a separate layer, you can use `--setup-target-triple`. -``` -... +```dockerfile +# ... RUN xx-clang --setup-target-triple RUN $(xx-info)-clang -o hello hello.c ``` -#### Building on Debian +### Building on Debian Building on Debian/Ubuntu is very similar. The only required dependency that needs to be installed with `xx-apt` is `libc6-dev` or `libstdc++-N-dev` for C++. -``` -... +```dockerfile +# ... RUN apt-get update && apt-get instal -y clang lld # copy source ARG TARGETPLATFORM @@ -192,15 +215,15 @@ Refer to the previous section for other variants. If you wish to build with GCC instead of Clang you need to install `gcc` and `binutils` packages additionally with `xx-apt-get`. `xx-apt-get` will automatically install the packages that generate binaries for the current target architecture. You can then call GCC directly with the correct target triple. Note that Debian currently only provides GCC cross-compilation packages if your native platform is amd64 or arm64. -``` -... +```dockerfile +# ... # copy source ARG TARGETPLATFORM RUN xx-apt-get install -y binutils gcc libc6-dev RUN $(xx-info)-gcc -o hello hello.c ``` -#### Wrapping as default +### Wrapping as default Special flags `xx-clang --wrap` and `xx-clang --unwarp` can be used to override the default behavior of `clang` with `xx-clang` in the extreme cases where your build scripts have no way to point to alternative compiler names. @@ -219,40 +242,38 @@ x86_64-alpine-linux-musl aarch64-alpine-linux-musl ``` - -### Autotools +## Autotools Autotools has [built-in support](https://www.gnu.org/software/automake/manual/html_node/Cross_002dCompilation.html) for cross-compilation that works by passing `--host`, `--build`, and `--target` flags to the configure script. `--host` defines the target architecture of the build result, `--build` defines compilers native architecture(used for compiling helper tools etc.), and `--target` defines an architecture that the binary returns if it is running as a compiler of other binaries. Usually, only `--host` is needed. -``` -... +```dockerfile +# ... ARG TARGETPLATFORM RUN ./configure --host=$(xx-clang --print-target-triple) && make ``` If you need to pass `--build`, you can temporarily reset the `TARGETPLATFORM` variable to get the system value. -``` +```dockerfile ARG TARGETPLATFORM RUN ./configure --host=$(xx-clang --print-target-triple) --build=$(TARGETPLATFORM= xx-clang --print-target-triple) && make ``` Sometimes `configure` scripts misbehave and don't work correctly unless the name of the C compiler is passed directly. In these cases, you can use overrides like: -``` +```dockerfile RUN CC=xx-clang ./configure ... ``` -``` +```dockerfile RUN ./configure --with-cc=xx-clang ... ``` -``` +```dockerfile RUN ./configure --with-cc=$(xx-clang --print-target-triple)-clang ... ``` - -### CMake +## CMake In order to make cross-compiling with CMake easier, `xx-clang` has a special flag `xx-clang --print-cmake-defines`. Running that command returns the following Cmake definitions: @@ -268,7 +289,7 @@ In order to make cross-compiling with CMake easier, `xx-clang` has a special fla Usually, this should be enough to pick up the correct configuration. -``` +```dockerfile RUN apk add cmake clang lld ARG TARGETPLATFORM RUN xx-apk musl-dev gcc @@ -276,23 +297,23 @@ RUN mkdir build && cd build && \ cmake $(xx-clang --print-cmake-defines) .. ``` -### Go / Cgo +## Go / Cgo Building Go can be achieved with the `xx-go` wrapper that automatically sets up values for `GOOS`, `GOARCH`, `GOARM` etc. It also sets up `pkg-config` and C compiler if building with CGo. Note that by default, CGo is enabled in Go when compiling for native architecture and disabled when cross-compiling. This can easily produce unexpected results; therefore, you should always define either `CGO_ENABLED=1` or `CGO_ENABLED=0` depending on if you expect your compilation to use CGo or not. -``` +```dockerfile FROM --platform=$BUILDPLATFORM golang:alpine -... +# ... ARG TARGETPLATFORM ENV CGO_ENABLED=0 RUN xx-go build -o hello ./hello.go && \ xx-verify hello ``` -``` +```dockerfile FROM --platform=$BUILDPLATFORM golang:alpine RUN apk add clang lld -... +# ... ARG TARGETPLATFORM RUN xx-apk add musl-dev gcc ENV CGO_ENABLED=1 @@ -302,22 +323,22 @@ RUN xx-go build -o hello ./hello.go && \ If you want to make `go` compiler cross-compile by default, you can use `xx-go --wrap` and `xx-go --unwrap` -``` -... +```dockerfile +# ... RUN xx-go --wrap RUN go build -o hello hello.go && \ xx-verify hello ``` -### External SDK support +## External SDK support In addition to Linux targets, `xx` can also build binaries for MacOS and Windows. When building MacOS binaries from C, external MacOS SDK is needed in `/xx-sdk` directory. Such SDK can be built, for example, with [gen_sdk_package script in osxcross project](https://github.com/tpoechtrager/osxcross/blob/master/tools/gen_sdk_package.sh). Please consult XCode license terms when making such an image. `RUN --mount` syntax can be used in Dockerfile in order to avoid copying SDK files. No special tooling such as `ld64` linker is required in the image itself. Building Windows binaries from C/CGo is currently a work in progress and not functional. -``` -#syntax=docker/dockerfile:1.2 -... +```dockerfile +# syntax=docker/dockerfile:1.2 +# ... RUN apk add clang lld ARG TARGETPLATFORM RUN --mount=from=my/sdk-image,target=/xx-sdk,src=/xx-sdk \ @@ -328,14 +349,13 @@ FROM scratch COPY --from=build /hello / ``` -``` +```console docker buildx build --platform=darwin/amd64,darwin/arm64 -o bin . ``` `-o/--output` flag can be used to export binaries out from the builder without creating a container image. - -### Used by +## Used by These projects, as well as [xx Dockerfile](https://github.com/tonistiigi/xx/blob/41f7f39551857836e691da81580296ba5acf6ac3/base/Dockerfile) can be used for reference. @@ -345,6 +365,6 @@ These projects, as well as [xx Dockerfile](https://github.com/tonistiigi/xx/blob - [Docker Buildx](https://github.com/docker/buildx/blob/4fec647b9d8f34f8569141124d8462c912858144/Dockerfile) - [Containerd](https://github.com/containerd/containerd/blob/9e7910ebdcbf3bf10ebd0a282ab9996572e38749/.github/workflows/release/Dockerfile) -### Issues +## Issues `xx` project welcomes contributions if you notice any issues or want to extend the capabilities with new features. We are also interested in cases where a popular project does not compile easily with `xx` so it can be improved, and tests can be added that try building these projects when `xx` gets updated. If you want to add support for a new architecture or language, please open an issue first to verify that the proposal matches the scope or `xx`. From 3a5d8189b85cf4abdd0b8c3fe3f96ce3f45e33e5 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Mon, 31 Oct 2022 07:18:45 +0100 Subject: [PATCH 20/31] docs: rust support Signed-off-by: CrazyMax --- README.md | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 120 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3cdd7a9e..0021e45f 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,9 @@ ___ * [Autotools](#autotools) * [CMake](#cmake) * [Go / Cgo](#go--cgo) +* [Rust](#rust) + * [Building on Alpine](#building-on-alpine-1) + * [Building on Debian](#building-on-debian-1) * [External SDK support](#external-sdk-support) * [Used by](#used-by) * [Issues](#issues) @@ -59,13 +62,13 @@ ARG TARGETPLATFORM RUN xx-info env ``` -`xx` currently contains `xx-info`, `xx-apk`, `xx-apt-get`, `xx-cc`, `xx-c++`, `xx-clang`, `xx-clang++`, `xx-go`, `xx-verify`. `xx-clang` (and its aliases) creates additional aliases, eg. `${triple}-clang`, `${triple}-pkg-config`, on first invocation or on `xx-clang --setup-target-triple` call. +`xx` currently contains `xx-info`, `xx-apk`, `xx-apt-get`, `xx-cc`, `xx-c++`, `xx-clang`, `xx-clang++`, `xx-go`, `xx-cargo`, `xx-verify`. `xx-clang` (and its aliases) creates additional aliases, eg. `${triple}-clang`, `${triple}-pkg-config`, on first invocation or on `xx-clang --setup-target-triple` call. ## Supported targets -`xx` supports building from and into Linux amd64, arm64, arm/v7, s390x, ppc64le and 386, and Alpine, Debian and Ubuntu. Risc-V is supported for Go builds and for newer distros that provide Risc-V packages like `alpine:edge` or `debian:sid`. +`xx` supports building from and into Linux amd64, arm64, arm/v7, s390x, ppc64le and 386, and Alpine, Debian and Ubuntu. Risc-V is supported for Go and Rust builds and for newer distros that provide Risc-V packages like `alpine:edge` or `debian:sid`. -Go builds that don't depend on system packages can additionally target MacOS and Windows on all architectures. C/C++/CGo builds are supported for MacOS targets when an external SDK image is provided. +Go builds that don't depend on system packages can additionally target MacOS and Windows on all architectures. C/C++/CGo/Rust builds are supported for MacOS targets when an external SDK image is provided. `xx-info` command also works on RHEL-style distros but no support is provided for package manager wrappers(eg. yum, dnf) there. @@ -330,6 +333,120 @@ RUN go build -o hello hello.go && \ xx-verify hello ``` +## Rust + +Building Rust can be achieved with the `xx-cargo` wrapper that automatically +sets up the target triple and also `pkg-config` and C compiler. + +The wrapper supports rust installed via [`rustup`](https://rustup.rs/) +(alpine/debian), distribution packages (alpine/debian) and the [official `rust` image](https://hub.docker.com/_/rust). + +### Building on Alpine + +```dockerfile +# syntax=docker/dockerfile:1 +# official rust image +FROM --platform=$BUILDPLATFORM rust:alpine +RUN apk add clang lld +# ... +RUN --mount=type=cache,target=/usr/local/cargo/git/db \ + --mount=type=cache,target=/usr/local/cargo/registry/cache \ + --mount=type=cache,target=/usr/local/cargo/registry/index \ + cargo fetch +ARG TARGETPLATFORM +RUN xx-cargo build --release --target-dir ./build && \ + xx-verify ./build/$(xx-cargo --print-target)/release/hello_cargo +``` + +```dockerfile +# syntax=docker/dockerfile:1 +# rustup +FROM --platform=$BUILDPLATFORM alpine AS rustup +RUN apk add curl +RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable --no-modify-path --profile minimal +ENV PATH="/root/.cargo/bin:$PATH" + +FROM rustup +RUN apk add clang lld +# ... +RUN --mount=type=cache,target=/root/.cargo/git/db \ + --mount=type=cache,target=/root/.cargo/registry/cache \ + --mount=type=cache,target=/root/.cargo/registry/index \ + cargo fetch +ARG TARGETPLATFORM +RUN xx-cargo build --release --target-dir ./build && \ + xx-verify ./build/$(xx-cargo --print-target)/release/hello_cargo +``` + +```dockerfile +# syntax=docker/dockerfile:1 +# packages +FROM --platform=$BUILDPLATFORM alpine +RUN apk add clang lld rust cargo +# ... +RUN --mount=type=cache,target=/root/.cargo/git/db \ + --mount=type=cache,target=/root/.cargo/registry/cache \ + --mount=type=cache,target=/root/.cargo/registry/index \ + cargo fetch +ARG TARGETPLATFORM +RUN xx-apk add xx-c-essentials +RUN xx-cargo build --release --target-dir ./build && \ + xx-verify ./build/$(xx-cargo --print-target)/release/hello_cargo +``` + +### Building on Debian + +```dockerfile +# syntax=docker/dockerfile:1 +# official rust image +FROM --platform=$BUILDPLATFORM rust:bullseye +RUN apt-get update && apt-get install -y clang lld +# ... +RUN --mount=type=cache,target=/usr/local/cargo/git/db \ + --mount=type=cache,target=/usr/local/cargo/registry/cache \ + --mount=type=cache,target=/usr/local/cargo/registry/index \ + cargo fetch +ARG TARGETPLATFORM +RUN xx-cargo build --release --target-dir ./build && \ + xx-verify ./build/$(xx-cargo --print-target)/release/hello_cargo +``` + +```dockerfile +# syntax=docker/dockerfile:1 +# rustup +FROM --platform=$BUILDPLATFORM debian:bullseye AS rustup +RUN apt-get update && apt-get install -y curl ca-certificates +RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable --no-modify-path --profile minimal +ENV PATH="/root/.cargo/bin:$PATH" + +FROM rustup +RUN apt-get update && apt-get install -y clang lld +# ... +RUN --mount=type=cache,target=/root/.cargo/git/db \ + --mount=type=cache,target=/root/.cargo/registry/cache \ + --mount=type=cache,target=/root/.cargo/registry/index \ + cargo fetch +ARG TARGETPLATFORM +RUN xx-cargo build --release --target-dir ./build && \ + xx-verify ./build/$(xx-cargo --print-target)/release/hello_cargo +``` + +```dockerfile +# syntax=docker/dockerfile:1 +# packages +FROM --platform=$BUILDPLATFORM debian:bullseye +RUN apt-get update && apt-get install -y clang lld cargo +# ... +RUN --mount=type=cache,target=/root/.cargo/git/db \ + --mount=type=cache,target=/root/.cargo/registry/cache \ + --mount=type=cache,target=/root/.cargo/registry/index \ + cargo fetch +ARG TARGETPLATFORM +RUN xx-apt-get install xx-c-essentials +RUN xx-cargo build --release --target-dir ./build && \ + xx-verify ./build/$(xx-cargo --print-target)/release/hello_cargo +``` + ## External SDK support In addition to Linux targets, `xx` can also build binaries for MacOS and Windows. When building MacOS binaries from C, external MacOS SDK is needed in `/xx-sdk` directory. Such SDK can be built, for example, with [gen_sdk_package script in osxcross project](https://github.com/tpoechtrager/osxcross/blob/master/tools/gen_sdk_package.sh). Please consult XCode license terms when making such an image. `RUN --mount` syntax can be used in Dockerfile in order to avoid copying SDK files. No special tooling such as `ld64` linker is required in the image itself. From 0c10a44f30f84dbe572f8d1caeffcdcdf0d3a6a1 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sun, 30 Oct 2022 08:15:41 +0100 Subject: [PATCH 21/31] xx-info: fix os-version Signed-off-by: CrazyMax --- base/xx-info | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/base/xx-info b/base/xx-info index b45cc4e7..dcb4667a 100755 --- a/base/xx-info +++ b/base/xx-info @@ -13,7 +13,7 @@ : "${XX_DEBIAN_ARCH=unknown}" # https://docs.fedoraproject.org/ro/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch01s03.html : "${XX_RHEL_ARCH=unknown}" -: "${XX_OS_VERSION=unknown}" +: "${XX_OS_VERSION=}" : "${XX_TRIPLE=unknown-unknown-none}" : "${XX_VENDOR=}" : "${XX_LIBC=}" @@ -110,6 +110,7 @@ distro="" # shellcheck disable=SC1091 if . /etc/os-release 2>/dev/null; then distro=$ID + XX_OS_VERSION=$VERSION_ID fi vendor="" From be3bd3e995505a7c9bfafd0f3d655e720d4686eb Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Thu, 3 Nov 2022 10:49:28 -0700 Subject: [PATCH 22/31] add maintainers file Signed-off-by: Tonis Tiigi --- MAINTAINERS | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 MAINTAINERS diff --git a/MAINTAINERS b/MAINTAINERS new file mode 100644 index 00000000..b392629c --- /dev/null +++ b/MAINTAINERS @@ -0,0 +1,20 @@ +# The Twenty Committee +# +# This file describes the maintainer groups within the xx project. +# The rules for governance are borrowed from and can be seen in +# https://github.com/moby/moby/blob/master/project/GOVERNANCE.md file. +# +# It is structured to be consumable by both humans and programs. +# To extract its contents programmatically, use any TOML-compliant +# parser. +# + +[Org] + + [Org.Maintainers] + + people = [ + "crazy-max", + "tiborvass", + "tonistiigi", + ] From 3b367c3e49c6becae3136750a8c84a8ab67f225b Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Mon, 7 Nov 2022 09:09:41 +0100 Subject: [PATCH 23/31] ci: bump actions Signed-off-by: CrazyMax --- .github/workflows/build.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f198a2f3..e33b38f6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,10 +21,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Validate - uses: docker/bake-action@v1 + uses: docker/bake-action@v2 with: targets: validate @@ -106,16 +106,16 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up QEMU - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Test - uses: docker/bake-action@v1 + uses: docker/bake-action@v2 with: targets: test-${{ matrix.typ }} set: | @@ -129,17 +129,17 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up QEMU - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Docker meta id: meta - uses: docker/metadata-action@v3 + uses: docker/metadata-action@v4 with: images: | tonistiigi/xx @@ -151,13 +151,13 @@ jobs: - name: Login to DockerHub if: github.event_name != 'pull_request' - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build - uses: docker/bake-action@v1 + uses: docker/bake-action@v2 with: files: | ./docker-bake.hcl From 800828fbfe4c428b07024ac348527d7b738ca453 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Tue, 8 Nov 2022 09:12:59 +0100 Subject: [PATCH 24/31] xx-apt: fix xx essentials Signed-off-by: CrazyMax --- base/test-apk.bats | 8 ++++++++ base/test-apt.bats | 8 ++++++++ base/xx-apt | 4 ++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/base/test-apk.bats b/base/test-apk.bats index a1d3f421..4ae9b65c 100755 --- a/base/test-apk.bats +++ b/base/test-apk.bats @@ -15,6 +15,14 @@ load 'assert' assert_output --partial "alpine-baselayout" } +@test "essentials" { + run xx-apk list xx-c-essentials + assert_success + + run xx-apk list xx-cxx-essentials + assert_success +} + @test "cross" { target="arm64" if [ "$(xx-info arch)" = "arm64" ]; then target="amd64"; fi diff --git a/base/test-apt.bats b/base/test-apt.bats index 997a9b3e..4cde980a 100755 --- a/base/test-apt.bats +++ b/base/test-apt.bats @@ -22,6 +22,14 @@ load 'assert' assert_line "Package: gcc" } +@test "essentials" { + run xx-apt show xx-c-essentials + assert_success + + run xx-apt show xx-cxx-essentials + assert_success +} + @test "amd64" { export TARGETARCH=amd64 if ! xx-info is-cross; then skip; fi diff --git a/base/xx-apt b/base/xx-apt index ad5e313c..738f3275 100755 --- a/base/xx-apt +++ b/base/xx-apt @@ -170,13 +170,13 @@ packages2= for p in ${packages}; do if [ "${p}" = "xx-c-essentials" ]; then p="libc6-dev" - if "$arg0" info "libgcc-10-dev:${XX_PKG_ARCH}" >/dev/null 2>/dev/null; then + if checkpkg "libgcc-10-dev:${XX_PKG_ARCH}" >/dev/null 2>/dev/null; then p="$p libgcc-10-dev" else p="$p libgcc-8-dev" fi elif [ "${p}" = "xx-cxx-essentials" ]; then - if "$arg0" info "libstdc++-10-dev:${XX_PKG_ARCH}" >/dev/null 2>/dev/null; then + if checkpkg "libstdc++-10-dev:${XX_PKG_ARCH}" >/dev/null 2>/dev/null; then p="libstdc++-10-dev" else p="libstdc++-8-dev" From 5b2e08ba86381b2cb1767f9bebf3ae1718ad5159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Tiigi?= Date: Fri, 18 Nov 2022 11:18:12 -0800 Subject: [PATCH 25/31] ci: os update Signed-off-by: CrazyMax --- .github/workflows/build.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e33b38f6..99055ab2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -51,6 +51,10 @@ jobs: image: alpine:3.16 typ: alpine allow-failure: false + - + image: alpine:3.17 + typ: alpine + allow-failure: false - image: alpine:edge typ: alpine @@ -91,6 +95,10 @@ jobs: image: fedora:36 typ: rhel allow-failure: false + - + image: fedora:37 + typ: rhel + allow-failure: false - image: centos:7 typ: rhel From c819078ec1f47a3c93f9ee9abbcc3bcaa823ca98 Mon Sep 17 00:00:00 2001 From: Victor Lin <13424970+victorlin@users.noreply.github.com> Date: Tue, 11 Oct 2022 16:30:52 -0700 Subject: [PATCH 26/31] Fix typos in README Signed-off-by: Victor Lin <13424970+victorlin@users.noreply.github.com> --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0021e45f..8c6f6206 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ RUN xx-clang --static -o /out/myapp app.c && \ The recommended method for C-based build is to use `clang` via `xx-clang` wrapper. Clang is natively a cross-compiler, but in order to use it, you also need a linker, compiler-rt or libgcc, and a C library(musl or glibc). All these are available as packages in Alpine and Debian based distros. Clang and linker are binaries and should be installed for your build architecture, while libgcc and C library should be installed for your target architecture. -The recommended linker is `lld,` but there are some caveats. `lld` is not supported on S390x, and based on our experience, sometimes has issues with preparing static binaries for Ppc64le. In these cases, `ld` from `binutils` is required. As separate `ld` binary needs to be built for each architecture, distros often do not provide it as a package. Therefore `xx` loads [prebuilt](https://github.com/tonistiigi/xx/releases/tag/prebuilt%2Fld-1) `ld` binaries when needed. `XX_CC_PREFER_LINKER=ld` can be defined if you want to always use `ld`, even when `lld` is available on the system. Building MacOS binaries happens through a prebuilt `ld64` linker that also adds ad-hoc code-signature to the resulting binary. +The recommended linker is `lld`, but there are some caveats. `lld` is not supported on S390x, and based on our experience, sometimes has issues with preparing static binaries for Ppc64le. In these cases, `ld` from `binutils` is required. As separate `ld` binary needs to be built for each architecture, distros often do not provide it as a package. Therefore `xx` loads [prebuilt](https://github.com/tonistiigi/xx/releases/tag/prebuilt%2Fld-1) `ld` binaries when needed. `XX_CC_PREFER_LINKER=ld` can be defined if you want to always use `ld`, even when `lld` is available on the system. Building MacOS binaries happens through a prebuilt `ld64` linker that also adds ad-hoc code-signature to the resulting binary. `xx-clang` can be called with any arguments `clang` binary accepts and will internally call the native `clang` binary with additional configuration for correct cross-compilation. On first invocation, `xx-clang` will also set up alias commands for the current target triple that can be later called directly. This helps with tooling that looks for programs with a target triple prefix from your `PATH`. This setup phase can be manually invoked by calling `xx-clang --setup-target-triple` that is a special flag that `clang` itself does not implement. @@ -207,7 +207,7 @@ Building on Debian/Ubuntu is very similar. The only required dependency that nee ```dockerfile # ... -RUN apt-get update && apt-get instal -y clang lld +RUN apt-get update && apt-get install -y clang lld # copy source ARG TARGETPLATFORM RUN xx-apt install -y libc6-dev @@ -228,7 +228,7 @@ RUN $(xx-info)-gcc -o hello hello.c ### Wrapping as default -Special flags `xx-clang --wrap` and `xx-clang --unwarp` can be used to override the default behavior of `clang` with `xx-clang` in the extreme cases where your build scripts have no way to point to alternative compiler names. +Special flags `xx-clang --wrap` and `xx-clang --unwrap` can be used to override the default behavior of `clang` with `xx-clang` in the extreme cases where your build scripts have no way to point to alternative compiler names. ``` # export TARGETPLATFORM=linux/amd64 From 75cb3da16afdc8d6c8a235c33ba096ff4c0551e2 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Mon, 7 Nov 2022 08:03:09 +0100 Subject: [PATCH 27/31] xx-cargo: rename to --print-target-triple Signed-off-by: CrazyMax --- base/test-cargo.bats | 4 ++-- base/xx-cargo | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/base/test-cargo.bats b/base/test-cargo.bats index 73de90ef..ec0e9050 100755 --- a/base/test-cargo.bats +++ b/base/test-cargo.bats @@ -30,9 +30,9 @@ testHelloCargo() { assert_success run xx-cargo build --verbose --color=never --manifest-path=./fixtures/hello_cargo/Cargo.toml --release --target-dir /tmp/cargobuild assert_success - xx-verify /tmp/cargobuild/$(xx-cargo --print-target)/release/hello_cargo + xx-verify /tmp/cargobuild/$(xx-cargo --print-target-triple)/release/hello_cargo if ! xx-info is-cross; then - run /tmp/cargobuild/$(xx-cargo --print-target)/release/hello_cargo + run /tmp/cargobuild/$(xx-cargo --print-target-triple)/release/hello_cargo assert_success assert_output "hello cargo" fi diff --git a/base/xx-cargo b/base/xx-cargo index e08e4d11..38ff2148 100755 --- a/base/xx-cargo +++ b/base/xx-cargo @@ -29,7 +29,7 @@ for a in "$@"; do "--setup-target-triple") setuponly=1 ;; - "--print-target") + "--print-target-triple") printtarget=1 ;; *) From d0e5d9e41fd4f10434286fc4a619fe74f47597db Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Mon, 7 Nov 2022 08:41:30 +0100 Subject: [PATCH 28/31] update rust docs Signed-off-by: CrazyMax --- README.md | 106 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 8c6f6206..ad904b2b 100644 --- a/README.md +++ b/README.md @@ -345,22 +345,70 @@ The wrapper supports rust installed via [`rustup`](https://rustup.rs/) ```dockerfile # syntax=docker/dockerfile:1 -# official rust image FROM --platform=$BUILDPLATFORM rust:alpine RUN apk add clang lld # ... -RUN --mount=type=cache,target=/usr/local/cargo/git/db \ - --mount=type=cache,target=/usr/local/cargo/registry/cache \ - --mount=type=cache,target=/usr/local/cargo/registry/index \ - cargo fetch ARG TARGETPLATFORM RUN xx-cargo build --release --target-dir ./build && \ - xx-verify ./build/$(xx-cargo --print-target)/release/hello_cargo + xx-verify ./build/$(xx-cargo --print-target-triple)/release/hello_cargo +``` + +Cargo binary can also be called directly with `--target` flag if you don't want +to use the wrapper. `--print-target-triple` is a built-in flag that can be used +to set the correct target: + +```dockerfile +# syntax=docker/dockerfile:1 +FROM --platform=$BUILDPLATFORM rust:alpine +RUN apk add clang lld +# ... +ARG TARGETPLATFORM +RUN cargo build --target=$(xx-cargo --print-target-triple) --release --target-dir ./build && \ + xx-verify ./build/$(xx-cargo --print-target-triple)/release/hello_cargo +``` + +> **Note** +> +> `xx-cargo --print-target-triple` does not always have the same value as +> `xx-clang --print-target-triple`. This is because prebuilt Rust and C +> libraries sometimes use a different value. + +The first invocation of `xx-cargo` will install the standard library for Rust +matching the target if not already installed. + +To fetch dependencies from crates.io you can use `cargo fetch` before building: + +```dockerfile +# syntax=docker/dockerfile:1 +FROM --platform=$BUILDPLATFORM rust:alpine +RUN apk add clang lld +# ... +RUN --mount=type=cache,target=/root/.cargo/git/db \ + --mount=type=cache,target=/root/.cargo/registry/cache \ + --mount=type=cache,target=/root/.cargo/registry/index \ + cargo fetch +ARG TARGETPLATFORM +RUN --mount=type=cache,target=/root/.cargo/git/db \ + --mount=type=cache,target=/root/.cargo/registry/cache \ + --mount=type=cache,target=/root/.cargo/registry/index \ + xx-cargo build --release --target-dir ./build && \ + xx-verify ./build/$(xx-cargo --print-target-triple)/release/hello_cargo ``` +> **Note** +> +> By calling `cargo fetch` before `ARG TARGETPLATFORM` your packages are +> fetched only once for the whole build while the building happens separately +> for each target architecture. + +To avoid redownloading dependencies on every build, you can use cache mounts +to store [Git sources with packages and metadata of crate registries](https://doc.rust-lang.org/cargo/guide/cargo-home.html#directories). + +If you don't want to use the official Rust image, you can install `rustup` +manually: + ```dockerfile # syntax=docker/dockerfile:1 -# rustup FROM --platform=$BUILDPLATFORM alpine AS rustup RUN apk add curl RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable --no-modify-path --profile minimal @@ -369,51 +417,41 @@ ENV PATH="/root/.cargo/bin:$PATH" FROM rustup RUN apk add clang lld # ... -RUN --mount=type=cache,target=/root/.cargo/git/db \ - --mount=type=cache,target=/root/.cargo/registry/cache \ - --mount=type=cache,target=/root/.cargo/registry/index \ - cargo fetch ARG TARGETPLATFORM RUN xx-cargo build --release --target-dir ./build && \ - xx-verify ./build/$(xx-cargo --print-target)/release/hello_cargo + xx-verify ./build/$(xx-cargo --print-target-triple)/release/hello_cargo ``` +If you install rust using distribution packages, `rustup` will not be available: + ```dockerfile # syntax=docker/dockerfile:1 -# packages FROM --platform=$BUILDPLATFORM alpine RUN apk add clang lld rust cargo # ... -RUN --mount=type=cache,target=/root/.cargo/git/db \ - --mount=type=cache,target=/root/.cargo/registry/cache \ - --mount=type=cache,target=/root/.cargo/registry/index \ - cargo fetch ARG TARGETPLATFORM RUN xx-apk add xx-c-essentials RUN xx-cargo build --release --target-dir ./build && \ - xx-verify ./build/$(xx-cargo --print-target)/release/hello_cargo + xx-verify ./build/$(xx-cargo --print-target-triple)/release/hello_cargo ``` +In this case, you need to also install minimum necessary packages using `xx-apk`. + ### Building on Debian +Building on Debian/Ubuntu is very similar. If you are using `rustup`: + ```dockerfile # syntax=docker/dockerfile:1 -# official rust image FROM --platform=$BUILDPLATFORM rust:bullseye RUN apt-get update && apt-get install -y clang lld -# ... -RUN --mount=type=cache,target=/usr/local/cargo/git/db \ - --mount=type=cache,target=/usr/local/cargo/registry/cache \ - --mount=type=cache,target=/usr/local/cargo/registry/index \ - cargo fetch ARG TARGETPLATFORM RUN xx-cargo build --release --target-dir ./build && \ - xx-verify ./build/$(xx-cargo --print-target)/release/hello_cargo + xx-verify ./build/$(xx-cargo --print-target-triple)/release/hello_cargo ``` ```dockerfile # syntax=docker/dockerfile:1 -# rustup FROM --platform=$BUILDPLATFORM debian:bullseye AS rustup RUN apt-get update && apt-get install -y curl ca-certificates RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable --no-modify-path --profile minimal @@ -422,29 +460,21 @@ ENV PATH="/root/.cargo/bin:$PATH" FROM rustup RUN apt-get update && apt-get install -y clang lld # ... -RUN --mount=type=cache,target=/root/.cargo/git/db \ - --mount=type=cache,target=/root/.cargo/registry/cache \ - --mount=type=cache,target=/root/.cargo/registry/index \ - cargo fetch ARG TARGETPLATFORM RUN xx-cargo build --release --target-dir ./build && \ - xx-verify ./build/$(xx-cargo --print-target)/release/hello_cargo + xx-verify ./build/$(xx-cargo --print-target-triple)/release/hello_cargo ``` +Or distribution packages: + ```dockerfile # syntax=docker/dockerfile:1 -# packages FROM --platform=$BUILDPLATFORM debian:bullseye RUN apt-get update && apt-get install -y clang lld cargo -# ... -RUN --mount=type=cache,target=/root/.cargo/git/db \ - --mount=type=cache,target=/root/.cargo/registry/cache \ - --mount=type=cache,target=/root/.cargo/registry/index \ - cargo fetch ARG TARGETPLATFORM RUN xx-apt-get install xx-c-essentials RUN xx-cargo build --release --target-dir ./build && \ - xx-verify ./build/$(xx-cargo --print-target)/release/hello_cargo + xx-verify ./build/$(xx-cargo --print-target-triple)/release/hello_cargo ``` ## External SDK support From 99638a7d40ead835d18737ffb8ae6320f48567f2 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sat, 26 Nov 2022 17:25:56 +0100 Subject: [PATCH 29/31] xx-cargo: set PKG_CONFIG Signed-off-by: CrazyMax --- base/xx-cargo | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/base/xx-cargo b/base/xx-cargo index 38ff2148..1af1b1bb 100755 --- a/base/xx-cargo +++ b/base/xx-cargo @@ -88,6 +88,10 @@ if which "qemu-$(RISCV64_TARGET_ARCH='' ARM_TARGET_ARCH='' xx-info march)" >/dev fi fi +if command -v "$(xx-info)-pkg-config" >/dev/null 2>/dev/null; then + export "PKG_CONFIG=$(xx-info)-pkg-config" +fi + if [ -n "$printtarget" ]; then xx-info exit 0 From 373a1a7092bdc4be1c441c892db6f0b5aebdc2e6 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Thu, 26 Jan 2023 19:40:06 +0100 Subject: [PATCH 30/31] ci: allow failure for bookworm Signed-off-by: CrazyMax --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 99055ab2..0166d8f2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -70,7 +70,8 @@ jobs: - image: debian:bookworm typ: debian - allow-failure: false + # FIXME: Set to false when https://github.com/tonistiigi/xx/issues/95 fixed + allow-failure: true - image: debian:sid typ: debian From 77cb53cb29903001e03cdbd40615bf83a4e15a4a Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sun, 12 Feb 2023 20:39:39 +0100 Subject: [PATCH 31/31] xx-cc: update prebuilt ld to binutils 2.38 Signed-off-by: CrazyMax --- base/xx-cc | 152 ++++++++++++++++++++++++++--------------------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/base/xx-cc b/base/xx-cc index de93f523..cef131a2 100755 --- a/base/xx-cc +++ b/base/xx-cc @@ -2,7 +2,7 @@ set -e -mirrors="https://github.com/tonistiigi/xx/releases/download/prebuilt%2Fld-1" +mirrors="https://github.com/tonistiigi/xx/releases/download/prebuilt%2Fld-2.38-0" if [ -n "$XX_MIRROR" ]; then mirrors="$XX_MIRROR" @@ -194,11 +194,11 @@ download_ld64() { ensurewget shas=$( cat <<'EOT' -ld64-signed-linux-386 7b664761928f6d5dd8d505e533b45e67a86ff1d4 -ld64-signed-linux-amd64 a218662887a1c9daf94a57fb4569455315f8ef7f -ld64-signed-linux-arm64 3257520368b3e32fa1b413151c79f75bd0c77bed -ld64-signed-linux-armv6 df770289f82a1ce50fd069cef48a3e79185bd508 -ld64-signed-linux-armv7 1dbf5be507a73768bb1ee72d3325020640cca614 +ld64-signed-linux-386 b60f72fb81845f707786cee499f49541a1c46686 +ld64-signed-linux-amd64 2dd147c0b50f83e7939c7fa151fe81febae84caf +ld64-signed-linux-arm64 89125aa156c77a772d05b3d02a183b446b20c5b8 +ld64-signed-linux-armv6 ce1744dfaff44ffacf57e77994e3a8b2eedffe8a +ld64-signed-linux-armv7 93314800a42f36e2d2a90c99e7c1f7ac7e6f43fb EOT ) @@ -245,76 +245,76 @@ download_ld() { # for f in *; do echo -n "${f%.tar.gz} " ; shasum -a 1 -b $f | cut -d' ' -f1 ; done | pbcopy shas=$( cat <<'EOT' -linux-386-ld-linux-386 f26c1d9bdefe3c139db91f1f02369a897db1a682 -linux-386-ld-linux-amd64 1bbb8c30de5855ed183ba5e1799d46da66f18525 -linux-386-ld-linux-arm64 8fe1e78d15e0835272025de3cd14b1d863038e0b -linux-386-ld-linux-armv6 0b6fdc84037e2d20057ef4c3d567989b4ce588b1 -linux-386-ld-linux-armv7 a860b73e473f3596a9166462a8e279d871e1596b -linux-386-ld-linux-ppc64le 359cbcf078111430e42654e06a06817384d08f1c -linux-386-ld-linux-s390x fc63fe0ad012ac5ed8d5423b8d40e709ed690da7 -linux-amd64-ld-linux-386 7211f566acb3bf43e3cf5b0e89583203d14e00b5 -linux-amd64-ld-linux-amd64 00b702ae772948804f222996f15ba9dc3def8d9f -linux-amd64-ld-linux-arm64 67f3be9f050435699bfe1edfdf9e6fed569afd56 -linux-amd64-ld-linux-armv6 97e9ed3e0f20a69e913fca5495a00429abf53204 -linux-amd64-ld-linux-armv7 0218d6fed88fc5e0b7ec3241b8ba22bf694dc861 -linux-amd64-ld-linux-ppc64le 851638910f930390a6e28ff32f05f8a7a1424a33 -linux-amd64-ld-linux-s390x 9fd10cc922d78e781fb57969b642f82262f5b9b6 -linux-arm64-ld-linux-386 67ed0a1c166895b5bc69746a4d46462c66433f1f -linux-arm64-ld-linux-amd64 63d9ea9166dd42015ed0b88258dded7800ba0991 -linux-arm64-ld-linux-arm64 f87a87bd6cd2fdba224656fecea8b87ebe4e06df -linux-arm64-ld-linux-armv6 d5afd182c57bfd49e7543c4690dd4562487c1bb2 -linux-arm64-ld-linux-armv7 146c11f8f51034fed91c4462cb56f042dfd8f6ee -linux-arm64-ld-linux-ppc64le 32440a9eb9fee7ae7979e91f029456af14fe77bc -linux-arm64-ld-linux-s390x 2d8b144a7c662d32517130bbd479a1ba950d4021 -linux-armv6-ld-linux-386 8f1412fa81afd382c5bf37ccbeee9933120e4e24 -linux-armv6-ld-linux-amd64 bc9191dd462119e7561366be0903d5aa80182745 -linux-armv6-ld-linux-arm64 9b8cc4996ab5f7ad7981632c3b80e56a81841632 -linux-armv6-ld-linux-armv6 4aa7d4981c1ca62ffe95c3b822508ffbc915bfd4 -linux-armv6-ld-linux-armv7 c60bd68a5229fb9c6edabc74f75e569d67a8c191 -linux-armv6-ld-linux-ppc64le 05f7220c713c57ebda9cfae674685cce1efd15eb -linux-armv6-ld-linux-s390x 6f16aa712e04200635bee2a18221bc2b53b5367f -linux-armv7-ld-linux-386 dc7b03f32f7b62117af7b158f8918194821ed70c -linux-armv7-ld-linux-amd64 20b59e08b60214d4ac7f9c552802412347e4cb0b -linux-armv7-ld-linux-arm64 fbdff9ab4676e6a4abd4462f93031a8f2043bf0e -linux-armv7-ld-linux-armv6 9e91f0a25b816342a4241d722ca36bfec9c9cf97 -linux-armv7-ld-linux-armv7 c2f0dcbdd2afe320f2c93b8aa5f9214f692b439e -linux-armv7-ld-linux-ppc64le 52b0c279025b147ca5f8c9a9795e636bdf02632b -linux-armv7-ld-linux-s390x a9544446c0890c961f53c0dadc43784eca406f0a -linux-ppc64le-ld-linux-386 93c90d7a14407e9e17cadcdcb695b833187fcdb4 -linux-ppc64le-ld-linux-amd64 c90cdfb51bf6e439c273b5867518ad5e9c6dd371 -linux-ppc64le-ld-linux-arm64 b58ed9a8bb7287a558d0027d1c5901a14f9214fb -linux-ppc64le-ld-linux-armv6 0c4635be4d2df4010213babc4b194b5b4148716b -linux-ppc64le-ld-linux-armv7 15c7b36d0df188081e00ecdc3297eb14093b255f -linux-ppc64le-ld-linux-ppc64le f48781830bce5e87f814fe3bf480ea349d019d89 -linux-ppc64le-ld-linux-s390x 72ec84b9a73904555aa56490fc8acf37813b397e -linux-riscv64-ld-linux-386 0028e50478b516f8e97640d48329cc3dca4d1aef -linux-riscv64-ld-linux-amd64 3f1a6c377fd37b0bd20cee2d5de0dd2594652b91 -linux-riscv64-ld-linux-arm64 2be29a72197846ccaba24832ecf99cf9df1db2b2 -linux-riscv64-ld-linux-armv6 f88badee63c0ecaecb7d807cc65586bf5711bb13 -linux-riscv64-ld-linux-armv7 6d8cbb17d3fc71e48001566f3ef4895f2f680b81 -linux-riscv64-ld-linux-ppc64le 9fa253d83d4f46c39fd141d551c0d2b211c8826c -linux-riscv64-ld-linux-s390x c17ebba5f0742fb78d39fb65288f851a3652dd90 -linux-s390x-ld-linux-386 e6d6b1ac10b726cc6d57efe7900e40131295d446 -linux-s390x-ld-linux-amd64 f7d1e1a0a0dbf6bdb64e3da253e6ca843d42a683 -linux-s390x-ld-linux-arm64 490d359bf81c8d338e8fced61f9185e516e3bf7a -linux-s390x-ld-linux-armv6 dc2c3c584fbf0e31b227c26436b6a3bb2fa6f58d -linux-s390x-ld-linux-armv7 de9a38da06d6c08f411b85fd7e81ce20c3b6c956 -linux-s390x-ld-linux-ppc64le 09f74ed0bfbc97f38e5ef9c8885f19cceedfeb11 -linux-s390x-ld-linux-s390x 3e882ae2edaf06f5ae0900d16cd456516f710482 -windows-386-ld-linux-386 6519bb906421c76df6432c0f9a324759f7a89799 -windows-386-ld-linux-amd64 b7c26a07cb1811808c9b51bcab11718aa73fc3d0 -windows-386-ld-linux-arm64 7d218748f9608e580cf0718a0286de5803cc7148 -windows-386-ld-linux-armv6 656ecf7ccfcf8815f541abb1c812659c93828d79 -windows-386-ld-linux-armv7 73b2e3414932b3d6e18db6eb717078f08b705543 -windows-386-ld-linux-ppc64le e259fd1b96e1403b669538bc5769a15c9dc4e5a0 -windows-386-ld-linux-s390x 035ccf00fbc7d283c25f34c189cdac85f819ed5e -windows-amd64-ld-linux-386 2a82e2de449522a5643ec009b4fedd22751e7af6 -windows-amd64-ld-linux-amd64 800175f19d6c2bfe27cf92e7b7c286fb1a459968 -windows-amd64-ld-linux-arm64 af4a20ea92033de3331d6a1add46e8273ecc420d -windows-amd64-ld-linux-armv6 ae97f91058d79281256e19815a84c792dc15709e -windows-amd64-ld-linux-armv7 d57ab7ba5e84953069d10ad75ed6d8977df90de1 -windows-amd64-ld-linux-ppc64le e667b511c61b84d83e2956a5aad3d580b66e3c80 -windows-amd64-ld-linux-s390x 92777b3e15b6bdde0c106a86466abc9d0d9cdb94 +linux-386-ld-linux-386 1c6e95b6fa2cd67d5b139d8f59ef42736bca1b29 +linux-386-ld-linux-amd64 3a6a2aeaa926c910348d1272c9100f5a2fc880cc +linux-386-ld-linux-arm64 54d1a061f1e0ce5b7f0150e0d86d140dbc74e810 +linux-386-ld-linux-armv6 a5ec847effb4dae7ba7ebdba8efac96851f55c52 +linux-386-ld-linux-armv7 4fd68022c815529d31a4104a2eaa4964614fa9b7 +linux-386-ld-linux-ppc64le f3d59fcf8ccd052abee648e89df0035a923b251b +linux-386-ld-linux-s390x 6347f3b773972302071d56a1cedfcda3616270da +linux-amd64-ld-linux-386 3e8f208da293ca1726716b9f9176e9eec7bb70d7 +linux-amd64-ld-linux-amd64 080368ec185f7cd46a4d416ec9d9b07a87a0e38e +linux-amd64-ld-linux-arm64 aa3f0aaa30bde9e3e43ad22abf9cd741571414d8 +linux-amd64-ld-linux-armv6 be9ded3bbb3656351c601d09ed8efb78c345e511 +linux-amd64-ld-linux-armv7 990a6abd228c910f803a68c2d1be140029d955a8 +linux-amd64-ld-linux-ppc64le 0c00ea4fec4284a43499a0823ae2f0d27cc0df7f +linux-amd64-ld-linux-s390x c69551214da34452bedcdd082e0e5100d30f0123 +linux-arm64-ld-linux-386 4bb1f097624679f77b47755b46bb2420dad53056 +linux-arm64-ld-linux-amd64 c925dee584f3d4fef2c19469c54b4b32b2d6e29c +linux-arm64-ld-linux-arm64 67e4fe36075015a9f06053db9bda041f628f100c +linux-arm64-ld-linux-armv6 36f7cc07023b50c368405fcfe5475a7d143f8cbc +linux-arm64-ld-linux-armv7 8a0eef9ce950480883910914084859f1dfdc2763 +linux-arm64-ld-linux-ppc64le 582cc738880295275c833ce67629d44a6c4735dc +linux-arm64-ld-linux-s390x 81d000a3111f06a0a3536886dbe1f4b5a65fabf9 +linux-armv6-ld-linux-386 8499efdc3d266e3bc7e97e47fb63372bb9283596 +linux-armv6-ld-linux-amd64 e48a60bdfd05b2fd15313a026d008f572a31f3fa +linux-armv6-ld-linux-arm64 8aba449dd98656122d20442b6db2119b574af7d8 +linux-armv6-ld-linux-armv6 c9b31c63a5d7af690562d48237020f098fb0d362 +linux-armv6-ld-linux-armv7 618cf8d0b425ca2a73d540ec832b65822211e9da +linux-armv6-ld-linux-ppc64le 1ded4435d9d2af95fe2600307a7c21463d84d1ab +linux-armv6-ld-linux-s390x 295a424043251b2ce4c1419e4f50824a17e06f8d +linux-armv7-ld-linux-386 a545fafc90240152388b9bcfd264db303d2524fb +linux-armv7-ld-linux-amd64 e03db86d6ddf0aabf16fcd49cf5d96794dc5364b +linux-armv7-ld-linux-arm64 8b20b6aa8b08619c19c323cdf59c2312aa93ceaf +linux-armv7-ld-linux-armv6 31e0b269e161245b2811963fa7982d6aac608fbd +linux-armv7-ld-linux-armv7 133cc2777f712d69b16c3a19ed4f3ca33d992f4b +linux-armv7-ld-linux-ppc64le 6bc0428090108a37591bef38dec1b8f5105903fc +linux-armv7-ld-linux-s390x e06e2e4fc0642eb36008b264eaf62f3a1296a9da +linux-ppc64le-ld-linux-386 b4561d4a74f82e628931bad3daf28c97ce9d7347 +linux-ppc64le-ld-linux-amd64 f3f032245399ff46afc9a2aff051fc6c58b1a62d +linux-ppc64le-ld-linux-arm64 c6bc1cee1513e8c8109d57a25de2e78f8d643cfe +linux-ppc64le-ld-linux-armv6 c8bb4beaea974db2b4651cf45853eb72e80e23da +linux-ppc64le-ld-linux-armv7 693b5617b282bcb1e6fcde2b3abd5b720d3d2f46 +linux-ppc64le-ld-linux-ppc64le b49b5a55cf7d3239bb9ae53350b5635d8a848f29 +linux-ppc64le-ld-linux-s390x f2757e8242fc190c4fcf35c7ece88486b949e2c3 +linux-riscv64-ld-linux-386 030f59c1425f42232e0075a7324640dfb6f835be +linux-riscv64-ld-linux-amd64 0b5bd6ea0ec242606c4e63458a134dfc6670770c +linux-riscv64-ld-linux-arm64 03f23014888953b581c3d607bfa35b5c5c66aa88 +linux-riscv64-ld-linux-armv6 2a7491470763390bf89e667869fc16096b9ecc3a +linux-riscv64-ld-linux-armv7 cad4ee8ee1739cbcf91ace751a3e7e5ffed595c1 +linux-riscv64-ld-linux-ppc64le 2901d8ca953e58961013f12f46e5309c54004d1f +linux-riscv64-ld-linux-s390x cd875e21040d79d81c6e812232bb9a53e410941d +linux-s390x-ld-linux-386 e077c4664f58223b5e6f0033aa76f459b7b5b87b +linux-s390x-ld-linux-amd64 acf4e62ff69b1ed2eba67913a2df3a86285dcc93 +linux-s390x-ld-linux-arm64 3dedd7834e52d3713f6136a62960e90500dc8581 +linux-s390x-ld-linux-armv6 72a780e78f27c50a578f874ed0cb1268430831bf +linux-s390x-ld-linux-armv7 95d0c9723e6a6f0c6743a928d666783b37ff2ffa +linux-s390x-ld-linux-ppc64le 2dd0d7d86e1a59f95bc5740d9a9757d1e945c04d +linux-s390x-ld-linux-s390x 82af2cab690c7bf7d0f50cb1a77e4cb24a4b59ca +windows-386-ld-linux-386 33acb48796a4819836efae4501ff03d0f735ccdc +windows-386-ld-linux-amd64 bc69c14e05a95cd36507267169423d19c34be57d +windows-386-ld-linux-arm64 c7d6edf9c6dc99ac77c1a43afa4c47d63dbbe925 +windows-386-ld-linux-armv6 17f4a54c173f33771864071277ef9406d21e4e34 +windows-386-ld-linux-armv7 90193a36ade422db6a83132a3646df14ccb33c24 +windows-386-ld-linux-ppc64le 9333dfb85995486f42a7d84ad6e5554663bdba99 +windows-386-ld-linux-s390x 22b53c83bdfd7c50d664ad451f5215b7297a65fc +windows-amd64-ld-linux-386 c33d238d88be7396b2cfcc3fdcb3eb315caf5026 +windows-amd64-ld-linux-amd64 190e25f106c2c94bd4a9eb43c1a1adfa467ab16c +windows-amd64-ld-linux-arm64 f79e8a5d76f6cb73758ba686032931e0ca79882e +windows-amd64-ld-linux-armv6 a2bf366e475a05fdd5f76dcb89853c0fa9688732 +windows-amd64-ld-linux-armv7 f80649beea9fda70e571b60b5a8c002e68962dd8 +windows-amd64-ld-linux-ppc64le 85e1ca017bf8336f197612440964483cc48a21f5 +windows-amd64-ld-linux-s390x 5de90ec0906a3a28cc62058b90a89d266590b5d6 EOT )