mirror of
https://gitlab.alpinelinux.org/alpine/aports.git
synced 2025-04-15 21:06:46 +02:00
173 lines
5.7 KiB
Bash
Executable file
173 lines
5.7 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
set -e
|
|
|
|
abuild_opts="-r"
|
|
if [ "$1" = "-k" ] || [ "$1" = "--keep" ]; then
|
|
abuild_opts="$abuild_opts -k"
|
|
shift
|
|
fi
|
|
|
|
TARGET_ARCH="$1"
|
|
SUDO_APK=abuild-apk
|
|
|
|
shift
|
|
|
|
# optional cross build packages
|
|
#: ${KERNEL_PKG=linux-firmware linux-lts}
|
|
#: ${COMPILER_PKG=libffi brotli libev c-ares cunit nghttp2 libidn2 libunistring libpsl curl libssh2 libxml2 pax-utils llvm15 community/ghc llvm19 rust community/go}
|
|
# FIXME: Maybe subdivide into ghc, rust, and go stuff
|
|
: ${MKINITFS=libcap-ng ncurses readline sqlite util-linux libaio lvm2 popt xz json-c argon2 cryptsetup kmod lddtree mkinitfs}
|
|
#: ${OPENSSH=openssh}
|
|
|
|
if [ -z "$TARGET_ARCH" ]; then
|
|
program=$(basename $0)
|
|
cat <<EOF
|
|
usage: $program TARGET_ARCH
|
|
|
|
This script creates a local cross-compiler, and uses it to
|
|
cross-compile an Alpine Linux base system for new architecture.
|
|
|
|
Steps for introducing new architecture include:
|
|
- adding the compiler triplet and arch type to abuild
|
|
- adding the arch type detection to apk-tools
|
|
- adjusting build rules for packages that are arch aware:
|
|
gcc, openssl, linux-headers, musl
|
|
- create new kernel config for linux-lts
|
|
|
|
After these steps the initial cross-build can be completed
|
|
by running this with the target arch as parameter, e.g.:
|
|
./$program aarch64
|
|
|
|
The cross-compiler generated by this script is not intended
|
|
nor supported for any use other than building the base system
|
|
and other packages in the bootstrap path.
|
|
|
|
EOF
|
|
return 1
|
|
fi
|
|
|
|
# get abuild configurables
|
|
sharedir=${ABUILD_SHAREDIR:-/usr/share/abuild}
|
|
[ -e "$sharedir"/functions.sh ] || (echo "abuild not found" ; exit 1)
|
|
CBUILDROOT="$(CTARGET=$TARGET_ARCH . "$sharedir"/functions.sh ; echo $CBUILDROOT)"
|
|
. "$sharedir"/functions.sh
|
|
[ -z "$CBUILD_ARCH" ] && die "abuild is too old (use 2.29.0 or later)"
|
|
[ -z "$CBUILDROOT" ] && die "CBUILDROOT not set for $TARGET_ARCH"
|
|
export CBUILD
|
|
|
|
# deduce aports directory
|
|
[ -z "$APORTS" ] && APORTS=$(realpath $(dirname $0)/../)
|
|
[ -e "$APORTS/main/build-base" ] || die "Unable to deduce aports base checkout"
|
|
|
|
apkbuildname() {
|
|
local repo="${1%%/*}"
|
|
local pkg="${1##*/}"
|
|
[ "$repo" = "$1" ] && repo="main"
|
|
echo $APORTS/$repo/$pkg/APKBUILD
|
|
}
|
|
|
|
msg() {
|
|
[ -n "$quiet" ] && return 0
|
|
local prompt="$GREEN>>>${NORMAL}"
|
|
local name="${BLUE}bootstrap-${TARGET_ARCH}${NORMAL}"
|
|
printf "${prompt} ${name}: %s\n" "$1" >&2
|
|
}
|
|
|
|
if [ ! -d "$CBUILDROOT" ]; then
|
|
msg "Creating sysroot in $CBUILDROOT"
|
|
mkdir -p "$CBUILDROOT/etc/apk/keys"
|
|
# /etc/apk/keys and ~/.abuild/ can contain files with the same names.
|
|
# if that is the case, cp will abort copying and fail. Then on the next
|
|
# run of the bootstrap script, 1) the keys are not in the sysroot and
|
|
# 2) the apk database is not initialized the sysroot
|
|
# Thus it's unusable at that point and needs to be deleted manually.
|
|
cp -a /etc/apk/keys/* "$CBUILDROOT/etc/apk/keys"
|
|
cp -a ~/.abuild/*.pub "$CBUILDROOT/etc/apk/keys"
|
|
${SUDO_APK} add --quiet --initdb --arch $TARGET_ARCH --root $CBUILDROOT
|
|
fi
|
|
|
|
msg "Building cross-compiler"
|
|
|
|
# Build and install cross binutils (--with-sysroot)
|
|
CTARGET=$TARGET_ARCH BOOTSTRAP=nobase APKBUILD=$(apkbuildname binutils) abuild $abuild_opts
|
|
|
|
if ! CHOST=$TARGET_ARCH BOOTSTRAP=nolibc APKBUILD=$(apkbuildname musl) abuild up2date 2>/dev/null; then
|
|
# C-library headers for target
|
|
CHOST=$TARGET_ARCH BOOTSTRAP=nocc APKBUILD=$(apkbuildname musl) abuild $abuild_opts
|
|
|
|
# Minimal cross GCC
|
|
EXTRADEPENDS_HOST="musl-dev" \
|
|
CTARGET=$TARGET_ARCH BOOTSTRAP=nolibc APKBUILD=$(apkbuildname gcc) abuild $abuild_opts
|
|
|
|
# Cross build bootstrap C-library for the target
|
|
EXTRADEPENDS_BUILD="gcc-pass2-$TARGET_ARCH" \
|
|
CHOST=$TARGET_ARCH BOOTSTRAP=nolibc APKBUILD=$(apkbuildname musl) abuild $abuild_opts
|
|
fi
|
|
|
|
# Build libucontext without docs and pkgconfig file as a dependency for gcc-gdc
|
|
EXTRADEPENDS_BUILD="gcc-pass2-$TARGET_ARCH" \
|
|
EXTRADEPENDS_TARGET="musl musl-dev" \
|
|
CHOST=$TARGET_ARCH BOOTSTRAP=nobase APKBUILD=$(apkbuildname libucontext) abuild $abuild_opts
|
|
|
|
# Full cross GCC
|
|
EXTRADEPENDS_TARGET="musl musl-dev libucontext-dev" \
|
|
CTARGET=$TARGET_ARCH BOOTSTRAP=nobase APKBUILD=$(apkbuildname gcc) abuild $abuild_opts
|
|
|
|
# Cross build-base
|
|
CTARGET=$TARGET_ARCH BOOTSTRAP=nobase APKBUILD=$(apkbuildname build-base) abuild $abuild_opts
|
|
|
|
msg "Cross building base system"
|
|
|
|
# Implicit dependencies for early targets
|
|
EXTRADEPENDS_TARGET="libgcc libstdc++ musl-dev"
|
|
|
|
# On a few architectures like riscv64 we need to account for
|
|
# gcc requiring -ltomic to be set explicitly if a C[++]11 program
|
|
# uses atomics (e.g. #include <atomic>):
|
|
# https://github.com/riscv/riscv-gnu-toolchain/issues/183#issuecomment-253721765
|
|
# The reason gcc itself is needed is because .so is in that package,
|
|
# not in libatomic.
|
|
if [ "$TARGET_ARCH" = "riscv64" ]; then
|
|
NEEDS_LIBATOMIC="yes"
|
|
fi
|
|
|
|
if [ $# -eq 0 ]; then
|
|
set -- fortify-headers linux-headers musl pkgconf zlib \
|
|
openssl ca-certificates libmd \
|
|
gmp mpfr4 mpc1 isl26 libucontext zstd binutils gcc \
|
|
bsd-compat-headers libbsd busybox make \
|
|
apk-tools file \
|
|
libcap openrc alpine-conf alpine-baselayout alpine-keys alpine-base patch build-base \
|
|
attr acl fakeroot tar \
|
|
lzip abuild \
|
|
$OPENSSH \
|
|
$MKINITFS \
|
|
$COMPILER_PKG \
|
|
$KERNEL_PKG
|
|
fi
|
|
|
|
for PKG; do
|
|
|
|
if [ "$NEEDS_LIBATOMIC" = "yes" ]; then
|
|
EXTRADEPENDS_BUILD="libatomic gcc-$TARGET_ARCH g++-$TARGET_ARCH"
|
|
fi
|
|
EXTRADEPENDS_TARGET="$EXTRADEPENDS_TARGET" EXTRADEPENDS_BUILD="$EXTRADEPENDS_BUILD" \
|
|
CHOST=$TARGET_ARCH BOOTSTRAP=bootimage APKBUILD=$(apkbuildname $PKG) abuild $abuild_opts
|
|
|
|
case "$PKG" in
|
|
fortify-headers)
|
|
# Additional implicit dependencies once built
|
|
EXTRADEPENDS_TARGET="$EXTRADEPENDS_TARGET $PKG"
|
|
;;
|
|
gcc)
|
|
if [ "$NEEDS_LIBATOMIC" = "yes" ]; then
|
|
EXTRADEPENDS_TARGET="libatomic gcc $EXTRADEPENDS_TARGET"
|
|
fi
|
|
;;
|
|
build-base)
|
|
# After build-base, that alone is sufficient dependency in the target
|
|
EXTRADEPENDS_TARGET="busybox $PKG"
|
|
;;
|
|
esac
|
|
done
|