Support building on an arm64 host too

This adds a `.host-arch` symlink to build output; this doesn't get committed (for hopefully obvious reasons), but allows for things like `CMD` and `update.sh` to have a known-effective target for testing the output further in some way.

This was a mapping we already had thanks to `ARCH_TEST`, so I've also reordered our builds such that they're grouped by "host" architecture and sorted by "preference"/compatibility (with the goal that we get a more "correct" `.host-arch` symlink).
This commit is contained in:
Tianon Gravi 2025-02-03 10:47:53 -08:00
parent 6ad8af5782
commit f689a8df49
5 changed files with 36 additions and 27 deletions

View File

@ -4,5 +4,6 @@
*.sh *.sh
.dockerignore .dockerignore
.git* .git*
.host-arch
Dockerfile* Dockerfile*
LICENSE LICENSE

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.host-arch

View File

@ -3,6 +3,7 @@ FROM debian:bookworm-slim
RUN set -eux; \ RUN set -eux; \
apt-get update; \ apt-get update; \
dpkgArch="$(dpkg --print-architecture)"; \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
ca-certificates \ ca-certificates \
gnupg \ gnupg \
@ -12,6 +13,8 @@ RUN set -eux; \
libc6-dev \ libc6-dev \
make \ make \
\ \
# these are all "arch:all" so we can just install all of them
libc6-dev-amd64-cross \
libc6-dev-arm64-cross \ libc6-dev-arm64-cross \
libc6-dev-armel-cross \ libc6-dev-armel-cross \
libc6-dev-armhf-cross \ libc6-dev-armhf-cross \
@ -21,7 +24,9 @@ RUN set -eux; \
libc6-dev-riscv64-cross \ libc6-dev-riscv64-cross \
libc6-dev-s390x-cross \ libc6-dev-s390x-cross \
\ \
gcc-aarch64-linux-gnu \ # the cross-compilers are particular about which architectures they build for, so for now we'll only support a host architecture of amd64 or arm64
$([ "$dpkgArch" = 'amd64' ] || echo 'gcc-x86-64-linux-gnu') \
$([ "$dpkgArch" = 'arm64' ] || echo 'gcc-aarch64-linux-gnu') \
gcc-arm-linux-gnueabi \ gcc-arm-linux-gnueabi \
gcc-arm-linux-gnueabihf \ gcc-arm-linux-gnueabihf \
gcc-i686-linux-gnu \ gcc-i686-linux-gnu \
@ -54,32 +59,18 @@ RUN set -eux; \
WORKDIR /usr/src/hello WORKDIR /usr/src/hello
COPY . . COPY . .
# the following steps are grouped into "architecture families" and roughly ordered in a descending compatibility way such that we end up with the most accurate ".host-arch" symlink we can reasonably get
RUN set -ex; \ RUN set -ex; \
make clean all test \ make clean all test \
TARGET_ARCH='amd64' \ TARGET_ARCH='amd64' \
CROSS_COMPILE='x86_64-linux-gnu-' \ CROSS_COMPILE='x86_64-linux-gnu-' \
ARCH_TEST='amd64' ARCH_TEST='amd64'
RUN set -ex; \ RUN set -ex; \
make clean all test \ make clean all test \
TARGET_ARCH='arm32v5' \ TARGET_ARCH='i386' \
CROSS_COMPILE='arm-linux-gnueabi-' \ CROSS_COMPILE='i686-linux-gnu-' \
# EXTRA_CFLAGS='-march=armv5te' \ ARCH_TEST='i386'
ARCH_TEST='armel'
RUN set -ex; \
make clean all test \
TARGET_ARCH='arm32v6' \
CROSS_COMPILE='arm-linux-gnueabi-' \
EXTRA_CFLAGS='-march=armv6+fp' \
ARCH_TEST='armhf'
RUN set -ex; \
make clean all test \
TARGET_ARCH='arm32v7' \
CROSS_COMPILE='arm-linux-gnueabihf-' \
# EXTRA_CFLAGS='-march=armv7-a+fp' \
ARCH_TEST='armhf'
RUN set -ex; \ RUN set -ex; \
make clean all test \ make clean all test \
@ -89,9 +80,22 @@ RUN set -ex; \
RUN set -ex; \ RUN set -ex; \
make clean all test \ make clean all test \
TARGET_ARCH='i386' \ TARGET_ARCH='arm32v7' \
CROSS_COMPILE='i686-linux-gnu-' \ CROSS_COMPILE='arm-linux-gnueabihf-' \
ARCH_TEST='i386' # EXTRA_CFLAGS='-march=armv7-a+fp' \
ARCH_TEST='armhf'
RUN set -ex; \
make clean all test \
TARGET_ARCH='arm32v6' \
CROSS_COMPILE='arm-linux-gnueabi-' \
EXTRA_CFLAGS='-march=armv6+fp' \
ARCH_TEST='armhf'
RUN set -ex; \
make clean all test \
TARGET_ARCH='arm32v5' \
CROSS_COMPILE='arm-linux-gnueabi-' \
# EXTRA_CFLAGS='-march=armv5te' \
ARCH_TEST='armel'
RUN set -ex; \ RUN set -ex; \
make clean all test \ make clean all test \
@ -118,6 +122,6 @@ RUN set -ex; \
CROSS_COMPILE='s390x-linux-gnu-' \ CROSS_COMPILE='s390x-linux-gnu-' \
ARCH_TEST='s390x' ARCH_TEST='s390x'
RUN find \( -name 'hello' -or -name 'hello.txt' \) -exec file '{}' + -exec ls -lh '{}' + RUN find \( -name 'hello' -or -name 'hello.txt' -or -name '.host-arch' \) -exec file '{}' + -exec ls -lh '{}' +
CMD ["./amd64/hello-world/hello"] CMD [".host-arch/hello-world/hello"]

