source: mainline/tools/toolchain.sh@ 0f28387

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 0f28387 was 0f28387, checked in by jzr <zarevucky.jiri@…>, 8 years ago

toolchain.sh: enable gold linker, disable guile support, only touch install path after finishing build, and symlink clang and lld.

Guile support causes build failure on some systems (at least Archlinux) because of API breakage.
Disabling it for now, until upstream sorts out the issue.

  • Property mode set to 100755
File size: 15.8 KB
Line 
1#! /bin/bash
2
3#
4# Copyright (c) 2009 Martin Decky
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10#
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.
18#
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.
29#
30
31GMP_MAIN=<<EOF
32#define GCC_GMP_VERSION_NUM(a, b, c) \
33 (((a) << 16L) | ((b) << 8) | (c))
34
35#define GCC_GMP_VERSION \
36 GCC_GMP_VERSION_NUM(__GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL)
37
38#if GCC_GMP_VERSION < GCC_GMP_VERSION_NUM(4, 3, 2)
39 choke me
40#endif
41EOF
42
43MPFR_MAIN=<<EOF
44#if MPFR_VERSION < MPFR_VERSION_NUM(2, 4, 2)
45 choke me
46#endif
47EOF
48
49MPC_MAIN=<<EOF
50#if MPC_VERSION < MPC_VERSION_NUM(0, 8, 1)
51 choke me
52#endif
53EOF
54
55ISL_MAIN=<<EOF
56isl_ctx_get_max_operations (isl_ctx_alloc ());
57EOF
58
59BINUTILS_VERSION="2.28"
60BINUTILS_RELEASE=""
61## BINUTILS_PATCHES="toolchain-binutils-2.23.1.patch"
62GCC_VERSION="7.1.0"
63## GCC_PATCHES="toolchain-gcc-4.8.1-targets.patch toolchain-gcc-4.8.1-headers.patch"
64GDB_VERSION="7.12.1"
65## GDB_PATCHES="toolchain-gdb-7.6.1.patch"
66
67BASEDIR="`pwd`"
68SRCDIR="$(readlink -f $(dirname "$0"))"
69BINUTILS="binutils-${BINUTILS_VERSION}${BINUTILS_RELEASE}.tar.bz2"
70GCC="gcc-${GCC_VERSION}.tar.bz2"
71GDB="gdb-${GDB_VERSION}.tar.gz"
72
73REAL_INSTALL=true
74USE_HELENOS_TARGET=false
75INSTALL_DIR="${BASEDIR}/PKG"
76
77#
78# Check if the library described in the argument
79# exists and has acceptable version.
80#
81check_dependency() {
82 DEPENDENCY="$1"
83 HEADER="$2"
84 BODY="$3"
85
86 FNAME="/tmp/conftest-$$"
87
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"
95
96 cc $CFLAGS -c -o "${FNAME}.o" "${FNAME}.c" 2> "${FNAME}.log"
97 RC="$?"
98
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"
112 fi
113}
114
115check_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
122}
123
124check_error() {
125 if [ "$1" -ne "0" ] ; then
126 echo
127 echo "Script failed: $2"
128
129 exit 1
130 fi
131}
132
133check_md5() {
134 FILE="$1"
135 SUM="$2"
136
137 COMPUTED="`md5sum "${FILE}" | cut -d' ' -f1`"
138 if [ "${SUM}" != "${COMPUTED}" ] ; then
139 echo
140 echo "Checksum of ${FILE} does not match."
141
142 exit 2
143 fi
144}
145
146show_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
187
188 exit 3
189}
190
191change_title() {
192 echo -en "\e]0;$1\a"
193}
194
195show_countdown() {
196 TM="$1"
197
198 if [ "${TM}" -eq 0 ] ; then
199 echo
200 return 0
201 fi
202
203 echo -n "${TM} "
204 change_title "${TM}"
205 sleep 1
206
207 TM="`expr "${TM}" - 1`"
208 show_countdown "${TM}"
209}
210
211show_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
231}
232
233download_fetch() {
234 SOURCE="$1"
235 FILE="$2"
236 CHECKSUM="$3"
237
238 if [ ! -f "${FILE}" ] ; then
239 change_title "Downloading ${FILE}"
240 wget -c "${SOURCE}${FILE}"
241 check_error $? "Error downloading ${FILE}."
242 fi
243
244 check_md5 "${FILE}" "${CHECKSUM}"
245}
246
247source_check() {
248 FILE="$1"
249
250 if [ ! -f "${FILE}" ] ; then
251 echo
252 echo "File ${FILE} not found."
253
254 exit 4
255 fi
256}
257
258cleanup_dir() {
259 DIR="$1"
260
261 if [ -d "${DIR}" ] ; then
262 change_title "Removing ${DIR}"
263 echo " >>> Removing ${DIR}"
264 rm -fr "${DIR}"
265 fi
266}
267
268create_dir() {
269 DIR="$1"
270 DESC="$2"
271
272 change_title "Creating ${DESC}"
273 echo ">>> Creating ${DESC}"
274
275 mkdir -p "${DIR}"
276 test -d "${DIR}"
277 check_error $? "Unable to create ${DIR}."
278}
279
280check_dirs() {
281 OUTSIDE="$1"
282 BASE="$2"
283 ORIGINAL="`pwd`"
284
285 mkdir -p "${OUTSIDE}"
286
287 cd "${OUTSIDE}"
288 check_error $? "Unable to change directory to ${OUTSIDE}."
289 ABS_OUTSIDE="`pwd`"
290
291 cd "${BASE}"
292 check_error $? "Unable to change directory to ${BASE}."
293 ABS_BASE="`pwd`"
294
295 cd "${ORIGINAL}"
296 check_error $? "Unable to change directory to ${ORIGINAL}."
297
298 BASE_LEN="${#ABS_BASE}"
299 OUTSIDE_TRIM="${ABS_OUTSIDE:0:${BASE_LEN}}"
300
301 if [ "${OUTSIDE_TRIM}" == "${ABS_BASE}" ] ; then
302 echo
303 echo "CROSS_PREFIX cannot reside within the working directory."
304
305 exit 5
306 fi
307}
308
309unpack_tarball() {
310 FILE="$1"
311 DESC="$2"
312
313 change_title "Unpacking ${DESC}"
314 echo " >>> Unpacking ${DESC}"
315
316 case "${FILE}" in
317 *.gz)
318 tar -xzf "${FILE}"
319 ;;
320 *.xz)
321 tar -xJf "${FILE}"
322 ;;
323 *.bz2)
324 tar -xjf "${FILE}"
325 ;;
326 *)
327 check_error 1 "Don't know how to unpack ${DESC}."
328 ;;
329 esac
330 check_error $? "Error unpacking ${DESC}."
331}
332
333patch_sources() {
334 PATCH_FILE="$1"
335 PATCH_STRIP="$2"
336 DESC="$3"
337
338 change_title "Patching ${DESC}"
339 echo " >>> Patching ${DESC} with ${PATCH_FILE}"
340
341 patch -t "-p${PATCH_STRIP}" <"$PATCH_FILE"
342 check_error $? "Error patching ${DESC}."
343}
344
345prepare() {
346 show_dependencies
347 check_dependecies
348 show_countdown 10
349
350 BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
351 GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
352 GDB_SOURCE="ftp://ftp.gnu.org/gnu/gdb/"
353
354 download_fetch "${BINUTILS_SOURCE}" "${BINUTILS}" "9e8340c96626b469a603c15c9d843727"
355 download_fetch "${GCC_SOURCE}" "${GCC}" "6bf56a2bca9dac9dbbf8e8d1036964a8"
356 download_fetch "${GDB_SOURCE}" "${GDB}" "06c8f40521ed65fe36ebc2be29b56942"
357}
358
359set_target_from_platform() {
360 case "$1" in
361 "amd64")
362 LINUX_TARGET="amd64-linux-gnu"
363 HELENOS_TARGET="amd64-helenos"
364 ;;
365 "arm32")
366 LINUX_TARGET="arm-linux-gnueabi"
367 HELENOS_TARGET="arm-helenos-gnueabi"
368 ;;
369 "ia32")
370 LINUX_TARGET="i686-pc-linux-gnu"
371 HELENOS_TARGET="i686-pc-helenos"
372 ;;
373 "ia64")
374 LINUX_TARGET="ia64-pc-linux-gnu"
375 HELENOS_TARGET="ia64-pc-helenos"
376 ;;
377 "mips32")
378 LINUX_TARGET="mipsel-linux-gnu"
379 HELENOS_TARGET="mipsel-helenos"
380 ;;
381 "mips32eb")
382 LINUX_TARGET="mips-linux-gnu"
383 HELENOS_TARGET="mips-helenos"
384 ;;
385 "mips64")
386 LINUX_TARGET="mips64el-linux-gnu"
387 HELENOS_TARGET="mips64el-helenos"
388 ;;
389 "ppc32")
390 LINUX_TARGET="ppc-linux-gnu"
391 HELENOS_TARGET="ppc-helenos"
392 ;;
393 "ppc64")
394 LINUX_TARGET="ppc64-linux-gnu"
395 HELENOS_TARGET="ppc64-helenos"
396 ;;
397 "riscv64")
398 LINUX_TARGET="riscv64-unknown-linux-gnu"
399 HELENOS_TARGET="riscv64-helenos"
400 ;;
401 "sparc64")
402 LINUX_TARGET="sparc64-linux-gnu"
403 HELENOS_TARGET="sparc64-helenos"
404 ;;
405 *)
406 check_error 1 "No target known for $1."
407 ;;
408 esac
409}
410
411build_target() {
412 PLATFORM="$1"
413
414 # This sets the *_TARGET variables
415 set_target_from_platform "$PLATFORM"
416 if $USE_HELENOS_TARGET ; then
417 TARGET="$HELENOS_TARGET"
418 else
419 TARGET="$LINUX_TARGET"
420 fi
421
422 WORKDIR="${BASEDIR}/${PLATFORM}"
423 BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
424 GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
425 OBJDIR="${WORKDIR}/gcc-obj"
426 GDBDIR="${WORKDIR}/gdb-${GDB_VERSION}"
427
428 if [ -z "${CROSS_PREFIX}" ] ; then
429 CROSS_PREFIX="/usr/local/cross"
430 fi
431 if [ -z "${CROSS_HELENOS_PREFIX}" ] ; then
432 CROSS_HELENOS_PREFIX="/usr/local/cross-helenos"
433 fi
434
435 if $USE_HELENOS_TARGET ; then
436 PREFIX="${CROSS_HELENOS_PREFIX}/${PLATFORM}"
437 else
438 PREFIX="${CROSS_PREFIX}/${PLATFORM}"
439 fi
440
441 echo ">>> Downloading tarballs"
442 source_check "${BASEDIR}/${BINUTILS}"
443 source_check "${BASEDIR}/${GCC}"
444 source_check "${BASEDIR}/${GDB}"
445
446 echo ">>> Removing previous content"
447 cleanup_dir "${WORKDIR}"
448
449 create_dir "${OBJDIR}" "GCC object directory"
450
451 check_dirs "${PREFIX}" "${WORKDIR}"
452
453 echo ">>> Unpacking tarballs"
454 cd "${WORKDIR}"
455 check_error $? "Change directory failed."
456
457 unpack_tarball "${BASEDIR}/${BINUTILS}" "binutils"
458 unpack_tarball "${BASEDIR}/${GCC}" "GCC"
459 unpack_tarball "${BASEDIR}/${GDB}" "GDB"
460
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
471
472 echo ">>> Processing binutils (${PLATFORM})"
473 cd "${BINUTILSDIR}"
474 check_error $? "Change directory failed."
475
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 --enable-gold
481 check_error $? "Error configuring binutils."
482
483 change_title "binutils: make (${PLATFORM})"
484 make all
485 check_error $? "Error compiling binutils."
486
487 change_title "binutils: install (${PLATFORM})"
488 make install "DESTDIR=${INSTALL_DIR}"
489 check_error $? "Error installing binutils."
490
491
492 echo ">>> Processing GCC (${PLATFORM})"
493 cd "${OBJDIR}"
494 check_error $? "Change directory failed."
495
496 change_title "GCC: configure (${PLATFORM})"
497 PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" "${GCCDIR}/configure" \
498 "--target=${TARGET}" \
499 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
500 --with-gnu-as --with-gnu-ld --disable-nls --disable-threads \
501 --enable-languages=c,objc,c++,obj-c++ \
502 --disable-multilib --disable-libgcj --without-headers \
503 --disable-shared --enable-lto --disable-werror
504 check_error $? "Error configuring GCC."
505
506 change_title "GCC: make (${PLATFORM})"
507 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-gcc
508 check_error $? "Error compiling GCC."
509
510 change_title "GCC: install (${PLATFORM})"
511 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-gcc "DESTDIR=${INSTALL_DIR}"
512 check_error $? "Error installing GCC."
513
514
515 # No GDB support for RISC-V so far
516 if [ "$PLATFORM" != "riscv64" ] ; then
517 echo ">>> Processing GDB (${PLATFORM})"
518 cd "${GDBDIR}"
519 check_error $? "Change directory failed."
520
521 change_title "GDB: configure (${PLATFORM})"
522 PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" ./configure \
523 "--target=${TARGET}" \
524 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
525 --enable-werror=no --without-guile
526 check_error $? "Error configuring GDB."
527
528 change_title "GDB: make (${PLATFORM})"
529 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all
530 check_error $? "Error compiling GDB."
531
532 change_title "GDB: make (${PLATFORM})"
533 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install "DESTDIR=${INSTALL_DIR}"
534 check_error $? "Error installing GDB."
535 fi
536
537 # Symlink clang and lld to the install path.
538 CLANG=`which clang 2> /dev/null || echo "/usr/bin/clang"`
539 LLD=`which ld.lld 2> /dev/null || echo "/usr/bin/ld.lld"`
540
541 ln -s $CLANG "${INSTALL_DIR}/${PREFIX}/bin/${TARGET}-clang"
542 ln -s $LLD "${INSTALL_DIR}/${PREFIX}/bin/${TARGET}-ld.lld"
543
544 if $REAL_INSTALL ; then
545 echo ">>> Moving to the destination directory."
546 cleanup_dir "${PREFIX}"
547 echo mv "${INSTALL_DIR}/${PREFIX}" "${PREFIX}"
548 mv "${INSTALL_DIR}/${PREFIX}" "${PREFIX}"
549 fi
550
551 cd "${BASEDIR}"
552 check_error $? "Change directory failed."
553
554 echo ">>> Cleaning up"
555 cleanup_dir "${WORKDIR}"
556
557 echo
558 echo ">>> Cross-compiler for ${TARGET} installed."
559}
560
561while [ "$#" -gt 1 ] ; do
562 case "$1" in
563 --no-install)
564 REAL_INSTALL=false
565 shift
566 ;;
567 --helenos-target)
568 USE_HELENOS_TARGET=true
569 shift
570 ;;
571 *)
572 show_usage
573 ;;
574 esac
575done
576
577if [ "$#" -lt "1" ] ; then
578 show_usage
579fi
580
581case "$1" in
582 amd64|arm32|ia32|ia64|mips32|mips32eb|mips64|ppc32|ppc64|riscv64|sparc64)
583 prepare
584 build_target "$1"
585 ;;
586 "all")
587 prepare
588 build_target "amd64"
589 build_target "arm32"
590 build_target "ia32"
591 build_target "ia64"
592 build_target "mips32"
593 build_target "mips32eb"
594 build_target "mips64"
595 build_target "ppc32"
596 build_target "ppc64"
597 build_target "riscv64"
598 build_target "sparc64"
599 ;;
600 "essential")
601 prepare
602 build_target "amd64"
603 build_target "arm32"
604 build_target "ia32"
605 build_target "ia64"
606 build_target "mips32"
607 build_target "mips32eb"
608 build_target "ppc32"
609 build_target "sparc64"
610 ;;
611 "parallel")
612 prepare
613 build_target "amd64" &
614 build_target "arm32" &
615 build_target "ia32" &
616 build_target "ia64" &
617 build_target "mips32" &
618 build_target "mips32eb" &
619 build_target "mips64" &
620 build_target "ppc32" &
621 build_target "ppc64" &
622 build_target "riscv64" &
623 build_target "sparc64" &
624 wait
625 ;;
626 "2-way")
627 prepare
628 build_target "amd64" &
629 build_target "arm32" &
630 wait
631
632 build_target "ia32" &
633 build_target "ia64" &
634 wait
635
636 build_target "mips32" &
637 build_target "mips32eb" &
638 wait
639
640 build_target "mips64" &
641 build_target "ppc32" &
642 wait
643
644 build_target "riscv64" &
645 build_target "ppc64" &
646 wait
647
648 build_target "sparc64" &
649 wait
650 ;;
651 *)
652 show_usage
653 ;;
654esac
Note: See TracBrowser for help on using the repository browser.