Merge pull request #144 from maurizio-lombardi/sysinst_fix
[helenos.git] / tools / toolchain.sh
bloba55effaa811fb2a6beb9ad0646d907d89842f9da
1 #! /bin/bash
4 # Copyright (c) 2009 Martin Decky
5 # All rights reserved.
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
11 # - Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
13 # - Redistributions in binary form must reproduce the above copyright
14 # notice, this list of conditions and the following disclaimer in the
15 # documentation and/or other materials provided with the distribution.
16 # - The name of the author may not be used to endorse or promote products
17 # derived from this software without specific prior written permission.
19 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 BINUTILS_GDB_GIT="https://github.com/HelenOS/binutils-gdb.git"
33 BINUTILS_BRANCH="binutils-2_31_1-helenos"
34 BINUTILS_VERSION="2.31.1"
36 GDB_BRANCH="gdb-8_2-helenos"
37 GDB_VERSION="8.2"
39 GCC_GIT="https://github.com/HelenOS/gcc.git"
40 GCC_BRANCH="8_2_0-helenos"
41 GCC_VERSION="8.2.0"
43 BASEDIR="`pwd`"
44 SRCDIR="$(readlink -f $(dirname "$0"))"
46 REAL_INSTALL=true
47 USE_HELENOS_TARGET=true
49 check_error() {
50 if [ "$1" -ne "0" ] ; then
51 echo
52 echo "Script failed: $2"
54 exit 1
58 show_usage() {
59 echo "Cross-compiler toolchain build script"
60 echo
61 echo "Syntax:"
62 echo " $0 [--no-install] [--non-helenos-target] <platform>"
63 echo
64 echo "Possible target platforms are:"
65 echo " amd64 AMD64 (x86-64, x64)"
66 echo " arm32 ARM 32b"
67 echo " ia32 IA-32 (x86, i386)"
68 echo " ia64 IA-64 (Itanium)"
69 echo " mips32 MIPS little-endian 32b"
70 echo " mips32eb MIPS big-endian 32b"
71 echo " ppc32 PowerPC 32b"
72 echo " riscv64 RISC-V 64b"
73 echo " sparc64 SPARC V9"
74 echo " all build all targets"
75 echo " essential build only targets currently needed for HelenOS development"
76 echo " parallel same as 'all', but all in parallel"
77 echo " 2-way same as 'all', but 2-way parallel"
78 echo
79 echo "The toolchain is installed into directory specified by the"
80 echo "CROSS_PREFIX environment variable. If the variable is not"
81 echo "defined, /usr/local/cross/ is used as default."
82 echo
83 echo "If --no-install is present, the toolchain still uses the"
84 echo "CROSS_PREFIX as the target directory but the installation"
85 echo "copies the files into PKG/ subdirectory without affecting"
86 echo "the actual root file system. That is only useful if you do"
87 echo "not want to run the script under the super user."
88 echo
89 echo "The --non-helenos-target will build non-HelenOS-specific toolchain"
90 echo "(i.e. it will use *-linux-* triplet instead of *-helenos)."
91 echo "Using this toolchain for building HelenOS is not supported."
92 echo
94 exit 3
97 change_title() {
98 echo -en "\e]0;$1\a"
101 show_countdown() {
102 TM="$1"
104 if [ "${TM}" -eq 0 ] ; then
105 echo
106 return 0
109 echo -n "${TM} "
110 change_title "${TM}"
111 sleep 1
113 TM="`expr "${TM}" - 1`"
114 show_countdown "${TM}"
117 show_dependencies() {
118 echo "IMPORTANT NOTICE:"
119 echo
120 echo "For a successful compilation and use of the cross-compiler"
121 echo "toolchain you need at least the following dependencies."
122 echo
123 echo "Please make sure that the dependencies are present in your"
124 echo "system. Otherwise the compilation process might fail after"
125 echo "a few seconds or minutes."
126 echo
127 echo " - SED, AWK, Flex, Bison, gzip, bzip2, Bourne Shell"
128 echo " - gettext, zlib, Texinfo, libelf, libgomp"
129 echo " - GNU Make, Coreutils, Sharutils, tar"
130 echo " - native C and C++ compiler, assembler and linker"
131 echo " - native C and C++ standard library with headers"
132 echo
135 cleanup_dir() {
136 DIR="$1"
138 if [ -d "${DIR}" ] ; then
139 change_title "Removing ${DIR}"
140 echo " >>> Removing ${DIR}"
141 rm -fr "${DIR}"
145 create_dir() {
146 DIR="$1"
147 DESC="$2"
149 change_title "Creating ${DESC}"
150 echo ">>> Creating ${DESC}"
152 mkdir -p "${DIR}"
153 test -d "${DIR}"
154 check_error $? "Unable to create ${DIR}."
157 check_dirs() {
158 OUTSIDE="$1"
159 BASE="$2"
160 ORIGINAL="`pwd`"
162 mkdir -p "${OUTSIDE}"
164 cd "${OUTSIDE}"
165 check_error $? "Unable to change directory to ${OUTSIDE}."
166 ABS_OUTSIDE="`pwd`"
168 cd "${BASE}"
169 check_error $? "Unable to change directory to ${BASE}."
170 ABS_BASE="`pwd`"
172 cd "${ORIGINAL}"
173 check_error $? "Unable to change directory to ${ORIGINAL}."
175 BASE_LEN="${#ABS_BASE}"
176 OUTSIDE_TRIM="${ABS_OUTSIDE:0:${BASE_LEN}}"
178 if [ "${OUTSIDE_TRIM}" == "${ABS_BASE}" ] ; then
179 echo
180 echo "CROSS_PREFIX cannot reside within the working directory."
182 exit 5
186 prepare() {
187 show_dependencies
188 show_countdown 10
190 mkdir -p "${BASEDIR}/downloads"
191 cd "${BASEDIR}/downloads"
192 check_error $? "Change directory failed."
194 echo ">>> Downloading sources"
195 git clone --depth 1 -b "$BINUTILS_BRANCH" "$BINUTILS_GDB_GIT" "binutils-$BINUTILS_VERSION"
196 git clone --depth 1 -b "$GDB_BRANCH" "$BINUTILS_GDB_GIT" "gdb-$GDB_VERSION"
197 git clone --depth 1 -b "$GCC_BRANCH" "$GCC_GIT" "gcc-$GCC_VERSION"
199 # If the directory already existed, pull upstream changes.
200 git -C "binutils-$BINUTILS_VERSION" pull
201 git -C "gdb-$GDB_VERSION" pull
202 git -C "gcc-$GCC_VERSION" pull
204 echo ">>> Downloading GCC prerequisites"
205 cd "gcc-${GCC_VERSION}"
206 ./contrib/download_prerequisites
207 cd ..
210 set_target_from_platform() {
211 case "$1" in
212 "arm32")
213 GNU_ARCH="arm"
215 "ia32")
216 GNU_ARCH="i686"
218 "mips32")
219 GNU_ARCH="mipsel"
221 "mips32eb")
222 GNU_ARCH="mips"
224 "ppc32")
225 GNU_ARCH="ppc"
228 GNU_ARCH="$1"
230 esac
232 HELENOS_TARGET="${GNU_ARCH}-helenos"
234 case "$1" in
235 "arm32")
236 LINUX_TARGET="${GNU_ARCH}-linux-gnueabi"
239 LINUX_TARGET="${GNU_ARCH}-linux-gnu"
241 esac
244 build_target() {
245 PLATFORM="$1"
247 # This sets the *_TARGET variables
248 set_target_from_platform "$PLATFORM"
249 if $USE_HELENOS_TARGET ; then
250 TARGET="$HELENOS_TARGET"
251 else
252 TARGET="$LINUX_TARGET"
255 WORKDIR="${BASEDIR}/${TARGET}"
256 INSTALL_DIR="${BASEDIR}/PKG"
257 BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
258 GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
259 GDBDIR="${WORKDIR}/gdb-${GDB_VERSION}"
261 if [ -z "${CROSS_PREFIX}" ] ; then
262 CROSS_PREFIX="/usr/local/cross"
265 if [ -z "$JOBS" ] ; then
266 JOBS=`nproc`
269 PREFIX="${CROSS_PREFIX}"
271 echo ">>> Removing previous content"
272 cleanup_dir "${WORKDIR}"
273 mkdir -p "${WORKDIR}"
274 check_dirs "${PREFIX}" "${WORKDIR}"
276 if $USE_HELENOS_TARGET ; then
277 echo ">>> Creating build sysroot"
278 mkdir -p "${WORKDIR}/sysroot/include"
279 mkdir "${WORKDIR}/sysroot/lib"
280 cp -r -L -t "${WORKDIR}/sysroot/include" \
281 ${SRCDIR}/../abi/include/* \
282 ${SRCDIR}/../uspace/lib/c/arch/${PLATFORM}/include/* \
283 ${SRCDIR}/../uspace/lib/c/include/*
284 check_error $? "Failed to create build sysroot."
287 echo ">>> Processing binutils (${PLATFORM})"
288 mkdir -p "${BINUTILSDIR}"
289 cd "${BINUTILSDIR}"
290 check_error $? "Change directory failed."
292 change_title "binutils: configure (${PLATFORM})"
293 CFLAGS=-Wno-error "${BASEDIR}/downloads/binutils-${BINUTILS_VERSION}/configure" \
294 "--target=${TARGET}" \
295 "--prefix=${PREFIX}" \
296 "--program-prefix=${TARGET}-" \
297 --disable-nls \
298 --disable-werror \
299 --enable-gold \
300 --enable-deterministic-archives \
301 --disable-gdb \
302 --with-sysroot
303 check_error $? "Error configuring binutils."
305 change_title "binutils: make (${PLATFORM})"
306 make all -j$JOBS
307 check_error $? "Error compiling binutils."
309 change_title "binutils: install (${PLATFORM})"
310 make install "DESTDIR=${INSTALL_DIR}"
311 check_error $? "Error installing binutils."
314 echo ">>> Processing GCC (${PLATFORM})"
315 mkdir -p "${GCCDIR}"
316 cd "${GCCDIR}"
317 check_error $? "Change directory failed."
319 if $USE_HELENOS_TARGET ; then
320 SYSROOT=--with-sysroot --with-build-sysroot="${WORKDIR}/sysroot"
321 else
322 SYSROOT=--without-headers
325 change_title "GCC: configure (${PLATFORM})"
326 PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" "${BASEDIR}/downloads/gcc-${GCC_VERSION}/configure" \
327 "--target=${TARGET}" \
328 "--prefix=${PREFIX}" \
329 "--program-prefix=${TARGET}-" \
330 --with-gnu-as \
331 --with-gnu-ld \
332 --disable-nls \
333 --enable-languages=c,c++,go \
334 --enable-lto \
335 --disable-shared \
336 --disable-werror \
337 $SYSROOT
338 check_error $? "Error configuring GCC."
340 change_title "GCC: make (${PLATFORM})"
341 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-gcc -j$JOBS
342 check_error $? "Error compiling GCC."
344 if $USE_HELENOS_TARGET ; then
345 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-target-libgcc -j$JOBS
346 check_error $? "Error compiling libgcc."
347 # TODO: needs some extra care
348 #PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-target-libatomic -j$JOBS
349 #check_error $? "Error compiling libatomic."
350 #PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-target-libstdc++-v3 -j$JOBS
351 #check_error $? "Error compiling libstdc++."
354 change_title "GCC: install (${PLATFORM})"
355 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-gcc "DESTDIR=${INSTALL_DIR}"
356 if $USE_HELENOS_TARGET ; then
357 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-target-libgcc "DESTDIR=${INSTALL_DIR}"
358 #PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-target-libatomic "DESTDIR=${INSTALL_DIR}"
359 #PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-target-libstdc++-v3 "DESTDIR=${INSTALL_DIR}"
361 check_error $? "Error installing GCC."
364 echo ">>> Processing GDB (${PLATFORM})"
365 mkdir -p "${GDBDIR}"
366 cd "${GDBDIR}"
367 check_error $? "Change directory failed."
369 change_title "GDB: configure (${PLATFORM})"
370 PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" "${BASEDIR}/downloads/gdb-${GDB_VERSION}/configure" \
371 "--target=${TARGET}" \
372 "--prefix=${PREFIX}" \
373 "--program-prefix=${TARGET}-" \
374 --enable-werror=no
375 check_error $? "Error configuring GDB."
377 change_title "GDB: make (${PLATFORM})"
378 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-gdb -j$JOBS
379 check_error $? "Error compiling GDB."
381 change_title "GDB: make (${PLATFORM})"
382 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-gdb "DESTDIR=${INSTALL_DIR}"
383 check_error $? "Error installing GDB."
385 # Symlink clang and lld to the install path.
386 CLANG="`which clang 2> /dev/null || echo "/usr/bin/clang"`"
387 LLD="`which ld.lld 2> /dev/null || echo "/usr/bin/ld.lld"`"
389 ln -s $CLANG "${INSTALL_DIR}/${PREFIX}/bin/${TARGET}-clang"
390 ln -s $LLD "${INSTALL_DIR}/${PREFIX}/bin/${TARGET}-ld.lld"
392 if $REAL_INSTALL ; then
393 echo ">>> Moving to the destination directory."
394 echo cp -r -t "${PREFIX}" "${INSTALL_DIR}/${PREFIX}/"*
395 cp -r -t "${PREFIX}" "${INSTALL_DIR}/${PREFIX}/"*
398 cd "${BASEDIR}"
399 check_error $? "Change directory failed."
401 echo ">>> Cleaning up"
402 cleanup_dir "${WORKDIR}"
404 echo
405 echo ">>> Cross-compiler for ${TARGET} installed."
408 while [ "$#" -gt 1 ] ; do
409 case "$1" in
410 --no-install)
411 REAL_INSTALL=false
412 shift
414 --non-helenos-target)
415 USE_HELENOS_TARGET=false
416 shift
419 show_usage
421 esac
422 done
424 if [ "$#" -lt "1" ] ; then
425 show_usage
428 case "$1" in
429 amd64|arm32|ia32|ia64|mips32|mips32eb|ppc32|riscv64|sparc64)
430 prepare
431 build_target "$1"
433 "all")
434 prepare
435 build_target "amd64"
436 build_target "arm32"
437 build_target "ia32"
438 build_target "ia64"
439 build_target "mips32"
440 build_target "mips32eb"
441 build_target "ppc32"
442 build_target "riscv64"
443 build_target "sparc64"
445 "essential")
446 prepare
447 build_target "amd64"
448 build_target "arm32"
449 build_target "ia32"
450 build_target "ia64"
451 build_target "mips32"
452 build_target "mips32eb"
453 build_target "ppc32"
454 build_target "sparc64"
456 "parallel")
457 prepare
458 build_target "amd64" &
459 build_target "arm32" &
460 build_target "ia32" &
461 build_target "ia64" &
462 build_target "mips32" &
463 build_target "mips32eb" &
464 build_target "ppc32" &
465 build_target "riscv64" &
466 build_target "sparc64" &
467 wait
469 "2-way")
470 prepare
471 build_target "amd64" &
472 build_target "arm32" &
473 wait
475 build_target "ia32" &
476 build_target "ia64" &
477 wait
479 build_target "mips32" &
480 build_target "mips32eb" &
481 wait
483 build_target "ppc32" &
484 build_target "riscv64" &
485 wait
487 build_target "sparc64" &
488 wait
491 show_usage
493 esac