Mark HelenOS-specific toolchain as experimental
[helenos.git] / tools / toolchain.sh
blobe8bd611e7b2997a95206ce9937a6e80927dd7c67
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 BINUTILS_VERSION="2.23.1"
56 BINUTILS_RELEASE=""
57 BINUTILS_PATCHES="toolchain-binutils-2.23.1.patch"
58 GCC_VERSION="4.8.1"
59 GCC_PATCHES="toolchain-gcc-4.8.1-targets.patch toolchain-gcc-4.8.1-headers.patch"
60 GDB_VERSION="7.6.1"
61 GDB_PATCHES="toolchain-gdb-7.6.patch"
63 BASEDIR="`pwd`"
64 BINUTILS="binutils-${BINUTILS_VERSION}${BINUTILS_RELEASE}.tar.bz2"
65 GCC="gcc-${GCC_VERSION}.tar.bz2"
66 GDB="gdb-${GDB_VERSION}.tar.bz2"
68 REAL_INSTALL=true
69 USE_HELENOS_TARGET=false
70 INSTALL_DIR="${BASEDIR}/PKG"
73 # Check if the library described in the argument
74 # exists and has acceptable version.
76 check_dependency() {
77 DEPENDENCY="$1"
78 HEADER="$2"
79 BODY="$3"
81 FNAME="/tmp/conftest-$$"
83 echo "#include ${HEADER}" > "${FNAME}.c"
84 echo >> "${FNAME}.c"
85 echo "int main()" >> "${FNAME}.c"
86 echo "{" >> "${FNAME}.c"
87 echo "${BODY}" >> "${FNAME}.c"
88 echo " return 0;" >> "${FNAME}.c"
89 echo "}" >> "${FNAME}.c"
91 cc -c -o "${FNAME}.o" "${FNAME}.c" 2> "${FNAME}.log"
92 RC="$?"
94 if [ "$RC" -ne "0" ] ; then
95 echo " ${DEPENDENCY} not found, too old or compiler error."
96 echo " Please recheck manually the source file \"${FNAME}.c\"."
97 echo " The compilation of the toolchain is probably going to fail,"
98 echo " you have been warned."
99 echo
100 echo " ===== Compiler output ====="
101 cat "${FNAME}.log"
102 echo " ==========================="
103 echo
104 else
105 echo " ${DEPENDENCY} found"
106 rm -f "${FNAME}.log" "${FNAME}.o" "${FNAME}.c"
110 check_dependecies() {
111 echo ">>> Basic dependency check"
112 check_dependency "GMP" "<gmp.h>" "${GMP_MAIN}"
113 check_dependency "MPFR" "<mpfr.h>" "${MPFR_MAIN}"
114 check_dependency "MPC" "<mpc.h>" "${MPC_MAIN}"
115 echo
118 check_error() {
119 if [ "$1" -ne "0" ]; then
120 echo
121 echo "Script failed: $2"
123 exit 1
127 check_md5() {
128 FILE="$1"
129 SUM="$2"
131 COMPUTED="`md5sum "${FILE}" | cut -d' ' -f1`"
132 if [ "${SUM}" != "${COMPUTED}" ] ; then
133 echo
134 echo "Checksum of ${FILE} does not match."
136 exit 2
140 show_usage() {
141 echo "Cross-compiler toolchain build script"
142 echo
143 echo "Syntax:"
144 echo " $0 [--no-install] [--helenos-target] <platform>"
145 echo
146 echo "Possible target platforms are:"
147 echo " amd64 AMD64 (x86-64, x64)"
148 echo " arm32 ARM"
149 echo " ia32 IA-32 (x86, i386)"
150 echo " ia64 IA-64 (Itanium)"
151 echo " mips32 MIPS little-endian 32b"
152 echo " mips32eb MIPS big-endian 32b"
153 echo " mips64 MIPS little-endian 64b"
154 echo " ppc32 32-bit PowerPC"
155 echo " ppc64 64-bit PowerPC"
156 echo " sparc64 SPARC V9"
157 echo " all build all targets"
158 echo " parallel same as 'all', but all in parallel"
159 echo " 2-way same as 'all', but 2-way parallel"
160 echo
161 echo "The toolchain is installed into directory specified by the"
162 echo "CROSS_PREFIX environment variable. If the variable is not"
163 echo "defined, /usr/local/cross/ is used as default."
164 echo
165 echo "If --no-install is present, the toolchain still uses the"
166 echo "CROSS_PREFIX as the target directory but the installation"
167 echo "copies the files into PKG/ subdirectory without affecting"
168 echo "the actual root file system. That is only useful if you do"
169 echo "not want to run the script under the super user."
170 echo
171 echo "The --helenos-target will build HelenOS-specific toolchain"
172 echo "(i.e. it will use *-helenos-* triplet instead of *-linux-*)."
173 echo "This toolchain is installed into /usr/local/cross-helenos by"
174 echo "default. The settings can be changed by setting environment"
175 echo "variable CROSS_HELENOS_PREFIX."
176 echo "Using the HelenOS-specific toolchain is still an experimental"
177 echo "feature that is not fully supported."
178 echo
180 exit 3
183 change_title() {
184 echo -en "\e]0;$1\a"
187 show_countdown() {
188 TM="$1"
190 if [ "${TM}" -eq 0 ] ; then
191 echo
192 return 0
195 echo -n "${TM} "
196 change_title "${TM}"
197 sleep 1
199 TM="`expr "${TM}" - 1`"
200 show_countdown "${TM}"
203 show_dependencies() {
204 echo "IMPORTANT NOTICE:"
205 echo
206 echo "For a successful compilation and use of the cross-compiler"
207 echo "toolchain you need at least the following dependencies."
208 echo
209 echo "Please make sure that the dependencies are present in your"
210 echo "system. Otherwise the compilation process might fail after"
211 echo "a few seconds or minutes."
212 echo
213 echo " - SED, AWK, Flex, Bison, gzip, bzip2, Bourne Shell"
214 echo " - gettext, zlib, Texinfo, libelf, libgomp"
215 echo " - terminfo"
216 echo " - GNU Multiple Precision Library (GMP)"
217 echo " - GNU Make"
218 echo " - GNU tar"
219 echo " - GNU Coreutils"
220 echo " - GNU Sharutils"
221 echo " - MPFR"
222 echo " - MPC"
223 echo " - Parma Polyhedra Library (PPL)"
224 echo " - ClooG-PPL"
225 echo " - native C compiler, assembler and linker"
226 echo " - native C library with headers"
227 echo
230 download_fetch() {
231 SOURCE="$1"
232 FILE="$2"
233 CHECKSUM="$3"
235 if [ ! -f "${FILE}" ]; then
236 change_title "Downloading ${FILE}"
237 wget -c "${SOURCE}${FILE}"
238 check_error $? "Error downloading ${FILE}."
241 check_md5 "${FILE}" "${CHECKSUM}"
244 source_check() {
245 FILE="$1"
247 if [ ! -f "${FILE}" ]; then
248 echo
249 echo "File ${FILE} not found."
251 exit 4
255 cleanup_dir() {
256 DIR="$1"
258 if [ -d "${DIR}" ]; then
259 change_title "Removing ${DIR}"
260 echo " >>> Removing ${DIR}"
261 rm -fr "${DIR}"
265 create_dir() {
266 DIR="$1"
267 DESC="$2"
269 change_title "Creating ${DESC}"
270 echo ">>> Creating ${DESC}"
272 mkdir -p "${DIR}"
273 test -d "${DIR}"
274 check_error $? "Unable to create ${DIR}."
277 check_dirs() {
278 OUTSIDE="$1"
279 BASE="$2"
280 ORIGINAL="`pwd`"
282 cd "${OUTSIDE}"
283 check_error $? "Unable to change directory to ${OUTSIDE}."
284 ABS_OUTSIDE="`pwd`"
286 cd "${BASE}"
287 check_error $? "Unable to change directory to ${BASE}."
288 ABS_BASE="`pwd`"
290 cd "${ORIGINAL}"
291 check_error $? "Unable to change directory to ${ORIGINAL}."
293 BASE_LEN="${#ABS_BASE}"
294 OUTSIDE_TRIM="${ABS_OUTSIDE:0:${BASE_LEN}}"
296 if [ "${OUTSIDE_TRIM}" == "${ABS_BASE}" ] ; then
297 echo
298 echo "CROSS_PREFIX cannot reside within the working directory."
300 exit 5
304 unpack_tarball() {
305 FILE="$1"
306 DESC="$2"
308 change_title "Unpacking ${DESC}"
309 echo " >>> Unpacking ${DESC}"
311 tar -xjf "${FILE}"
312 check_error $? "Error unpacking ${DESC}."
315 patch_sources() {
316 PATCH_FILE="$1"
317 PATCH_STRIP="$2"
318 DESC="$3"
320 change_title "Patching ${DESC}"
321 echo " >>> Patching ${DESC} with ${PATCH_FILE}"
323 patch -t "-p${PATCH_STRIP}" <"$PATCH_FILE"
324 check_error $? "Error patching ${DESC}."
327 prepare() {
328 show_dependencies
329 check_dependecies
330 show_countdown 10
332 BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
333 GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
334 GDB_SOURCE="ftp://ftp.gnu.org/gnu/gdb/"
336 download_fetch "${BINUTILS_SOURCE}" "${BINUTILS}" "33adb18c3048d057ac58d07a3f1adb38"
337 download_fetch "${GCC_SOURCE}" "${GCC}" "3b2386c114cd74185aa3754b58a79304"
338 download_fetch "${GDB_SOURCE}" "${GDB}" "fbc4dab4181e6e9937075b43a4ce2732"
341 set_target_from_platform() {
342 case "$1" in
343 "amd64")
344 LINUX_TARGET="amd64-linux-gnu"
345 HELENOS_TARGET="amd64-helenos"
347 "arm32")
348 LINUX_TARGET="arm-linux-gnueabi"
349 HELENOS_TARGET="arm-helenos-gnueabi"
351 "ia32")
352 LINUX_TARGET="i686-pc-linux-gnu"
353 HELENOS_TARGET="i686-pc-helenos"
355 "ia64")
356 LINUX_TARGET="ia64-pc-linux-gnu"
357 HELENOS_TARGET="ia64-pc-helenos"
359 "mips32")
360 LINUX_TARGET="mipsel-linux-gnu"
361 HELENOS_TARGET="mipsel-helenos"
363 "mips32eb")
364 LINUX_TARGET="mips-linux-gnu"
365 HELENOS_TARGET="mips-helenos"
367 "mips64")
368 LINUX_TARGET="mips64el-linux-gnu"
369 HELENOS_TARGET="mips64el-helenos"
371 "ppc32")
372 LINUX_TARGET="ppc-linux-gnu"
373 HELENOS_TARGET="ppc-helenos"
375 "ppc64")
376 LINUX_TARGET="ppc64-linux-gnu"
377 HELENOS_TARGET="ppc64-helenos"
379 "sparc64")
380 LINUX_TARGET="sparc64-linux-gnu"
381 HELENOS_TARGET="sparc64-helenos"
384 check_error 1 "No target known for $1."
386 esac
389 build_target() {
390 PLATFORM="$1"
391 # This sets the *_TARGET variables
392 set_target_from_platform "$PLATFORM"
393 if $USE_HELENOS_TARGET; then
394 TARGET="$HELENOS_TARGET"
395 else
396 TARGET="$LINUX_TARGET"
399 WORKDIR="${BASEDIR}/${PLATFORM}"
400 BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
401 GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
402 OBJDIR="${WORKDIR}/gcc-obj"
403 GDBDIR="${WORKDIR}/gdb-${GDB_VERSION}"
405 if [ -z "${CROSS_PREFIX}" ] ; then
406 CROSS_PREFIX="/usr/local/cross"
408 if [ -z "${CROSS_HELENOS_PREFIX}" ] ; then
409 CROSS_HELENOS_PREFIX="/usr/local/cross-helenos"
412 if $USE_HELENOS_TARGET; then
413 PREFIX="${CROSS_HELENOS_PREFIX}/${PLATFORM}"
414 else
415 PREFIX="${CROSS_PREFIX}/${PLATFORM}"
418 echo ">>> Downloading tarballs"
419 source_check "${BASEDIR}/${BINUTILS}"
420 source_check "${BASEDIR}/${GCC}"
421 source_check "${BASEDIR}/${GDB}"
423 echo ">>> Removing previous content"
424 $REAL_INSTALL && cleanup_dir "${PREFIX}"
425 cleanup_dir "${WORKDIR}"
427 $REAL_INSTALL && create_dir "${PREFIX}" "destination directory"
428 create_dir "${OBJDIR}" "GCC object directory"
430 check_dirs "${PREFIX}" "${WORKDIR}"
432 echo ">>> Unpacking tarballs"
433 cd "${WORKDIR}"
434 check_error $? "Change directory failed."
436 unpack_tarball "${BASEDIR}/${BINUTILS}" "binutils"
437 unpack_tarball "${BASEDIR}/${GCC}" "GCC"
438 unpack_tarball "${BASEDIR}/${GDB}" "GDB"
440 echo ">>> Applying patches"
441 for p in $BINUTILS_PATCHES; do
442 patch_sources "${BASEDIR}/${p}" 0 "binutils"
443 done
444 for p in $GCC_PATCHES; do
445 patch_sources "${BASEDIR}/${p}" 0 "GCC"
446 done
447 for p in $GDB_PATCHES; do
448 patch_sources "${BASEDIR}/${p}" 0 "GDB"
449 done
451 echo ">>> Processing binutils (${PLATFORM})"
452 cd "${BINUTILSDIR}"
453 check_error $? "Change directory failed."
455 change_title "binutils: configure (${PLATFORM})"
456 CFLAGS=-Wno-error ./configure \
457 "--target=${TARGET}" \
458 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
459 --disable-nls --disable-werror
460 check_error $? "Error configuring binutils."
462 change_title "binutils: make (${PLATFORM})"
463 make all
464 check_error $? "Error compiling binutils."
466 change_title "binutils: install (${PLATFORM})"
467 if $REAL_INSTALL; then
468 make install
469 else
470 make install "DESTDIR=${INSTALL_DIR}"
472 check_error $? "Error installing binutils."
475 echo ">>> Processing GCC (${PLATFORM})"
476 cd "${OBJDIR}"
477 check_error $? "Change directory failed."
479 change_title "GCC: configure (${PLATFORM})"
480 PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" "${GCCDIR}/configure" \
481 "--target=${TARGET}" \
482 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
483 --with-gnu-as --with-gnu-ld --disable-nls --disable-threads \
484 --enable-languages=c,objc,c++,obj-c++ \
485 --disable-multilib --disable-libgcj --without-headers \
486 --disable-shared --enable-lto --disable-werror
487 check_error $? "Error configuring GCC."
489 change_title "GCC: make (${PLATFORM})"
490 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-gcc
491 check_error $? "Error compiling GCC."
493 change_title "GCC: install (${PLATFORM})"
494 if $REAL_INSTALL; then
495 PATH="${PATH}:${PREFIX}/bin" make install-gcc
496 else
497 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-gcc "DESTDIR=${INSTALL_DIR}"
499 check_error $? "Error installing GCC."
502 echo ">>> Processing GDB (${PLATFORM})"
503 cd "${GDBDIR}"
504 check_error $? "Change directory failed."
506 change_title "GDB: configure (${PLATFORM})"
507 PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" ./configure \
508 "--target=${TARGET}" \
509 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-"
510 check_error $? "Error configuring GDB."
512 change_title "GDB: make (${PLATFORM})"
513 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all
514 check_error $? "Error compiling GDB."
516 change_title "GDB: make (${PLATFORM})"
517 if $REAL_INSTALL; then
518 PATH="${PATH}:${PREFIX}/bin" make install
519 else
520 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install "DESTDIR=${INSTALL_DIR}"
522 check_error $? "Error installing GDB."
525 cd "${BASEDIR}"
526 check_error $? "Change directory failed."
528 echo ">>> Cleaning up"
529 cleanup_dir "${WORKDIR}"
531 echo
532 echo ">>> Cross-compiler for ${TARGET} installed."
535 while [ "$#" -gt 1 ]; do
536 case "$1" in
537 --no-install)
538 REAL_INSTALL=false
539 shift
541 --helenos-target)
542 USE_HELENOS_TARGET=true
543 shift
546 show_usage
548 esac
549 done
551 if [ "$#" -lt "1" ]; then
552 show_usage
555 case "$1" in
556 amd64|arm32|ia32|ia64|mips32|mips32eb|mips64|ppc32|ppc64|sparc64)
557 prepare
558 build_target "$1"
560 "all")
561 prepare
562 build_target "amd64"
563 build_target "arm32"
564 build_target "ia32"
565 build_target "ia64"
566 build_target "mips32"
567 build_target "mips32eb"
568 build_target "mips64"
569 build_target "ppc32"
570 build_target "ppc64"
571 build_target "sparc64"
573 "parallel")
574 prepare
575 build_target "amd64" &
576 build_target "arm32" &
577 build_target "ia32" &
578 build_target "ia64" &
579 build_target "mips32" &
580 build_target "mips32eb" &
581 build_target "mips64" &
582 build_target "ppc32" &
583 build_target "ppc64" &
584 build_target "sparc64" &
585 wait
587 "2-way")
588 prepare
589 build_target "amd64" &
590 build_target "arm32" &
591 wait
593 build_target "ia32" &
594 build_target "ia64" &
595 wait
597 build_target "mips32" &
598 build_target "mips32eb" &
599 wait
601 build_target "mips64" &
602 build_target "ppc32" &
603 wait
605 build_target "ppc64" &
606 build_target "sparc64" &
607 wait
610 show_usage
612 esac