Skip to content

Commit 9e6baa1

Browse files
committed
build: completely refactor static build to support cross-compilation
1 parent 8dcb2d6 commit 9e6baa1

14 files changed

Lines changed: 1195 additions & 617 deletions

.docker/Dockerfile.alpine

Lines changed: 62 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,109 @@
11
# syntax=docker/dockerfile:1
22
ARG ARCH=amd64
33
FROM $ARCH/alpine:latest
4+
5+
ARG ARCH
6+
ARG TARGET_ARCHS
7+
ARG TOOLCHAIN_OPTIMIZE=2
8+
49
RUN apk update
510
RUN apk upgrade
6-
RUN apk add --no-cache \
11+
RUN qemu_pkgs=""; \
12+
for arch in $(echo $TARGET_ARCHS | tr ',' ' '); do \
13+
qemu_pkgs="$qemu_pkgs qemu-$arch"; \
14+
done; \
15+
apk add --no-cache \
716
bash-completion \
817
build-base \
918
wget \
1019
curl \
1120
vim \
1221
tar \
1322
ripgrep \
14-
py3-pip \
1523
less \
1624
gcc \
1725
g++ \
1826
clang18 \
1927
clang19 \
28+
clang20 \
29+
lld \
2030
git \
31+
xz \
32+
gzip \
33+
bzip2 \
34+
zstd \
2135
ccache \
22-
samurai \
36+
ninja-build \
2337
cmake \
2438
make \
2539
bison \
2640
flex \
2741
ronn \
42+
perf \
43+
py3-pip \
2844
fuse \
29-
fuse-dev \
30-
fuse-static \
3145
fuse3 \
32-
fuse3-dev \
33-
fuse3-static \
3446
pkgconf \
35-
binutils-dev \
36-
libevent-dev \
37-
libevent-static \
38-
linux-headers \
39-
date-dev \
40-
range-v3-dev \
41-
zlib-static \
42-
libucontext-dev \
43-
libdwarf-dev \
44-
elfutils-dev \
45-
utfcpp \
46-
nlohmann-json \
4747
meson \
4848
autoconf \
4949
strace \
50-
gdb
51-
52-
# Install UPX
53-
ARG ARCH
54-
# UPX isn't supported on RISC-V yet, so skip this
55-
RUN if [ "$ARCH" != "riscv64" ]; then \
56-
wget -O - https://github.com/upx/upx/releases/download/v5.0.0/upx-5.0.0-$(bash -c "echo \${0//v8/}" $ARCH)_linux.tar.xz | tar -xJf - -C /usr/local/bin --strip-components=1 --wildcards "*/upx"; \
57-
else \
58-
echo "Skipping UPX installation for RISC-V architecture while it is not supported."; \
59-
echo "See https://github.com/upx/upx/discussions/793 for details."; \
60-
fi
61-
62-
# Install mistletoe
63-
RUN pip3 install --break-system-packages --root-user-action ignore mistletoe
50+
gdb \
51+
gmp-dev \
52+
zlib-static \
53+
zstd-static \
54+
zlib-dev \
55+
zstd-dev \
56+
mpfr-dev \
57+
mpc1-dev \
58+
isl-dev \
59+
texinfo \
60+
linux-headers \
61+
gdb-multiarch \
62+
rsync \
63+
screen \
64+
$qemu_pkgs
6465

65-
# Install size-optimized and static-link-optimized libstdc++
66-
RUN apk add --no-cache gmp-dev mpfr-dev mpc1-dev isl-dev
67-
COPY install-libstdcxx.sh /usr/local/bin/install-libstdcxx.sh
68-
RUN bash /usr/local/bin/install-libstdcxx.sh
66+
COPY fetch.sh /usr/local/bin/fetch.sh
6967

7068
# Install mold
7169
COPY install-mold.sh /usr/local/bin/install-mold.sh
72-
RUN bash /usr/local/bin/install-mold.sh
70+
RUN --mount=type=cache,id=ccache,target=/root/.ccache --mount=type=cache,id=pkgcache,target=/root/.pkgcache \
71+
bash /usr/local/bin/install-mold.sh
7372