View File

@ -55,6 +55,9 @@ test: $(C_TARGETS)
if [ -n "$$ARCH_TEST" ] && command -v arch-test > /dev/null && arch-test "$$ARCH_TEST" > /dev/null; then \ if [ -n "$$ARCH_TEST" ] && command -v arch-test > /dev/null && arch-test "$$ARCH_TEST" > /dev/null; then \
( set -x && "./$$b" ); \ ( set -x && "./$$b" ); \
( set -x && "./$$b" | grep -q '"'"$$(basename "$$(dirname "$$b")")"'"' ); \ ( set -x && "./$$b" | grep -q '"'"$$(basename "$$(dirname "$$b")")"'"' ); \
if [ ! -e .host-arch ] && arch-test -n "$$ARCH_TEST" > /dev/null; then \
ln -svfT "$${b%%/*}" .host-arch; \
fi; \
else \ else \
echo >&2 "warning: $$TARGET_ARCH ($$ARCH_TEST) not supported; skipping test"; \ echo >&2 "warning: $$TARGET_ARCH ($$ARCH_TEST) not supported; skipping test"; \
fi; \ fi; \

View File

@ -8,7 +8,7 @@ set -x
docker build -f Dockerfile.build -t hello-world:build . docker build -f Dockerfile.build -t hello-world:build .
find */ \( -name hello -or -name hello.txt \) -delete find */ \( -name hello -or -name hello.txt \) -delete
docker run --rm hello-world:build sh -c 'find \( -name hello -or -name hello.txt \) -print0 | xargs -0 tar --create' | tar --extract --verbose docker run --rm hello-world:build sh -c 'find \( -name hello -or -name hello.txt -or -name .host-arch \) -print0 | xargs -0 tar --create' | tar --extract --verbose
find -name hello -type f -exec dirname '{}' ';' | xargs -n1 -i'{}' cp Dockerfile-linux.template '{}/Dockerfile' find -name hello -type f -exec dirname '{}' ';' | xargs -n1 -i'{}' cp Dockerfile-linux.template '{}/Dockerfile'
find -name hello.txt -type f -exec dirname '{}' ';' | xargs -n1 -i'{}' cp Dockerfile-windows.template '{}/Dockerfile' find -name hello.txt -type f -exec dirname '{}' ';' | xargs -n1 -i'{}' cp Dockerfile-windows.template '{}/Dockerfile'
@ -20,7 +20,7 @@ for h in */*/nanoserver-*/Dockerfile; do
sed -i 's!FROM .*!FROM mcr.microsoft.com/windows/nanoserver:'"$nano"'!' "$h" sed -i 's!FROM .*!FROM mcr.microsoft.com/windows/nanoserver:'"$nano"'!' "$h"
done done
for h in amd64/*/hello; do for h in .host-arch/*/hello; do
d="$(dirname "$h")" d="$(dirname "$h")"
b="$(basename "$d")" b="$(basename "$d")"
"$h" > /dev/null "$h" > /dev/null