summaryrefslogtreecommitdiff
path: root/scripts/bootstrap.sh
blob: 78f8ac7ff7842c78b7b87fc91ccbd977694f5932 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#!/bin/sh -e

set -x

HERE="$(dirname $(readlink -f ${0}))";

##
# mcmtools provides almost everything needed to build 'abuild',
# and it is a hard dependency for our bootstrap process now.
#
#     https://git.zv.io/toolchains/bootstrap
#
# It is possible to bootstrap from a non- Alpine/Adélie system.
# We will build 'abuild' and other utilities momentarily.
#
MCMTOOLS=${MCMTOOLS:-"$HOME/mcmtools"}
test ! -d "${MCMTOOLS}/sys/bin" && printf "Environment 'MCMTOOLS=%s' is not valid.\n" "${MCMTOOLS}" && exit 1;


##
# TARGET_ARCH (argv[1]) is used during cross-compilation.
#
TARGET_ARCH="$1"
test ! -n "${TARGET_ARCH}" && printf "Invoking '%s TARGET_ARCH' where 'TARGET_ARCH=%s' is not valid.\n" "${0}" "${TARGET_ARCH}" && exit 1;


##
# Build 'abuild', its dependencies, and other utilities.
# Once finished, add them to PATH.
#
"${HERE}/setup-abuild" ${TARGET_ARCH};
export PATH="${MCMTOOLS}/abuild/bin:${PATH}";
#bash;
#exit;

##
# Additional configuration.
#
export PACKAGER="Zach van Rijn <me@zv.io>";
export CBUILD=${TARGET_ARCH};
export CBUILDROOT="${MCMTOOLS}/abuild/${TARGET_ARCH}";
export ABUILD_USERDIR="${CBUILDROOT}.conf";
export SRCDEST="${MCMTOOLS}/abuild/src";
export REPODEST="${MCMTOOLS}/abuild/apk";
export ABUILD_APK_INDEX_OPTS="--allow-untrusted"; # FIXME
#export BUILD_ROOT="${CBUILDROOT}";

SUDO_APK=abuild-apk

# get abuild configurables
[ -e "${MCMTOOLS}/abuild/share/abuild/functions.sh" ] || (echo "abuild not found" ; exit 1)
CBUILDROOT="$(CTARGET=$TARGET_ARCH . ${MCMTOOLS}/abuild/share/abuild/functions.sh ; echo $CBUILDROOT)"
. "${MCMTOOLS}/abuild/share/abuild/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"

# deduce aports directory
[ -z "$APORTS" ] && APORTS=$(realpath $(dirname $0)/../)
[ -e "$APORTS/system/build-tools" ] || die "Unable to deduce packages directory"

apkbuildname() {
	local repo="${1%%/*}"
	local pkg="${1##*/}"
	[ "$repo" = "$1" ] && repo="system"
	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 [ -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 Adélie Linux base system for new architecture.

Steps for introducing new architecture include:
- adding the compiler tripler and arch type to abuild
- adding the arch type detection to apk-tools
- adjusting build rules for packages that are arch aware:
  gcc, musl, binutils, easy-kernel
- create new kernel config for easy-kernel

After these steps the initial cross-build can be completed
by running this with the target arch as parameter, e.g.:
	./$program aarch64

EOF
	return 1
fi


##
# Package signing keys. Public and Private keys are stored in a
# different location; variables for which are installed to arch-
# specific 'abuild.conf' file.
#
if [ ! -d "$CBUILDROOT/etc/apk/keys" ] || [ -n "$(find $CBUILDROOT -type f -name '*.rsa')" ]; then
	msg "Creating sysroot in $CBUILDROOT"
	mkdir -p "$CBUILDROOT/etc/apk/keys"
    abuild-keygen -an;
    p=$(find "${ABUILD_USERDIR}" -type f -name "*.rsa.pub");
    mv "${p}" "$CBUILDROOT/etc/apk/keys";
    grep 1>/dev/null PACKAGER_PUBKEY= "${ABUILD_USERDIR}/abuild.conf" || printf >> "${ABUILD_USERDIR}/abuild.conf" "PACKAGER_PUBKEY=\"%s\"\n" "$CBUILDROOT/etc/apk/keys/${p##*/}";
fi


##
# APK database.
#
if [ ! -f "${CBUILDROOT}/._database-${TARGET_ARCH}" ]; then
    mkdir -p "${CBUILDROOT}/var/log"; # why not created by default?
    ${SUDO_APK} add --quiet --initdb --arch $TARGET_ARCH --root $CBUILDROOT
    touch "${CBUILDROOT}/._database-${TARGET_ARCH}";
fi

msg "Building cross-compiler"

# Build and install cross binutils (--with-sysroot)
CTARGET=$TARGET_ARCH BOOTSTRAP=nobase APKBUILD=$(apkbuildname binutils) abuild -r
exit
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 -r

	# Minimal cross GCC
	EXTRADEPENDS_HOST="musl-dev" \
	CTARGET=$TARGET_ARCH BOOTSTRAP=nolibc APKBUILD=$(apkbuildname gcc) abuild -r

	# Cross build bootstrap C-library for the target
	EXTRADEPENDS_BUILD="gcc-pass2-$TARGET_ARCH" \
	CHOST=$TARGET_ARCH BOOTSTRAP=nolibc APKBUILD=$(apkbuildname musl) abuild -r
fi

# Full cross GCC
EXTRADEPENDS_TARGET="musl musl-dev" \
CTARGET=$TARGET_ARCH BOOTSTRAP=nobase APKBUILD=$(apkbuildname gcc) abuild -r

# Cross build-base
CTARGET=$TARGET_ARCH BOOTSTRAP=nobase APKBUILD=$(apkbuildname build-base) abuild -r

msg "Cross building base system"
msg "Change your abuild.conf NOW to avoid build errors!!"
read

# add implicit target prerequisite packages
apk info --quiet --installed --root "$CBUILDROOT" libgcc libstdc++ musl-dev || \
	${SUDO_APK} --root "$CBUILDROOT" add --repository "$REPODEST/system" libgcc libstdc++ musl-dev

# ordered cross-build
for PKG in musl pkgconf zlib \
	   gettext-tiny ncurses bash binutils make bison flex m4 \
	   openssl apk-tools linux-pam shadow \
	   gmp mpfr3 mpc1 isl gcc ca-certificates \
	   openrc libcap-ng coreutils sed gzip bzip2 diffutils \
	   attr libcap patch sudo acl fakeroot libarchive mawk \
	   pax-utils abuild grep findutils patch lzip unzip autoconf automake libtool \
	   ncurses util-linux lvm2 popt xz lddtree libssh2 curl build-tools pcre \
	   debianutils file shimmy procps zsh sharutils net-tools check kbd sysklogd vim db groff libpipeline man-db psmisc less \
	   adelie-base \
	    ; do

	CHOST=$TARGET_ARCH BOOTSTRAP=bootimage APKBUILD=$(apkbuildname $PKG) abuild -r

	case "$PKG" in
	fortify-headers | libc-dev | build-base)
		# headers packages which are implicit but mandatory dependency
		apk info --quiet --installed --root "$CBUILDROOT" $PKG || \
			${SUDO_APK} --update --root "$CBUILDROOT" --repository "$REPODEST/system" add $PKG
		;;
	musl | gcc)
		# target libraries rebuilt, force upgrade
		[ "$(apk upgrade --root "$CBUILDROOT" --repository "$REPODEST/main" --available --simulate | wc -l)" -gt 1 ] &&
			${SUDO_APK} upgrade --root "$CBUILDROOT" --repository "$REPODEST/main" --available
		;;
	esac
done