1#!/bin/bash
2
3set -o errexit
4set -o pipefail
5set -o xtrace
6
7ARCH="$1"
8PHASE="$2"
9
10JOBS="$(getconf _NPROCESSORS_ONLN)"
11
12case "$ARCH" in
13x86_64)
14        SYSROOT_MACH='i386'
15        ;;
16*)
17        printf 'ERROR: unknown architecture: %s\n' "$ARCH"
18        exit 1
19esac
20
21BUILD_TARGET="$ARCH-pc-solaris2.10"
22
23#
24# The illumos and the Solaris build both use the same GCC-level host triple,
25# though different versions of GCC are used and with different configure
26# options.  To ensure as little accidental cross-pollination as possible, we
27# build the illumos toolchain in a specific directory tree and just symlink the
28# expected tools into /usr/local/bin at the end.  We omit /usr/local/bin from
29# PATH here for similar reasons.
30#
31PREFIX="/opt/illumos/$ARCH"
32export PATH="$PREFIX/bin:/usr/bin:/bin:/usr/sbin:/sbin"
33
34#
35# NOTE: The compiler version selected here is more specific than might appear.
36# GCC 7.X releases do not appear to cross-compile correctly for Solaris
37# targets, at least insofar as they refuse to enable TLS in libstdc++.  When
38# changing the GCC version in future, one must carefully verify that TLS is
39# enabled in all of the static libraries we intend to include in output
40# binaries.
41#
42GCC_VERSION='8.4.0'
43GCC_SUM='e30a6e52d10e1f27ed55104ad233c30bd1e99cfb5ff98ab022dc941edd1b2dd4'
44GCC_BASE="gcc-$GCC_VERSION"
45GCC_TAR="gcc-$GCC_VERSION.tar.xz"
46GCC_URL="https://ftp.gnu.org/gnu/gcc/$GCC_BASE/$GCC_TAR"
47
48SYSROOT_VER='20181213-de6af22ae73b-v1'
49SYSROOT_SUM='ee792d956dfa6967453cebe9286a149143290d296a8ce4b8a91d36bea89f8112'
50SYSROOT_TAR="illumos-sysroot-$SYSROOT_MACH-$SYSROOT_VER.tar.gz"
51SYSROOT_URL='https://github.com/illumos/sysroot/releases/download/'
52SYSROOT_URL+="$SYSROOT_VER/$SYSROOT_TAR"
53SYSROOT_DIR="$PREFIX/sysroot"
54
55BINUTILS_VERSION='2.25.1'
56BINUTILS_SUM='b5b14added7d78a8d1ca70b5cb75fef57ce2197264f4f5835326b0df22ac9f22'
57BINUTILS_BASE="binutils-$BINUTILS_VERSION"
58BINUTILS_TAR="$BINUTILS_BASE.tar.bz2"
59BINUTILS_URL="https://ftp.gnu.org/gnu/binutils/$BINUTILS_TAR"
60
61
62download_file() {
63        local file="$1"
64        local url="$2"
65        local sum="$3"
66
67        while :; do
68                if [[ -f "$file" ]]; then
69                        if ! h="$(sha256sum "$file" | awk '{ print $1 }')"; then
70                                printf 'ERROR: reading hash\n' >&2
71                                exit 1
72                        fi
73
74                        if [[ "$h" == "$sum" ]]; then
75                                return 0
76                        fi
77
78                        printf 'WARNING: hash mismatch: %s != expected %s\n' \
79                            "$h" "$sum" >&2
80                        rm -f "$file"
81                fi
82
83                printf 'Downloading: %s\n' "$url"
84                if ! curl -f -L -o "$file" "$url"; then
85                        rm -f "$file"
86                        sleep 1
87                fi
88        done
89}
90
91
92case "$PHASE" in
93sysroot)
94        download_file "/tmp/$SYSROOT_TAR" "$SYSROOT_URL" "$SYSROOT_SUM"
95        mkdir -p "$SYSROOT_DIR"
96        cd "$SYSROOT_DIR"
97        tar -xzf "/tmp/$SYSROOT_TAR"
98        rm -f "/tmp/$SYSROOT_TAR"
99        ;;
100
101binutils)
102        download_file "/tmp/$BINUTILS_TAR" "$BINUTILS_URL" "$BINUTILS_SUM"
103        mkdir -p /ws/src/binutils
104        cd /ws/src/binutils
105        tar -xjf "/tmp/$BINUTILS_TAR"
106        rm -f "/tmp/$BINUTILS_TAR"
107
108        mkdir -p /ws/build/binutils
109        cd /ws/build/binutils
110        "/ws/src/binutils/$BINUTILS_BASE/configure" \
111            --prefix="$PREFIX" \
112            --target="$BUILD_TARGET" \
113            --program-prefix="$ARCH-illumos-" \
114            --with-sysroot="$SYSROOT_DIR"
115
116        make -j "$JOBS"
117
118        mkdir -p "$PREFIX"
119        make install
120
121        cd /
122        rm -rf /ws/src/binutils /ws/build/binutils
123        ;;
124
125gcc)
126        download_file "/tmp/$GCC_TAR" "$GCC_URL" "$GCC_SUM"
127        mkdir -p /ws/src/gcc
128        cd /ws/src/gcc
129        tar -xJf "/tmp/$GCC_TAR"
130        rm -f "/tmp/$GCC_TAR"
131
132        mkdir -p /ws/build/gcc
133        cd /ws/build/gcc
134        export CFLAGS='-fPIC'
135        export CXXFLAGS='-fPIC'
136        export CXXFLAGS_FOR_TARGET='-fPIC'
137        export CFLAGS_FOR_TARGET='-fPIC'
138        "/ws/src/gcc/$GCC_BASE/configure" \
139            --prefix="$PREFIX" \
140            --target="$BUILD_TARGET" \
141            --program-prefix="$ARCH-illumos-" \
142            --with-sysroot="$SYSROOT_DIR" \
143            --with-gnu-as \
144            --with-gnu-ld \
145            --disable-nls \
146            --disable-libgomp \
147            --disable-libquadmath \
148            --disable-libssp \
149            --disable-libvtv \
150            --disable-libcilkrts \
151            --disable-libada \
152            --disable-libsanitizer \
153            --disable-libquadmath-support \
154            --disable-shared \
155            --enable-tls
156
157        make -j "$JOBS"
158
159        mkdir -p "$PREFIX"
160        make install
161
162        #
163        # Link toolchain commands into /usr/local/bin so that cmake and others
164        # can find them:
165        #
166        (cd "$PREFIX/bin" && ls -U) | grep "^$ARCH-illumos-" |
167            xargs -t -I% ln -s "$PREFIX/bin/%" '/usr/local/bin/'
168
169        cd /
170        rm -rf /ws/src/gcc /ws/build/gcc
171        ;;
172
173*)
174        printf 'ERROR: unknown phase "%s"\n' "$PHASE" >&2
175        exit 100
176        ;;
177esac
178