7473
# Install bloaty
7574
COPY install-bloaty.sh /usr/local/bin/install-bloaty.sh
76-
RUN if [ "$ARCH" != "riscv64" ]; then \
75+
RUN --mount=type=cache,id=ccache,target=/root/.ccache --mount=type=cache,id=pkgcache,target=/root/.pkgcache \
76+
if [ "$ARCH" == "amd64" ]; then \
7777
bash /usr/local/bin/install-bloaty.sh; \
7878
else \
79-
echo "Skipping bloaty installation for RISC-V."; \
79+
echo "Skipping bloaty installation for $ARCH."; \
8080
fi
8181

82+
RUN apk del linux-headers
83+
84+
# Install size-optimized and static-link-optimized libstdc++
85+
COPY install-toolchain.sh /usr/local/bin/install-toolchain.sh
86+
RUN --mount=type=cache,id=ccache,target=/root/.ccache --mount=type=cache,id=pkgcache,target=/root/.pkgcache \
87+
bash /usr/local/bin/install-toolchain.sh $TOOLCHAIN_OPTIMIZE $TARGET_ARCHS
88+
89+
RUN apk del zlib-dev zstd-dev
90+
8291
# Install all static libraries
8392
COPY install-static-libs.sh /usr/local/bin/install-static-libs.sh
84-
RUN bash /usr/local/bin/install-static-libs.sh gcc clang-19 :alpine
8593

86-
# Install the *real* ninja...
87-
# TODO: move this up if we change anything
88-
RUN apk add --no-cache ninja-build
94+
RUN --mount=type=cache,id=ccache,target=/root/.ccache --mount=type=cache,id=pkgcache,target=/root/.pkgcache \
95+
bash /usr/local/bin/install-static-libs.sh :all $TARGET_ARCHS
96+
97+
# Install UPX
98+
# UPX isn't supported on RISC-V/S390 (yet), so skip this
99+
RUN if [ "$ARCH" == "amd64" ] || [ "$ARCH" == "arm64v8" ]; then \
100+
wget -O - https://github.com/upx/upx/releases/download/v5.0.2/upx-5.0.2-$(bash -c "echo \${0//v8/}" $ARCH)_linux.tar.xz | tar -xJf - -C /usr/local/bin --strip-components=1 --wildcards "*/upx"; \
101+
else \
102+
echo "Skipping UPX installation for $ARCH architecture while it is not supported."; \
103+
echo "See https://github.com/upx/upx/discussions/793 for details."; \
104+
fi
105+
106+
RUN pip3 install --break-system-packages --root-user-action ignore mistletoe
89107

90108
# Set up git & user
91109
RUN git config --global --add safe.directory /workspace

.docker/Dockerfile.ubuntu

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,6 @@ RUN apt install -y \
7272
libflac++-dev \
7373
nlohmann-json3-dev \
7474
python3-mistletoe
75-
### XXX: no more static libs for Ubuntu
76-
# COPY install-static-libs.sh /usr/local/bin/install-static-libs.sh
77-
# # TODO: gcc-14 cannot build the current version of libunwind
78-
# RUN bash /usr/local/bin/install-static-libs.sh gcc-13 clang-18 :ubuntu
79-
ARG ARCH
80-
# upx-4.2.2 is broken for arm64 (https://github.com/upx/upx/issues/758)
81-
RUN wget -O - https://github.com/upx/upx/releases/download/v5.0.0/upx-5.0.0-$(bash -c "echo \${0//v8/}" $ARCH)_linux.tar.xz | tar -xJf - -C /usr/local/bin --strip-components=1 --wildcards "*/upx"
8275
# current ronn version is horribly broken
8376
RUN gem install ronn-ng
8477
# RUN useradd -g users -u 1000 -m mhx

.docker/Makefile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
IMAGE_UBUNTU="dwarfs-buildenv"
22
IMAGE_DEBIAN="dwarfs-buildenv-debian"
33
IMAGE_ALPINE="dwarfs-buildenv-alpine"
4-
IMAGE_ALPINE_RISCV="dwarfs-buildenv-alpine-riscv64"
4+
IMAGE_ALPINE_NEWARCH="dwarfs-buildenv-alpine-newarch"
55
IMAGE_UBUNTU2204="dwarfs-buildenv-ubuntu2204"
66
IMAGE_FEDORA="dwarfs-buildenv-fedora"
77
IMAGE_ARCH="dwarfs-buildenv-arch"
@@ -34,16 +34,16 @@ run_debian:
3434
@docker run $(COMMON_RUN_OPTS) $(IMAGE_DEBIAN)
3535

3636
build_alpine:
37-
docker build -f Dockerfile.alpine -t $(IMAGE_ALPINE) .
37+
docker buildx build -f Dockerfile.alpine --build-arg TARGET_ARCHS=x86_64,aarch64,riscv64,ppc64le,s390x,arm,i386 -t $(IMAGE_ALPINE) .
3838

3939
run_alpine:
4040
@docker run $(COMMON_RUN_OPTS) $(IMAGE_ALPINE)
4141

42-
build_alpine_riscv:
43-
docker build -f Dockerfile.alpine -t $(IMAGE_ALPINE_RISCV) --build-arg ARCH=riscv64 .
42+
build_alpine_newarch:
43+
docker buildx build -f Dockerfile.alpine --build-arg TARGET_ARCHS=s390x -t $(IMAGE_ALPINE_NEWARCH) .
4444

45-
run_alpine_riscv:
46-
@docker run $(COMMON_RUN_OPTS) $(IMAGE_ALPINE_RISCV)
45+
run_alpine_newarch:
46+
@docker run $(COMMON_RUN_OPTS) $(IMAGE_ALPINE_NEWARCH)
4747

4848
build_ubuntu2204:
4949
docker build -f Dockerfile.ubuntu-2204 -t $(IMAGE_UBUNTU2204) .

.docker/build-linux.sh

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ mkdir -p "$LOCAL_REPO_PATH"
99
LAST_UPDATE_FILE="$LOCAL_REPO_PATH/last-update"
1010

1111
WORKFLOW_LOG_DIR="/artifacts/workflow-logs/${GITHUB_RUN_ID}"
12-
NINJA_LOG_FILE="${WORKFLOW_LOG_DIR}/ninja-${BUILD_ARCH},${BUILD_DIST},${BUILD_TYPE}.log"
13-
BUILD_LOG_FILE="${WORKFLOW_LOG_DIR}/build-${BUILD_ARCH},${BUILD_DIST},${BUILD_TYPE}.log"
12+
NINJA_LOG_FILE="${WORKFLOW_LOG_DIR}/ninja-${BUILD_ARCH},${CROSS_ARCH},${BUILD_DIST},${BUILD_TYPE}.log"
13+
BUILD_LOG_FILE="${WORKFLOW_LOG_DIR}/build-${BUILD_ARCH},${CROSS_ARCH},${BUILD_DIST},${BUILD_TYPE}.log"
1414
mkdir -p "$WORKFLOW_LOG_DIR"
1515

1616
log() {
@@ -77,7 +77,7 @@ cd build
7777
# Stick to clang-18, clang-19 has a regression for nilsimsa performance
7878
if [[ "$BUILD_DIST" == "alpine" ]]; then
7979
GCC_VERSION=
80-
CLANG_VERSION=-19
80+
CLANG_VERSION=-20
8181
elif [[ "$BUILD_DIST" == "ubuntu-2204" ]]; then
8282
GCC_VERSION=-12
8383
CLANG_VERSION=-15
@@ -114,6 +114,9 @@ case "-$BUILD_TYPE-" in
114114
*-ubuntu-*|*-debian-*)
115115
export CC=gcc$GCC_VERSION CXX=g++$GCC_VERSION
116116
;;
117+
*)
118+
export CC=gcc CXX=g++
119+
;;
117120
esac
118121
export COMPILER=gcc
119122
;;
@@ -182,7 +185,16 @@ esac
182185

183186
case "-$BUILD_TYPE-" in
184187
*-static-*)
185-
export LDFLAGS="${LDFLAGS} -fuse-ld=mold"
188+
case "$CROSS_ARCH" in
189+
ppc64le)
190+
# https://github.com/rui314/mold/issues/1490
191+
CMAKE_ARGS="${CMAKE_ARGS} -DDISABLE_MOLD=1"
192+
export LDFLAGS="${LDFLAGS} -fuse-ld=lld"
193+
;;
194+
*)
195+
export LDFLAGS="${LDFLAGS} -fuse-ld=mold"
196+
;;
197+
esac
186198
;;
187199
esac
188200

