Source
FROM scratch AS build
ARG GCC_SOURCE
ARG GCC_VERSION
ARG LINUX_SOURCE
ARG LINUX_VERSION
ARG MUSL_SOURCE
ARG MUSL_VERSION
ARG BINUTILS_SOURCE
ARG BINUTILS_VERSION
ENV TZ=UTC
ENV LANG=C.UTF-8
ENV SOURCE_DATE_EPOCH=1
ENV KCONFIG_NOTIMESTAMP=1
ENV BASE_PATH=/usr/sbin:/usr/bin:/sbin:/bin
ENV PATH=${BASE_PATH}
COPY --from=fetch . .
COPY --from=stagex/bootstrap-stage1 . /
RUN --network=none <<-EOF
set -eux
tar -xf ${LINUX_SOURCE}
tar -xzf ${MUSL_SOURCE}
tar -xf ${BINUTILS_SOURCE}
tar -xf ${GCC_SOURCE}
cd gcc-${GCC_VERSION}
mv ../*.tar.* .; \
./contrib/download_prerequisites
EOF
# Set environment variables based on target (gcc target format, like x86_64 or aarch64)
COPY --chmod=755 <<-'EOF' /env.sh
export TARGET=${TARGET_ARCH}-linux-musl
export SYSROOT=/usr/${TARGET}
export PATH=${SYSROOT}/bin:${BASE_PATH}
EOF
ARG TARGET_LIST="x86_64 aarch64"
# Setup sysroot
COPY --chmod=755 <<-'EOF' /sysroot.sh
set -eux
. /env.sh
mkdir -p ${SYSROOT}
cd ${SYSROOT}
mkdir -pv bin lib lib32 include usr "${TARGET}/bin"
ln -sfv ../bin ../lib ../lib32 ../include usr
cd ${SYSROOT}/${TARGET}
ln -sfv ../lib lib
ln -sfv ../lib32 lib32
ln -sfv ../include include
EOF
RUN --network=none <<-EOF
set -eux
for arch in ${TARGET_LIST}; do
TARGET_ARCH=$arch /sysroot.sh
done
EOF
# Install musl headers
COPY --chmod=755 <<-'EOF' /musl1.sh
set -eux
. /env.sh
cd /musl-${MUSL_VERSION}
make clean distclean
make \
-j$(nproc) \
ARCH="${TARGET_ARCH}" \
prefix="" \
DESTDIR="${SYSROOT}" \
install-headers
EOF
RUN --network=none <<-EOF
set -eux
for arch in ${TARGET_LIST}; do
TARGET_ARCH=$arch /musl1.sh
done
EOF
# Build and install cross binutils
COPY --chmod=755 <<-'EOF' /binutils.sh
set -eux
. /env.sh
mkdir -p /build-binutils-${TARGET_ARCH}
cd /build-binutils-${TARGET_ARCH}
/binutils-${BINUTILS_VERSION}/configure \
--target="${TARGET}" \
--prefix="" \
--exec-prefix="" \
--sbindir=/bin \
--libexecdir=/lib \
--datarootdir=/_tmp \
--with-sysroot=/ \
--with-build-sysroot="${SYSROOT}" \
--disable-nls \
--disable-multilib \
--disable-plugins \
--disable-gprofng \
--enable-64-bit-bfd \
--enable-ld=default \
--enable-install-libiberty \
--enable-deterministic-archives
make \
-j$(nproc) \
all-binutils \
all-gas \
all-ld
make \
-j$(nproc) \
DESTDIR="${SYSROOT}" \
install-strip-binutils \
install-strip-gas \
install-strip-ld
EOF
RUN --network=none <<-EOF
set -eux
for arch in ${TARGET_LIST}; do
TARGET_ARCH=$arch /binutils.sh
done
EOF
# Build and install cross gcc and bootstrap libgcc
COPY --chmod=755 <<-'EOF' /gcc1.sh
set -eux
. /env.sh
mkdir -p /build-gcc-${TARGET_ARCH}
cd /build-gcc-${TARGET_ARCH}
/gcc-${GCC_VERSION}/configure \
--prefix="" \
--exec-prefix="" \
--sbindir=/bin \
--libexecdir=/lib \
--datarootdir=/_tmp \
--target=${TARGET} \
--disable-multilib \
--disable-bootstrap \
--disable-assembly \
--disable-libmudflap \
--disable-libsanitizer \
--disable-gnu-indirect-function \
--disable-libmpx \
--disable-werror \
--enable-languages=c,c++ \
--enable-tls \
--enable-initfini-array \
--enable-libstdcxx-time=rt \
--enable-deterministic-archives \
--with-build-sysroot=${SYSROOT} \
--with-sysroot=/
make \
-j$(nproc) \
all-gcc
make \
-j$(nproc) \
enable_shared=no \
all-target-libgcc
make \
-j$(nproc) \
DESTDIR="${SYSROOT}" \
install-strip-gcc \
install-strip-target-libgcc
EOF
RUN --network=none <<-EOF
set -eux
for arch in ${TARGET_LIST}; do
TARGET_ARCH=$arch /gcc1.sh
done
EOF
# Build and install cross musl
COPY --chmod=755 <<-'EOF' /musl2.sh
set -eux
. /env.sh
mkdir -p /build-musl-${TARGET_ARCH}
cd /build-musl-${TARGET_ARCH}
ARCH="${TARGET_ARCH}" \
CC="${TARGET}-gcc" \
CROSS_COMPILE="${TARGET}-" \
LIBCC="${SYSROOT}/lib/gcc/${TARGET}/${GCC_VERSION}/libgcc.a" \
/musl-${MUSL_VERSION}/configure \
--host="${TARGET}" \
--prefix="" \
--disable-wrapper
make \
-j$(nproc) \
AR="${TARGET}-ar" \
RANLIB="${TARGET}-ranlib"
make \
-j$(nproc) \
AR="${TARGET}-ar" \
RANLIB="${TARGET}-ranlib" \
DESTDIR="${SYSROOT}" \
install-libs
rm -f "${SYSROOT}"/lib/ld-musl-${TARGET_ARCH}.so.1
cp -af \
"${SYSROOT}/usr/lib/libc.so" \
"${SYSROOT}/lib/ld-musl-${TARGET_ARCH}.so.1"
EOF
RUN --network=none <<-EOF
set -eux
for arch in ${TARGET_LIST}; do
TARGET_ARCH=$arch /musl2.sh
done
EOF
# Build and install final libgcc/libstdc++
COPY --chmod=755 <<-'EOF' /gcc2.sh
set -eux
. /env.sh
mkdir -p /build-gcc-${TARGET_ARCH}
cd /build-gcc-${TARGET_ARCH}
make \
-j $(nproc) \
-C "${TARGET}/libgcc" \
distclean
make \
-j$(nproc) \
enable_shared=yes \
all-target-libgcc \
all-target-libstdc++-v3
make \
-j$(nproc) \
DESTDIR="${SYSROOT}" \
install-strip-target-libgcc \
install-strip-target-libstdc++-v3
EOF
RUN --network=none <<-EOF
set -eux
for arch in ${TARGET_LIST}; do
TARGET_ARCH=$arch /gcc2.sh
done
EOF
# Build and install linux headers
COPY --chmod=755 <<-'EOF' /linux.sh
set -eux
. /env.sh
cp -r /linux-${LINUX_VERSION} /linux-build-${TARGET_ARCH}
cd /linux-build-${TARGET_ARCH}
set -eux
make -j$(nproc) ARCH="$(echo ${TARGET_ARCH} | sed 's/aarch64/arm64/')" headers
find usr/include ! -name '*.h' -type f -delete
cp -Rv usr/include/* "${SYSROOT}/include/"
rm -rf "${SYSROOT}/_tmp"
EOF
RUN --network=none <<-EOF
set -eux
for arch in ${TARGET_LIST}; do
TARGET_ARCH=$arch /linux.sh
done
EOF
# Finalize installation, copy prefixed binaries to /usr/bin
COPY --chmod=755 <<-'EOF' /install.sh
set -eux
. /env.sh
rm -rf "${SYSROOT}/_tmp"
mkdir -p /rootfs/${SYSROOT}
cd /rootfs/${SYSROOT}
mv ${SYSROOT}/* .
mkdir -p /rootfs/usr/bin
for bin_path in $(find bin -name ${TARGET}-*); do
bin_name=$(basename "$bin_path")
ln -s ${SYSROOT}/bin/${bin_name} /rootfs/usr/bin/${bin_name}
done
EOF
RUN --network=none <<-EOF
set -eux
for arch in ${TARGET_LIST}; do
TARGET_ARCH=$arch /install.sh
done
EOF
FROM stagex/bootstrap-stage1 AS package
COPY --from=build /rootfs/ /