Last active
November 13, 2025 01:04
-
-
Save RyanSquared/995e40b2abcc4b2a93f979010f2612bb to your computer and use it in GitHub Desktop.
Can't cross compile to GNU, run on Debian
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ARG PROFILE=release | |
| ARG CARGO_BUILD_TARGET=x86_64-unknown-linux-gnu | |
| FROM stagex/pallet-rust@sha256:740b9ed5f2a897d45cafdc806976d84231aa50a64998610750b42a48f8daacab AS pallet-rust | |
| FROM stagex/core-cross-x86_64-gnu-gcc@sha256:88a885049fddb21b48511d36b65d944322f3edfb699e95f1876b6ded8aa91da4 AS cross-x86_64-gnu-gcc | |
| FROM stagex/core-cross-x86_64-gnu-rust@sha256:12d60727f597a67a5ca8ec95c3ec7a6df13c516df30d1d98b4296308f430b1e1 AS cross-x86_64-gnu-rust | |
| FROM stagex/core-cross-x86_64-gnu-libunwind@sha256:3a5a3e2049d56830164b2677df8d96a1081209a6ff59ccecd5c743f69ae5008e AS cross-x86_64-gnu-libunwind | |
| FROM stagex/core-clang@sha256:abf6d2868bc441b5910ef28f38123c6053391521948b33eaf68980fb8be7d105 AS clang | |
| FROM stagex/core-llvm@sha256:bc1c6d67aa73a96dd92f5def7e2701de78b0639d0c815d69110fbb9b3b3e85fe AS llvm | |
| FROM stagex/core-lld@sha256:a5cb61edc071d404cd33cb0b5c7113a334cb90ca203cb40fe6cafd3559b6daa5 AS lld | |
| FROM stagex/core-libffi@sha256:9acd18e59ca11fa727670725e69a976d96f85a00704dea6ad07870bff2bd4e8b AS libffi | |
| FROM stagex/core-make@sha256:a47d8f67f8fd74905f724fdc5f0d18e29df96391751754947bdeaba9bef8f7d8 AS make | |
| FROM pallet-rust AS build | |
| ARG PROFILE | |
| ARG CARGO_BUILD_TARGET | |
| COPY --from=cross-x86_64-gnu-gcc . / | |
| COPY --from=cross-x86_64-gnu-rust . / | |
| COPY --from=cross-x86_64-gnu-libunwind . / | |
| COPY --from=clang . / | |
| COPY --from=llvm . / | |
| COPY --from=lld . / | |
| COPY --from=libffi . / | |
| COPY --from=make . / | |
| ENV RUST_BACKTRACE=1 | |
| ENV RUSTFLAGS="-C codegen-units=1" | |
| ENV RUSTFLAGS="${RUSTFLAGS} -C target-feature=-crt-static" | |
| ENV RUSTFLAGS="${RUSTFLAGS} -C linker=/usr/bin/clang" | |
| ENV RUSTFLAGS="${RUSTFLAGS} -C link-arg=-fuse-ld=lld -C link-arg=-Wl,--threads=1 -C link-arg=-L/opt/cross/x86_64-linux-gnu/lib" | |
| ENV RUSTFLAGS="${RUSTFLAGS} -C link-arg=-Wl,-z,nostart-stop-gc" | |
| RUN cargo new --bin yeet | |
| WORKDIR /yeet | |
| RUN cargo fetch | |
| RUN --network=none cargo build --frozen --profile $PROFILE --bin yeet --target ${CARGO_BUILD_TARGET} | |
| FROM scratch AS package | |
| ARG PROFILE | |
| ARG CARGO_BUILD_TARGET | |
| COPY --from=build /yeet/target/${CARGO_BUILD_TARGET}/${PROFILE}/yeet /opt/yeet/bin/ |
Okay, I think I got it. Being that it wants to dynamically link, its going to be looking for the dynamic libs in whatever filesystem its running in. This Dockerfile:
- Adds the glibc-dev package
- Adds clang lld and gcc from Alpine apk repos
- Installs the Rust target with rustup
- Modifies the RUSTFLAGS paths:
- ENV RUSTFLAGS="${RUSTFLAGS} -C link-arg=-L/usr/glibc-compat/lib"
- ENV RUSTFLAGS="${RUSTFLAGS} -C link-arg=-Wl,--dynamic-linker=/lib64/ld-linux-x86-64.so.2"
- Copies out the right things
- copies shared libs to the package container
- copies the dynamically linked binary to the package container
FROM rust:1.91-alpine AS build
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
ARG CARGO_BUILD_TARGET=x86_64-unknown-linux-gnu
ARG PROFILE
# NOTE: Glibc 2.35 package is broken: https://github.com/sgerrand/alpine-pkg-glibc/issues/176, so we stick to 2.34 for now
RUN ALPINE_GLIBC_BASE_URL="https://github.com/sgerrand/alpine-pkg-glibc/releases/download" && \
ALPINE_GLIBC_PACKAGE_VERSION="2.34-r0" && \
ALPINE_GLIBC_BASE_PACKAGE_FILENAME="glibc-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && \
ALPINE_GLIBC_BIN_PACKAGE_FILENAME="glibc-bin-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && \
ALPINE_GLIBC_I18N_PACKAGE_FILENAME="glibc-i18n-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && \
ALPINE_GLIBC_DEV_PACKAGE_FILENAME="glibc-dev-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && \
apk add --no-cache --virtual=.build-dependencies wget ca-certificates && \
wget -O "/etc/apk/keys/sgerrand.rsa.pub" "https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub" && \
wget \
"$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_I18N_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_DEV_PACKAGE_FILENAME" && \
mv /etc/nsswitch.conf /etc/nsswitch.conf.bak && \
apk add --no-cache --force-overwrite \
"$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_I18N_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_DEV_PACKAGE_FILENAME" && \
\
mv /etc/nsswitch.conf.bak /etc/nsswitch.conf && \
rm "/etc/apk/keys/sgerrand.rsa.pub" && \
(/usr/glibc-compat/bin/localedef --force --inputfile POSIX --charmap UTF-8 "$LANG" || true) && \
echo "export LANG=$LANG" > /etc/profile.d/locale.sh && \
\
apk del glibc-i18n && \
\
rm "/root/.wget-hsts" && \
apk del .build-dependencies && \
rm \
"$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_I18N_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_DEV_PACKAGE_FILENAME"
RUN apk add clang lld gcc
# Add the gnu target for cross-compilation (uses musl toolchain to compile)
RUN rustup target add ${CARGO_BUILD_TARGET}
#FROM stagex/pallet-rust@sha256:740b9ed5f2a897d45cafdc806976d84231aa50a64998610750b42a48f8daacab AS pallet-rust
#FROM stagex/core-cross-x86_64-gnu-gcc@sha256:88a885049fddb21b48511d36b65d944322f3edfb699e95f1876b6ded8aa91da4 AS cross-x86_64-gnu-gcc
#FROM stagex/core-cross-x86_64-gnu-rust@sha256:12d60727f597a67a5ca8ec95c3ec7a6df13c516df30d1d98b4296308f430b1e1 AS cross-x86_64-gnu-rust
#FROM stagex/core-cross-x86_64-gnu-libunwind@sha256:3a5a3e2049d56830164b2677df8d96a1081209a6ff59ccecd5c743f69ae5008e AS cross-x86_64-gnu-libunwind
#FROM stagex/core-clang@sha256:abf6d2868bc441b5910ef28f38123c6053391521948b33eaf68980fb8be7d105 AS clang
#FROM stagex/core-llvm@sha256:bc1c6d67aa73a96dd92f5def7e2701de78b0639d0c815d69110fbb9b3b3e85fe AS llvm
#FROM stagex/core-lld@sha256:a5cb61edc071d404cd33cb0b5c7113a334cb90ca203cb40fe6cafd3559b6daa5 AS lld
#FROM stagex/core-libffi@sha256:9acd18e59ca11fa727670725e69a976d96f85a00704dea6ad07870bff2bd4e8b AS libffi
#FROM stagex/core-make@sha256:a47d8f67f8fd74905f724fdc5f0d18e29df96391751754947bdeaba9bef8f7d8 AS make
#FROM pallet-rust AS build
#COPY --from=cross-x86_64-gnu-gcc . /
#COPY --from=cross-x86_64-gnu-rust . /
#COPY --from=cross-x86_64-gnu-libunwind . /
#COPY --from=clang /usr/bin/clang /usr/bin/clang
#COPY --from=llvm . /
#COPY --from=lld . /
#COPY --from=libffi . /
#COPY --from=make . /
ENV RUST_BACKTRACE=1
ENV RUSTFLAGS="-C codegen-units=1"
# ENV RUSTFLAGS="${RUSTFLAGS} -C target-feature=+crt-static"
ENV RUSTFLAGS="${RUSTFLAGS} -C linker=/usr/bin/clang"
ENV RUSTFLAGS="${RUSTFLAGS} -C link-arg=-fuse-ld=lld"
ENV RUSTFLAGS="${RUSTFLAGS} -C link-arg=-Wl,--threads=1"
ENV RUSTFLAGS="${RUSTFLAGS} -C link-arg=-L/usr/glibc-compat/lib"
ENV RUSTFLAGS="${RUSTFLAGS} -C link-arg=-Wl,-z,nostart-stop-gc"
ENV RUSTFLAGS="${RUSTFLAGS} -C link-arg=-Wl,--dynamic-linker=/lib64/ld-linux-x86-64.so.2"
WORKDIR /testing
ENV CARGO_TARGET_DIR=/target
RUN cargo init --bin
RUN --network=none cargo build --release --target ${CARGO_BUILD_TARGET}
# Check what libraries the binary actually needs
RUN readelf -d /target/${CARGO_BUILD_TARGET}/release/testing | grep NEEDED || true
FROM scratch AS package
ARG PROFILE
ARG CARGO_BUILD_TARGET
COPY --from=build /usr/glibc-compat/lib/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2
COPY --from=build /usr/glibc-compat/lib/libc.so.6 /lib/x86_64-linux-gnu/libc.so.6
COPY --from=build /usr/glibc-compat/lib/libm.so.6 /lib/x86_64-linux-gnu/libm.so.6
COPY --from=build /usr/glibc-compat/lib/libpthread.so.0 /lib/x86_64-linux-gnu/libpthread.so.0
COPY --from=build /usr/glibc-compat/lib/libdl.so.2 /lib/x86_64-linux-gnu/libdl.so.2
COPY --from=build /usr/glibc-compat/lib/librt.so.1 /lib/x86_64-linux-gnu/librt.so.1
COPY --from=build /usr/lib/libgcc_s.so.1 /lib/x86_64-linux-gnu/libgcc_s.so.1
COPY --from=build /target/${CARGO_BUILD_TARGET}/release/testing /opt/testing/bin/testing$ docker build --no-cache -t sui-node-deterministic --output output --build-arg CARGO_BUILD_TARGET=x86_64-unknown-linux-gnu . $ readelf -l ./output/opt/testing/bin/testing | grep interpreter
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
$ strace ./output/opt/testing/bin/testing
execve("./output/opt/testing/bin/testing", ["./output/opt/testing/bin/testing"], 0x7ffe884baf10 /* 52 vars */) = 0
brk(NULL) = 0x5f6dd01b6000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7c8888f1d000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=109635, ...}) = 0
mmap(NULL, 109635, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7c8888f02000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=182856, ...}) = 0
mmap(NULL, 181160, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7c8888ed5000
mmap(0x7c8888ed9000, 143360, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x4000) = 0x7c8888ed9000
mmap(0x7c8888efc000, 16384, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x27000) = 0x7c8888efc000
mmap(0x7c8888f00000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2b000) = 0x7c8888f00000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0p\236\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 840, 64) = 840
fstat(3, {st_mode=S_IFREG|0755, st_size=2003408, ...}) = 0
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 840, 64) = 840
mmap(NULL, 2055800, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7c8888cdf000
mmap(0x7c8888d07000, 1462272, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x28000) = 0x7c8888d07000
mmap(0x7c8888e6c000, 352256, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18d000) = 0x7c8888e6c000
mmap(0x7c8888ec2000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e2000) = 0x7c8888ec2000
mmap(0x7c8888ec8000, 52856, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7c8888ec8000
close(3) = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7c8888cdc000
arch_prctl(ARCH_SET_FS, 0x7c8888cdc780) = 0
set_tid_address(0x7c8888cdca50) = 40627
set_robust_list(0x7c8888cdca60, 24) = 0
rseq(0x7c8888cdc680, 0x20, 0, 0x53053053) = 0
mprotect(0x7c8888ec2000, 16384, PROT_READ) = 0
mprotect(0x7c8888f00000, 4096, PROT_READ) = 0
mprotect(0x5f6dab9d0000, 16384, PROT_READ) = 0
mprotect(0x7c8888f5b000, 8192, PROT_READ) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
munmap(0x7c8888f02000, 109635) = 0
poll([{fd=0, events=0}, {fd=1, events=0}, {fd=2, events=0}], 3, 0) = 0 (Timeout)
rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7c8888d1edf0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
getrandom("\x93\x07\x6a\x25\x25\x7c\x80\xc6", 8, GRND_NONBLOCK) = 8
brk(NULL) = 0x5f6dd01b6000
brk(0x5f6dd01d7000) = 0x5f6dd01d7000
openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 3
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(3, "5f6dab97a000-5f6dab98f000 r--p 0"..., 1024) = 1024
read(3, " /usr/lib/x86_64-linu"..., 1024) = 1024
read(3, "8888f25000 r--p 00000000 00:00 0"..., 1024) = 882
close(3) = 0
sched_getaffinity(40627, 32, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]) = 8
rt_sigaction(SIGSEGV, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
sigaltstack(NULL, {ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=0}) = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7c8888f1a000
mprotect(0x7c8888f1a000, 4096, PROT_NONE) = 0
sigaltstack({ss_sp=0x7c8888f1b000, ss_flags=0, ss_size=8192}, NULL) = 0
rt_sigaction(SIGSEGV, {sa_handler=0x5f6dab99ece0, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x7c8888d1edf0}, NULL, 8) = 0
rt_sigaction(SIGBUS, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGBUS, {sa_handler=0x5f6dab99ece0, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x7c8888d1edf0}, NULL, 8) = 0
write(1, "Hello, world!\n", 14Hello, world!
) = 14
sigaltstack({ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=8192}, NULL) = 0
munmap(0x7c8888f1a000, 12288) = 0
exit_group(0) = ?
+++ exited with 0 +++
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated Dockerfile based on https://github.com/Docker-Hub-sirmark/docker-rust-alpine-glibc also shitting the bed: