| 1 | |
| 2 |
|
| 3 | set -e
|
| 4 |
|
| 5 | abuild_opts="-r"
|
| 6 | if [ "$1" = "-k" ] || [ "$1" = "--keep" ]; then
|
| 7 | abuild_opts="$abuild_opts -k"
|
| 8 | shift
|
| 9 | fi
|
| 10 |
|
| 11 | CTARGET="$1"
|
| 12 | CHOST="$CBUILD"
|
| 13 | CARCH="$CBUILD_ARCH"
|
| 14 | SUDO_APK=abuild-apk
|
| 15 |
|
| 16 | shift
|
| 17 |
|
| 18 | |
| 19 | |
| 20 | |
| 21 | |
| 22 | |
| 23 | |
| 24 | : ${GO=community/go}
|
| 25 | : ${LLVM_DEPS=libffi brotli libev c-ares cunit nghttp2 nghttp3 libidn2 libunistring libpsl curl libssh2 libxml2}
|
| 26 | : ${RUST=llvm22 rust}
|
| 27 | |
| 28 | |
| 29 |
|
| 30 | if [ -z "$CTARGET" ]; then
|
| 31 | program=$(basename $0)
|
| 32 | cat <<EOF
|
| 33 | usage: $program CTARGET_ARCH
|
| 34 |
|
| 35 | This script creates a local cross-compiler, and uses it to
|
| 36 | cross-compile an Alpine Linux base system for new architecture.
|
| 37 |
|
| 38 | Steps for introducing new architecture include:
|
| 39 | - optional: joining the #alpine-ports channel on oftc
|
| 40 | - adding the compiler triplet and arch type to abuild
|
| 41 | - adjusting build rules for packages that are arch aware:
|
| 42 | gcc, openssl, linux-headers, musl
|
| 43 | - create new kernel config for linux-lts
|
| 44 | - optionally reserve an architecture name in apk-tools
|
| 45 |
|
| 46 | After these steps the initial cross-build can be completed
|
| 47 | by running this with the target arch as parameter, e.g.:
|
| 48 | ./$program aarch64
|
| 49 |
|
| 50 | The cross-compiler generated by this script is not intended
|
| 51 | nor supported for any use other than building the base system
|
| 52 | and other packages in the bootstrap path.
|
| 53 |
|
| 54 | EOF
|
| 55 | return 1
|
| 56 | fi
|
| 57 |
|
| 58 | |
| 59 | sharedir=${ABUILD_SHAREDIR:-/usr/share/abuild}
|
| 60 | [ -e "$sharedir"/functions.sh ] || (echo "abuild not found" ; exit 1)
|
| 61 | . "$sharedir"/functions.sh
|
| 62 | [ -z "$CBUILD_ARCH" ] && die "abuild is too old (use 2.29.0 or later)"
|
| 63 | [ -z "$CBUILDROOT" ] && die "CBUILDROOT not set for $CTARGET_ARCH"
|
| 64 | export CBUILD CBUILD_ARCH CHOST CARCH CTARGET CTARGET_ARCH
|
| 65 |
|
| 66 | |
| 67 | [ -z "$APORTS" ] && APORTS=$(realpath $(dirname $0)/../)
|
| 68 | [ -e "$APORTS/main/build-base" ] || die "Unable to deduce aports base checkout"
|
| 69 |
|
| 70 | apkbuildname() {
|
| 71 | local repo="${1%%/*}"
|
| 72 | local pkg="${1##*/}"
|
| 73 | [ "$repo" = "$1" ] && repo="main"
|
| 74 | echo $APORTS/$repo/$pkg/APKBUILD
|
| 75 | }
|
| 76 |
|
| 77 | msg() {
|
| 78 | [ -n "$quiet" ] && return 0
|
| 79 | local prompt="$GREEN>>>${NORMAL}"
|
| 80 | local name="${BLUE}bootstrap-${CTARGET_ARCH}${NORMAL}"
|
| 81 | printf "${prompt} ${name}: %s\n" "$1" >&2
|
| 82 | }
|
| 83 |
|
| 84 | if [ ! -d "$CBUILDROOT" ]; then
|
| 85 | msg "Creating sysroot in $CBUILDROOT"
|
| 86 | mkdir -p "$CBUILDROOT/etc/apk/keys"
|
| 87 | |
| 88 | |
| 89 | |
| 90 | |
| 91 | |
| 92 | cp -a /etc/apk/keys/* "$CBUILDROOT/etc/apk/keys"
|
| 93 | cp -a ~/.abuild/*.pub "$CBUILDROOT/etc/apk/keys"
|
| 94 | if [ "$BOOTSTRAP_USR_MERGED" = "1" ]; then
|
| 95 | mkdir -p "$CBUILDROOT"/usr/lib "$CBUILDROOT"/usr/bin "$CBUILDROOT"/usr/sbin
|
| 96 | ln -s usr/bin usr/sbin usr/lib "$CBUILDROOT"/
|
| 97 | fi
|
| 98 | ${SUDO_APK} add --quiet --initdb --arch $CTARGET_ARCH --root $CBUILDROOT
|
| 99 | fi
|
| 100 |
|
| 101 | msg "Building cross-compiler"
|
| 102 |
|
| 103 | |
| 104 | BOOTSTRAP=nobase APKBUILD=$(apkbuildname binutils) abuild $abuild_opts
|
| 105 |
|
| 106 | if ! CHOST=$CTARGET CARCH=$CTARGET_ARCH BOOTSTRAP=nolibc APKBUILD=$(apkbuildname musl) abuild up2date 2>/dev/null; then
|
| 107 | |
| 108 | CHOST=$CTARGET CARCH=$CTARGET_ARCH BOOTSTRAP=nocc APKBUILD=$(apkbuildname musl) abuild $abuild_opts
|
| 109 |
|
| 110 | |
| 111 | EXTRADEPENDS_HOST="musl-dev" \
|
| 112 | BOOTSTRAP=nolibc APKBUILD=$(apkbuildname gcc) abuild $abuild_opts
|
| 113 |
|
| 114 | |
| 115 | EXTRADEPENDS_BUILD="gcc-pass2-$CTARGET_ARCH" \
|
| 116 | CHOST=$CTARGET CARCH=$CTARGET_ARCH BOOTSTRAP=nolibc APKBUILD=$(apkbuildname musl) abuild $abuild_opts
|
| 117 | fi
|
| 118 |
|
| 119 | |
| 120 | EXTRADEPENDS_BUILD="gcc-pass2-$CTARGET_ARCH" \
|
| 121 | EXTRADEPENDS_TARGET="musl-dev" \
|
| 122 | CHOST=$CTARGET CARCH=$CTARGET_ARCH BOOTSTRAP=nobase APKBUILD=$(apkbuildname libucontext) abuild $abuild_opts
|
| 123 |
|
| 124 | |
| 125 | EXTRADEPENDS_TARGET="musl-dev libucontext-dev" \
|
| 126 | BOOTSTRAP=nobase APKBUILD=$(apkbuildname gcc) abuild $abuild_opts
|
| 127 |
|
| 128 | |
| 129 | BOOTSTRAP=nobase APKBUILD=$(apkbuildname build-base) abuild $abuild_opts
|
| 130 |
|
| 131 | msg "Cross building base system"
|
| 132 |
|
| 133 | |
| 134 | export EXTRADEPENDS_TARGET="libgcc libstdc++ musl-dev"
|
| 135 |
|
| 136 | |
| 137 | |
| 138 | |
| 139 | |
| 140 | |
| 141 | |
| 142 | if [ "$CTARGET_ARCH" = "riscv64" ]; then
|
| 143 | NEEDS_LIBATOMIC="yes"
|
| 144 | fi
|
| 145 |
|
| 146 | if [ $# -eq 0 ]; then
|
| 147 | set -- fortify-headers linux-headers musl zlib pkgconf gmp mpfr4 \
|
| 148 | mpc1 isl26 libucontext zstd binutils gcc make file patch openssl \
|
| 149 | busybox build-base ca-certificates libmd bsd-compat-headers libbsd \
|
| 150 | apk-tools libcap openrc alpine-conf alpine-baselayout alpine-keys \
|
| 151 | alpine-base attr acl fakeroot tar pax-utils lzip abuild \
|
| 152 | $OPENSSH \
|
| 153 | $MKINITFS \
|
| 154 | $COMPILER_PKG \
|
| 155 | $KERNEL_PKG \
|
| 156 | $LUA_APORTS
|
| 157 | fi
|
| 158 |
|
| 159 | for PKG; do
|
| 160 | CHOST=$CTARGET CARCH=$CTARGET_ARCH BOOTSTRAP=bootimage APKBUILD=$(apkbuildname $PKG) abuild $abuild_opts
|
| 161 |
|
| 162 | case "$PKG" in
|
| 163 | fortify-headers)
|
| 164 | |
| 165 | EXTRADEPENDS_TARGET="$EXTRADEPENDS_TARGET $PKG"
|
| 166 | ;;
|
| 167 | gcc)
|
| 168 | if [ "$NEEDS_LIBATOMIC" = "yes" ]; then
|
| 169 | EXTRADEPENDS_TARGET="$EXTRADEPENDS_TARGET $PKG"
|
| 170 | fi
|
| 171 | ;;
|
| 172 | build-base)
|
| 173 | |
| 174 | EXTRADEPENDS_TARGET="busybox $PKG"
|
| 175 | ;;
|
| 176 | esac
|
| 177 | done
|