@@ -287,39 +299,49 @@ if [[ "-$BUILD_TYPE-" == *-shared-* ]]; then
287299
fi
288300

289301
if [[ "-$BUILD_TYPE-" == *-static-* ]]; then
290-
if [[ "-$BUILD_TYPE-" == *-relsize-* ]]; then
291-
_LIBSTDCXXDIR="/opt/static-libs/libstdc++-Os/lib"
292-
if [[ "$ARCH" == "aarch64" ]]; then
293-
# Similar to the issue with *not* linking against `gcc_eh` in the CMakeLists.txt,
294-
# if we link against the `gcc_eh` from the `-Os` build, we run into exactly the
295-
# same issue. So we temporarily copy the size-optimized `libgcc.a` to a directory
296-
# we then use for linking.
297-
_GCCLIBDIR="/tmp/gcclib"
298-
mkdir -p "$_GCCLIBDIR"
299-
cp -a "$_LIBSTDCXXDIR"/gcc/*/*/libgcc.a "$_GCCLIBDIR"
300-
else
301-
_GCCLIBDIR=$(ls -d1 $_LIBSTDCXXDIR/gcc/*/*)
302-
fi
303-
LDFLAGS="${LDFLAGS} -L$_GCCLIBDIR -L$_LIBSTDCXXDIR"
302+
# A size-optimized libgcc/libstdc++/musl will only save about 10k for the universal
303+
# and fuse-extract binaries, so we'll just stick to using the -O2 toolchain.
304+
_SYSROOT="/opt/cross/O2"
305+
_MARCH="${CROSS_ARCH}"
306+
if [[ -z "$CROSS_ARCH" ]]; then
307+
_MARCH="${ARCH}"
304308
fi
305-
export LDFLAGS="${LDFLAGS} -L/opt/static-libs/$COMPILER/lib"
306-
if [[ "$ARCH" == "aarch64" ]]; then
307-
# For some reason, this dependency of libunwind is not resolved on aarch64
308-
export LDFLAGS="${LDFLAGS} -lz"
309+
if [[ "$_MARCH" == "arm" ]]; then
310+
_TARGET="${_MARCH}-linux-musleabihf"
311+
else
312+
_TARGET="${_MARCH}-alpine-linux-musl"
309313
fi
310-
CMAKE_ARGS="${CMAKE_ARGS} -DSTATIC_BUILD_DO_NOT_USE=1 -DWITH_UNIVERSAL_BINARY=1 -DWITH_FUSE_EXTRACT_BINARY=1"
314+
export CC="${_TARGET}-${CC}"
315+
export CXX="${_TARGET}-${CXX}"
316+
export STRIP_TOOL="${_TARGET}-strip"
317+
export PATH="$_SYSROOT/usr/bin:$PATH"
318+
319+
_staticprefix="/opt/static-libs/$COMPILER/$_TARGET"
311320
if [[ "$BUILD_TYPE" == *-minimal-* ]]; then
312-
_jemallocprefix="/opt/static-libs/$COMPILER-jemalloc-minimal"
321+
_jemallocprefix="/opt/static-libs/$COMPILER-jemalloc-minimal/$_TARGET"
313322
else
314323
CMAKE_ARGS="${CMAKE_ARGS} -DWITH_PXATTR=1"
315-
_jemallocprefix="/opt/static-libs/$COMPILER-jemalloc-full"
324+
_jemallocprefix="/opt/static-libs/$COMPILER-jemalloc-full/$_TARGET"
316325
fi
317326
if [[ "$BUILD_TYPE" == *-libressl-* ]]; then
318-
_sslprefix="/opt/static-libs/$COMPILER-libressl"
327+
_sslprefix="/opt/static-libs/$COMPILER-libressl/$_TARGET"
319328
else
320-
_sslprefix="/opt/static-libs/$COMPILER-openssl"
329+
_sslprefix="/opt/static-libs/$COMPILER-openssl/$_TARGET"
330+
fi
331+
332+
export LDFLAGS="${LDFLAGS} -static-libgcc -L$_staticprefix/lib -L$_sslprefix/lib"
333+
export CFLAGS="${CFLAGS} -isystem $_staticprefix/include"
334+
export CXXFLAGS="${CXXFLAGS} -isystem $_staticprefix/include"
335+
336+
if [[ "$_MARCH" == "i386" ]]; then
337+
export LDFLAGS="${LDFLAGS} -lucontext"
338+
fi
339+
340+
CMAKE_ARGS="${CMAKE_ARGS} -DCMAKE_SYSROOT=$_SYSROOT -DCMAKE_FIND_ROOT_PATH=$_staticprefix;$_sslprefix;$_jemallocprefix -DCMAKE_PREFIX_PATH=$_staticprefix;$_sslprefix;$_jemallocprefix -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY -DSTATIC_BUILD_DO_NOT_USE=1 -DWITH_UNIVERSAL_BINARY=1 -DWITH_FUSE_EXTRACT_BINARY=1"
341+
342+
if [[ -n "$CROSS_ARCH" ]]; then
343+
CMAKE_ARGS="${CMAKE_ARGS} -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=$_MARCH -DCMAKE_CROSSCOMPILING_EMULATOR=/usr/bin/qemu-$_MARCH -DFOLLY_HAVE_UNALIGNED_ACCESS=OFF -DFOLLY_HAVE_WEAK_SYMBOLS=ON -DFOLLY_HAVE_LINUX_VDSO=OFF -DFOLLY_HAVE_WCHAR_SUPPORT=OFF -DHAVE_VSNPRINTF_ERRORS=OFF"
321344
fi
322-
CMAKE_ARGS="${CMAKE_ARGS} -DSTATIC_BUILD_EXTRA_PREFIX=/opt/static-libs/$COMPILER;$_sslprefix;$_jemallocprefix"
323345
fi
324346

325347
INSTALLDIR="$HOME/install"

.docker/check_lib_versions.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@
2323
# "microsoft/mimalloc",
2424
"jemalloc/jemalloc",
2525
"tukaani-project/xz",
26+
"davea42/libdwarf-code",
27+
"libevent/libevent",
28+
"nlohmann/json",
29+
"HowardHinnant/date",
30+
"nemtrif/utfcpp",
31+
"ericniebler/range-v3",
32+
"greg7mdp/parallel-hashmap",
2633
]
2734

2835

.docker/fetch.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/bin/bash
2+
3+
set -ex
4+
5+
URL=$1
6+
FILE=${2:-$(basename "$URL")}
7+
SHA512SUM="${3}"
8+
9+
URLHASH=$(echo -n "$URL" | sha256sum | awk '{print $1}')
10+
CACHEDIR="$HOME/.pkgcache"
11+
CACHEFILE="$CACHEDIR/$URLHASH"
12+
13+
if [ ! -f "$CACHEFILE" ]; then
14+
rm -f "$CACHEFILE.tmp"
15+
curl --retry 5 -L "$URL" > "$CACHEFILE.tmp"
16+
if [ -n "$SHA512SUM" ]; then
17+
echo "$SHA512SUM $CACHEFILE.tmp" | sha512sum -c -
18+
if [ $? -ne 0 ]; then
19+
echo "Checksum verification failed for $URL"
20+
rm -f "$CACHEFILE.tmp"
21+
exit 1
22+
fi
23+
fi
24+
mv -f "$CACHEFILE.tmp" "$CACHEFILE"
25+
fi
26+
27+
if [ "$FILE" == "-" ]; then
28+
cat "$CACHEFILE"
29+
else
30+
cp "$CACHEFILE" "$FILE"
31+
fi

.docker/install-bloaty.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ cd "$HOME"
66
mkdir pkgs
77
cd pkgs
88

9-
git clone --recurse-submodules https://github.com/google/bloaty
9+
git clone --depth=1 --recurse-submodules --shallow-submodules https://github.com/google/bloaty
1010
cd bloaty
1111
mkdir build
1212
cd build
1313

14+
export PATH="/usr/lib/ccache/bin:$PATH"
15+
1416
cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local
1517
ninja
18+
ccache -s
1619
ninja install
1720

1821
cd "$HOME"

0 commit comments

Comments
 (0)