Rename caps_apply_to_all to caps_apply_to_type
[helenos.git] / tools / toolchain.sh
blob5ef5f964885692cf382c94e0ad83683e47ecf089
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 GMP_MAIN=<<EOF
32 #define GCC_GMP_VERSION_NUM(a, b, c) \
33 (((a) << 16L) | ((b) << 8) | (c))
35 #define GCC_GMP_VERSION \
36 GCC_GMP_VERSION_NUM(__GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL)
38 #if GCC_GMP_VERSION < GCC_GMP_VERSION_NUM(4, 3, 2)
39 choke me
40 #endif
41 EOF
43 MPFR_MAIN=<<EOF
44 #if MPFR_VERSION < MPFR_VERSION_NUM(2, 4, 2)
45 choke me
46 #endif
47 EOF
49 MPC_MAIN=<<EOF
50 #if MPC_VERSION < MPC_VERSION_NUM(0, 8, 1)
51 choke me
52 #endif
53 EOF
55 ISL_MAIN=<<EOF
56 isl_ctx_get_max_operations (isl_ctx_alloc ());
57 EOF
59 BINUTILS_VERSION="2.28"
60 BINUTILS_RELEASE=""
61 ## BINUTILS_PATCHES="toolchain-binutils-2.23.1.patch"
62 GCC_VERSION="7.1.0"
63 ## GCC_PATCHES="toolchain-gcc-4.8.1-targets.patch toolchain-gcc-4.8.1-headers.patch"
64 GDB_VERSION="7.12.1"
65 ## GDB_PATCHES="toolchain-gdb-7.6.1.patch"
67 BASEDIR="`pwd`"
68 SRCDIR="$(readlink -f $(dirname "$0"))"
69 BINUTILS="binutils-${BINUTILS_VERSION}${BINUTILS_RELEASE}.tar.bz2"
70 GCC="gcc-${GCC_VERSION}.tar.bz2"
71 GDB="gdb-${GDB_VERSION}.tar.gz"
73 REAL_INSTALL=true
74 USE_HELENOS_TARGET=false
75 INSTALL_DIR="${BASEDIR}/PKG"
78 # Check if the library described in the argument
79 # exists and has acceptable version.
81 check_dependency() {
82 DEPENDENCY="$1"
83 HEADER="$2"
84 BODY="$3"
86 FNAME="/tmp/conftest-$$"
88 echo "#include ${HEADER}" > "${FNAME}.c"
89 echo >> "${FNAME}.c"
90 echo "int main()" >> "${FNAME}.c"
91 echo "{" >> "${FNAME}.c"
92 echo "${BODY}" >> "${FNAME}.c"
93 echo " return 0;" >> "${FNAME}.c"
94 echo "}" >> "${FNAME}.c"
96 cc $CFLAGS -c -o "${FNAME}.o" "${FNAME}.c" 2> "${FNAME}.log"
97 RC="$?"
99 if [ "$RC" -ne "0" ] ; then
100 echo " ${DEPENDENCY} not found, too old or compiler error."
101 echo " Please recheck manually the source file \"${FNAME}.c\"."
102 echo " The compilation of the toolchain is probably going to fail,"
103 echo " you have been warned."
104 echo
105 echo " ===== Compiler output ====="
106 cat "${FNAME}.log"
107 echo " ==========================="
108 echo
109 else
110 echo " ${DEPENDENCY} found"
111 rm -f "${FNAME}.log" "${FNAME}.o" "${FNAME}.c"
115 check_dependecies() {
116 echo ">>> Basic dependency check"
117 check_dependency "GMP" "<gmp.h>" "${GMP_MAIN}"
118 check_dependency "MPFR" "<mpfr.h>" "${MPFR_MAIN}"
119 check_dependency "MPC" "<mpc.h>" "${MPC_MAIN}"
120 check_dependency "isl" "<isl/ctx.h>" "${ISL_MAIN}"
121 echo
124 check_error() {
125 if [ "$1" -ne "0" ] ; then
126 echo
127 echo "Script failed: $2"
129 exit 1
133 check_md5() {
134 FILE="$1"
135 SUM="$2"
137 COMPUTED="`md5sum "${FILE}" | cut -d' ' -f1`"
138 if [ "${SUM}" != "${COMPUTED}" ] ; then
139 echo
140 echo "Checksum of ${FILE} does not match."
142 exit 2
146 show_usage() {
147 echo "Cross-compiler toolchain build script"
148 echo
149 echo "Syntax:"
150 echo " $0 [--no-install] [--helenos-target] <platform>"
151 echo
152 echo "Possible target platforms are:"
153 echo " amd64 AMD64 (x86-64, x64)"
154 echo " arm32 ARM 32b"
155 echo " ia32 IA-32 (x86, i386)"
156 echo " ia64 IA-64 (Itanium)"
157 echo " mips32 MIPS little-endian 32b"
158 echo " mips32eb MIPS big-endian 32b"
159 echo " mips64 MIPS little-endian 64b"
160 echo " ppc32 PowerPC 32b"
161 echo " ppc64 PowerPC 64v"
162 echo " riscv64 RISC-V 64b"
163 echo " sparc64 SPARC V9"
164 echo " all build all targets"
165 echo " essential build only targets currently needed for HelenOS development"
166 echo " parallel same as 'all', but all in parallel"
167 echo " 2-way same as 'all', but 2-way parallel"
168 echo
169 echo "The toolchain is installed into directory specified by the"
170 echo "CROSS_PREFIX environment variable. If the variable is not"
171 echo "defined, /usr/local/cross/ is used as default."
172 echo
173 echo "If --no-install is present, the toolchain still uses the"
174 echo "CROSS_PREFIX as the target directory but the installation"
175 echo "copies the files into PKG/ subdirectory without affecting"
176 echo "the actual root file system. That is only useful if you do"
177 echo "not want to run the script under the super user."
178 echo
179 echo "The --helenos-target will build HelenOS-specific toolchain"
180 echo "(i.e. it will use *-helenos-* triplet instead of *-linux-*)."
181 echo "This toolchain is installed into /usr/local/cross-helenos by"
182 echo "default. The settings can be changed by setting environment"
183 echo "variable CROSS_HELENOS_PREFIX."
184 echo "Using the HelenOS-specific toolchain is still an experimental"
185 echo "feature that is not fully supported."
186 echo
188 exit 3
191 change_title() {
192 echo -en "\e]0;$1\a"
195 show_countdown() {
196 TM="$1"
198 if [ "${TM}" -eq 0 ] ; then
199 echo
200 return 0
203 echo -n "${TM} "
204 change_title "${TM}"
205 sleep 1
207 TM="`expr "${TM}" - 1`"
208 show_countdown "${TM}"
211 show_dependencies() {
212 echo "IMPORTANT NOTICE:"
213 echo
214 echo "For a successful compilation and use of the cross-compiler"
215 echo "toolchain you need at least the following dependencies."
216 echo
217 echo "Please make sure that the dependencies are present in your"
218 echo "system. Otherwise the compilation process might fail after"
219 echo "a few seconds or minutes."
220 echo
221 echo " - SED, AWK, Flex, Bison, gzip, bzip2, Bourne Shell"
222 echo " - gettext, zlib, Texinfo, libelf, libgomp"
223 echo " - GNU Make, Coreutils, Sharutils, tar"
224 echo " - GNU Multiple Precision Library (GMP)"
225 echo " - MPFR"
226 echo " - MPC"
227 echo " - integer point manipulation library (isl)"
228 echo " - native C and C++ compiler, assembler and linker"
229 echo " - native C and C++ standard library with headers"
230 echo
233 download_fetch() {
234 SOURCE="$1"
235 FILE="$2"
236 CHECKSUM="$3"
238 if [ ! -f "${FILE}" ] ; then
239 change_title "Downloading ${FILE}"
240 wget -c "${SOURCE}${FILE}"
241 check_error $? "Error downloading ${FILE}."
244 check_md5 "${FILE}" "${CHECKSUM}"
247 source_check() {
248 FILE="$1"
250 if [ ! -f "${FILE}" ] ; then
251 echo
252 echo "File ${FILE} not found."
254 exit 4
258 cleanup_dir() {
259 DIR="$1"
261 if [ -d "${DIR}" ] ; then
262 change_title "Removing ${DIR}"
263 echo " >>> Removing ${DIR}"
264 rm -fr "${DIR}"
268 create_dir() {
269 DIR="$1"
270 DESC="$2"
272 change_title "Creating ${DESC}"
273 echo ">>> Creating ${DESC}"
275 mkdir -p "${DIR}"
276 test -d "${DIR}"
277 check_error $? "Unable to create ${DIR}."
280 check_dirs() {
281 OUTSIDE="$1"
282 BASE="$2"
283 ORIGINAL="`pwd`"
285 cd "${OUTSIDE}"
286 check_error $? "Unable to change directory to ${OUTSIDE}."
287 ABS_OUTSIDE="`pwd`"
289 cd "${BASE}"
290 check_error $? "Unable to change directory to ${BASE}."
291 ABS_BASE="`pwd`"
293 cd "${ORIGINAL}"
294 check_error $? "Unable to change directory to ${ORIGINAL}."
296 BASE_LEN="${#ABS_BASE}"
297 OUTSIDE_TRIM="${ABS_OUTSIDE:0:${BASE_LEN}}"
299 if [ "${OUTSIDE_TRIM}" == "${ABS_BASE}" ] ; then
300 echo
301 echo "CROSS_PREFIX cannot reside within the working directory."
303 exit 5
307 unpack_tarball() {
308 FILE="$1"
309 DESC="$2"
311 change_title "Unpacking ${DESC}"
312 echo " >>> Unpacking ${DESC}"
314 case "${FILE}" in
315 *.gz)
316 tar -xzf "${FILE}"
318 *.xz)
319 tar -xJf "${FILE}"
321 *.bz2)
322 tar -xjf "${FILE}"
325 check_error 1 "Don't know how to unpack ${DESC}."
327 esac
328 check_error $? "Error unpacking ${DESC}."
331 patch_sources() {
332 PATCH_FILE="$1"
333 PATCH_STRIP="$2"
334 DESC="$3"
336 change_title "Patching ${DESC}"
337 echo " >>> Patching ${DESC} with ${PATCH_FILE}"
339 patch -t "-p${PATCH_STRIP}" <"$PATCH_FILE"
340 check_error $? "Error patching ${DESC}."
343 prepare() {
344 show_dependencies
345 check_dependecies
346 show_countdown 10
348 BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
349 GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
350 GDB_SOURCE="ftp://ftp.gnu.org/gnu/gdb/"
352 download_fetch "${BINUTILS_SOURCE}" "${BINUTILS}" "9e8340c96626b469a603c15c9d843727"
353 download_fetch "${GCC_SOURCE}" "${GCC}" "6bf56a2bca9dac9dbbf8e8d1036964a8"
354 download_fetch "${GDB_SOURCE}" "${GDB}" "06c8f40521ed65fe36ebc2be29b56942"
357 set_target_from_platform() {
358 case "$1" in
359 "amd64")
360 LINUX_TARGET="amd64-linux-gnu"
361 HELENOS_TARGET="amd64-helenos"
363 "arm32")
364 LINUX_TARGET="arm-linux-gnueabi"
365 HELENOS_TARGET="arm-helenos-gnueabi"
367 "ia32")
368 LINUX_TARGET="i686-pc-linux-gnu"
369 HELENOS_TARGET="i686-pc-helenos"
371 "ia64")
372 LINUX_TARGET="ia64-pc-linux-gnu"
373 HELENOS_TARGET="ia64-pc-helenos"
375 "mips32")
376 LINUX_TARGET="mipsel-linux-gnu"
377 HELENOS_TARGET="mipsel-helenos"
379 "mips32eb")
380 LINUX_TARGET="mips-linux-gnu"
381 HELENOS_TARGET="mips-helenos"
383 "mips64")
384 LINUX_TARGET="mips64el-linux-gnu"
385 HELENOS_TARGET="mips64el-helenos"
387 "ppc32")
388 LINUX_TARGET="ppc-linux-gnu"
389 HELENOS_TARGET="ppc-helenos"
391 "ppc64")
392 LINUX_TARGET="ppc64-linux-gnu"
393 HELENOS_TARGET="ppc64-helenos"
395 "riscv64")
396 LINUX_TARGET="riscv64-unknown-linux-gnu"
397 HELENOS_TARGET="riscv64-helenos"
399 "sparc64")
400 LINUX_TARGET="sparc64-linux-gnu"
401 HELENOS_TARGET="sparc64-helenos"
404 check_error 1 "No target known for $1."
406 esac
409 build_target() {
410 PLATFORM="$1"
412 # This sets the *_TARGET variables
413 set_target_from_platform "$PLATFORM"
414 if $USE_HELENOS_TARGET ; then
415 TARGET="$HELENOS_TARGET"
416 else
417 TARGET="$LINUX_TARGET"
420 WORKDIR="${BASEDIR}/${PLATFORM}"
421 BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
422 GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
423 OBJDIR="${WORKDIR}/gcc-obj"
424 GDBDIR="${WORKDIR}/gdb-${GDB_VERSION}"
426 if [ -z "${CROSS_PREFIX}" ] ; then
427 CROSS_PREFIX="/usr/local/cross"
429 if [ -z "${CROSS_HELENOS_PREFIX}" ] ; then
430 CROSS_HELENOS_PREFIX="/usr/local/cross-helenos"
433 if $USE_HELENOS_TARGET ; then
434 PREFIX="${CROSS_HELENOS_PREFIX}/${PLATFORM}"
435 else
436 PREFIX="${CROSS_PREFIX}/${PLATFORM}"
439 echo ">>> Downloading tarballs"
440 source_check "${BASEDIR}/${BINUTILS}"
441 source_check "${BASEDIR}/${GCC}"
442 source_check "${BASEDIR}/${GDB}"
444 echo ">>> Removing previous content"
445 $REAL_INSTALL && cleanup_dir "${PREFIX}"
446 cleanup_dir "${WORKDIR}"
448 $REAL_INSTALL && create_dir "${PREFIX}" "destination directory"
449 create_dir "${OBJDIR}" "GCC object directory"
451 check_dirs "${PREFIX}" "${WORKDIR}"
453 echo ">>> Unpacking tarballs"
454 cd "${WORKDIR}"
455 check_error $? "Change directory failed."
457 unpack_tarball "${BASEDIR}/${BINUTILS}" "binutils"
458 unpack_tarball "${BASEDIR}/${GCC}" "GCC"
459 unpack_tarball "${BASEDIR}/${GDB}" "GDB"
461 echo ">>> Applying patches"
462 for p in $BINUTILS_PATCHES ; do
463 patch_sources "${SRCDIR}/${p}" 0 "binutils"
464 done
465 for p in $GCC_PATCHES ; do
466 patch_sources "${SRCDIR}/${p}" 0 "GCC"
467 done
468 for p in $GDB_PATCHES ; do
469 patch_sources "${SRCDIR}/${p}" 0 "GDB"
470 done
472 echo ">>> Processing binutils (${PLATFORM})"
473 cd "${BINUTILSDIR}"
474 check_error $? "Change directory failed."
476 change_title "binutils: configure (${PLATFORM})"
477 CFLAGS=-Wno-error ./configure \
478 "--target=${TARGET}" \
479 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
480 --disable-nls --disable-werror
481 check_error $? "Error configuring binutils."
483 change_title "binutils: make (${PLATFORM})"
484 make all
485 check_error $? "Error compiling binutils."
487 change_title "binutils: install (${PLATFORM})"
488 if $REAL_INSTALL ; then
489 make install
490 else
491 make install "DESTDIR=${INSTALL_DIR}"
493 check_error $? "Error installing binutils."
496 echo ">>> Processing GCC (${PLATFORM})"
497 cd "${OBJDIR}"
498 check_error $? "Change directory failed."
500 change_title "GCC: configure (${PLATFORM})"
501 PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" "${GCCDIR}/configure" \
502 "--target=${TARGET}" \
503 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
504 --with-gnu-as --with-gnu-ld --disable-nls --disable-threads \
505 --enable-languages=c,objc,c++,obj-c++ \
506 --disable-multilib --disable-libgcj --without-headers \
507 --disable-shared --enable-lto --disable-werror
508 check_error $? "Error configuring GCC."
510 change_title "GCC: make (${PLATFORM})"
511 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-gcc
512 check_error $? "Error compiling GCC."
514 change_title "GCC: install (${PLATFORM})"
515 if $REAL_INSTALL ; then
516 PATH="${PATH}:${PREFIX}/bin" make install-gcc
517 else
518 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-gcc "DESTDIR=${INSTALL_DIR}"
520 check_error $? "Error installing GCC."
523 # No GDB support for RISC-V so far
524 if [ "$PLATFORM" != "riscv64" ] ; then
525 echo ">>> Processing GDB (${PLATFORM})"
526 cd "${GDBDIR}"
527 check_error $? "Change directory failed."
529 change_title "GDB: configure (${PLATFORM})"
530 PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" ./configure \
531 "--target=${TARGET}" \
532 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
533 --enable-werror=no
534 check_error $? "Error configuring GDB."
536 change_title "GDB: make (${PLATFORM})"
537 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all
538 check_error $? "Error compiling GDB."
540 change_title "GDB: make (${PLATFORM})"
541 if $REAL_INSTALL ; then
542 PATH="${PATH}:${PREFIX}/bin" make install
543 else
544 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install "DESTDIR=${INSTALL_DIR}"
546 check_error $? "Error installing GDB."
550 cd "${BASEDIR}"
551 check_error $? "Change directory failed."
553 echo ">>> Cleaning up"
554 cleanup_dir "${WORKDIR}"
556 echo
557 echo ">>> Cross-compiler for ${TARGET} installed."
560 while [ "$#" -gt 1 ] ; do
561 case "$1" in
562 --no-install)
563 REAL_INSTALL=false
564 shift
566 --helenos-target)
567 USE_HELENOS_TARGET=true
568 shift
571 show_usage
573 esac
574 done
576 if [ "$#" -lt "1" ] ; then
577 show_usage
580 case "$1" in
581 amd64|arm32|ia32|ia64|mips32|mips32eb|mips64|ppc32|ppc64|riscv64|sparc64)
582 prepare
583 build_target "$1"
585 "all")
586 prepare
587 build_target "amd64"
588 build_target "arm32"
589 build_target "ia32"
590 build_target "ia64"
591 build_target "mips32"
592 build_target "mips32eb"
593 build_target "mips64"
594 build_target "ppc32"
595 build_target "ppc64"
596 build_target "riscv64"
597 build_target "sparc64"
599 "essential")
600 prepare
601 build_target "amd64"
602 build_target "arm32"
603 build_target "ia32"
604 build_target "ia64"
605 build_target "mips32"
606 build_target "mips32eb"
607 build_target "ppc32"
608 build_target "sparc64"
610 "parallel")
611 prepare
612 build_target "amd64" &
613 build_target "arm32" &
614 build_target "ia32" &
615 build_target "ia64" &
616 build_target "mips32" &
617 build_target "mips32eb" &
618 build_target "mips64" &
619 build_target "ppc32" &
620 build_target "ppc64" &
621 build_target "riscv64" &
622 build_target "sparc64" &
623 wait
625 "2-way")
626 prepare
627 build_target "amd64" &
628 build_target "arm32" &
629 wait
631 build_target "ia32" &
632 build_target "ia64" &
633 wait
635 build_target "mips32" &
636 build_target "mips32eb" &
637 wait
639 build_target "mips64" &
640 build_target "ppc32" &
641 wait
643 build_target "riscv64" &
644 build_target "ppc64" &
645 wait
647 build_target "sparc64" &
648 wait
651 show_usage
653 esac