source: mainline/tools/toolchain.sh@ d2bd00f0

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since d2bd00f0 was d2bd00f0, checked in by Martin Decky <martin@…>, 8 years ago

bump to GCC 7.1, binutils 2.28 (both now include upstream support for RISC-V)
no upstream support for RISC-V in GDB so far

  • Property mode set to 100755
File size: 15.3 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 " parallel same as 'all', but all in parallel"
166 echo " 2-way same as 'all', but 2-way parallel"
167 echo
168 echo "The toolchain is installed into directory specified by the"
169 echo "CROSS_PREFIX environment variable. If the variable is not"
170 echo "defined, /usr/local/cross/ is used as default."
171 echo
172 echo "If --no-install is present, the toolchain still uses the"
173 echo "CROSS_PREFIX as the target directory but the installation"
174 echo "copies the files into PKG/ subdirectory without affecting"
175 echo "the actual root file system. That is only useful if you do"
176 echo "not want to run the script under the super user."
177 echo
178 echo "The --helenos-target will build HelenOS-specific toolchain"
179 echo "(i.e. it will use *-helenos-* triplet instead of *-linux-*)."
180 echo "This toolchain is installed into /usr/local/cross-helenos by"
181 echo "default. The settings can be changed by setting environment"
182 echo "variable CROSS_HELENOS_PREFIX."
183 echo "Using the HelenOS-specific toolchain is still an experimental"
184 echo "feature that is not fully supported."
185 echo
186
187 exit 3
188}
189
190change_title() {
191 echo -en "\e]0;$1\a"
192}
193
194show_countdown() {
195 TM="$1"
196
197 if [ "${TM}" -eq 0 ] ; then
198 echo
199 return 0
200 fi
201
202 echo -n "${TM} "
203 change_title "${TM}"
204 sleep 1
205
206 TM="`expr "${TM}" - 1`"
207 show_countdown "${TM}"
208}
209
210show_dependencies() {
211 echo "IMPORTANT NOTICE:"
212 echo
213 echo "For a successful compilation and use of the cross-compiler"
214 echo "toolchain you need at least the following dependencies."
215 echo
216 echo "Please make sure that the dependencies are present in your"
217 echo "system. Otherwise the compilation process might fail after"
218 echo "a few seconds or minutes."
219 echo
220 echo " - SED, AWK, Flex, Bison, gzip, bzip2, Bourne Shell"
221 echo " - gettext, zlib, Texinfo, libelf, libgomp"
222 echo " - GNU Make, Coreutils, Sharutils, tar"
223 echo " - GNU Multiple Precision Library (GMP)"
224 echo " - MPFR"
225 echo " - MPC"
226 echo " - integer point manipulation library (isl)"
227 echo " - native C and C++ compiler, assembler and linker"
228 echo " - native C and C++ standard library with headers"
229 echo
230}
231
232download_fetch() {
233 SOURCE="$1"
234 FILE="$2"
235 CHECKSUM="$3"
236
237 if [ ! -f "${FILE}" ]; then
238 change_title "Downloading ${FILE}"
239 wget -c "${SOURCE}${FILE}"
240 check_error $? "Error downloading ${FILE}."
241 fi
242
243 check_md5 "${FILE}" "${CHECKSUM}"
244}
245
246source_check() {
247 FILE="$1"
248
249 if [ ! -f "${FILE}" ]; then
250 echo
251 echo "File ${FILE} not found."
252
253 exit 4
254 fi
255}
256
257cleanup_dir() {
258 DIR="$1"
259
260 if [ -d "${DIR}" ]; then
261 change_title "Removing ${DIR}"
262 echo " >>> Removing ${DIR}"
263 rm -fr "${DIR}"
264 fi
265}
266
267create_dir() {
268 DIR="$1"
269 DESC="$2"
270
271 change_title "Creating ${DESC}"
272 echo ">>> Creating ${DESC}"
273
274 mkdir -p "${DIR}"
275 test -d "${DIR}"
276 check_error $? "Unable to create ${DIR}."
277}
278
279check_dirs() {
280 OUTSIDE="$1"
281 BASE="$2"
282 ORIGINAL="`pwd`"
283
284 cd "${OUTSIDE}"
285 check_error $? "Unable to change directory to ${OUTSIDE}."
286 ABS_OUTSIDE="`pwd`"
287
288 cd "${BASE}"
289 check_error $? "Unable to change directory to ${BASE}."
290 ABS_BASE="`pwd`"
291
292 cd "${ORIGINAL}"
293 check_error $? "Unable to change directory to ${ORIGINAL}."
294
295 BASE_LEN="${#ABS_BASE}"
296 OUTSIDE_TRIM="${ABS_OUTSIDE:0:${BASE_LEN}}"
297
298 if [ "${OUTSIDE_TRIM}" == "${ABS_BASE}" ] ; then
299 echo
300 echo "CROSS_PREFIX cannot reside within the working directory."
301
302 exit 5
303 fi
304}
305
306unpack_tarball() {
307 FILE="$1"
308 DESC="$2"
309
310 change_title "Unpacking ${DESC}"
311 echo " >>> Unpacking ${DESC}"
312
313 case "${FILE}" in
314 *.gz)
315 tar -xzf "${FILE}"
316 ;;
317 *.xz)
318 tar -xJf "${FILE}"
319 ;;
320 *.bz2)
321 tar -xjf "${FILE}"
322 ;;
323 *)
324 check_error 1 "Don't know how to unpack ${DESC}."
325 ;;
326 esac
327 check_error $? "Error unpacking ${DESC}."
328}
329
330patch_sources() {
331 PATCH_FILE="$1"
332 PATCH_STRIP="$2"
333 DESC="$3"
334
335 change_title "Patching ${DESC}"
336 echo " >>> Patching ${DESC} with ${PATCH_FILE}"
337
338 patch -t "-p${PATCH_STRIP}" <"$PATCH_FILE"
339 check_error $? "Error patching ${DESC}."
340}
341
342prepare() {
343 show_dependencies
344 check_dependecies
345 show_countdown 10
346
347 BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
348 GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
349 GDB_SOURCE="ftp://ftp.gnu.org/gnu/gdb/"
350
351 download_fetch "${BINUTILS_SOURCE}" "${BINUTILS}" "9e8340c96626b469a603c15c9d843727"
352 download_fetch "${GCC_SOURCE}" "${GCC}" "6bf56a2bca9dac9dbbf8e8d1036964a8"
353 download_fetch "${GDB_SOURCE}" "${GDB}" "06c8f40521ed65fe36ebc2be29b56942"
354}
355
356set_target_from_platform() {
357 case "$1" in
358 "amd64")
359 LINUX_TARGET="amd64-linux-gnu"
360 HELENOS_TARGET="amd64-helenos"
361 ;;
362 "arm32")
363 LINUX_TARGET="arm-linux-gnueabi"
364 HELENOS_TARGET="arm-helenos-gnueabi"
365 ;;
366 "ia32")
367 LINUX_TARGET="i686-pc-linux-gnu"
368 HELENOS_TARGET="i686-pc-helenos"
369 ;;
370 "ia64")
371 LINUX_TARGET="ia64-pc-linux-gnu"
372 HELENOS_TARGET="ia64-pc-helenos"
373 ;;
374 "mips32")
375 LINUX_TARGET="mipsel-linux-gnu"
376 HELENOS_TARGET="mipsel-helenos"
377 ;;
378 "mips32eb")
379 LINUX_TARGET="mips-linux-gnu"
380 HELENOS_TARGET="mips-helenos"
381 ;;
382 "mips64")
383 LINUX_TARGET="mips64el-linux-gnu"
384 HELENOS_TARGET="mips64el-helenos"
385 ;;
386 "ppc32")
387 LINUX_TARGET="ppc-linux-gnu"
388 HELENOS_TARGET="ppc-helenos"
389 ;;
390 "ppc64")
391 LINUX_TARGET="ppc64-linux-gnu"
392 HELENOS_TARGET="ppc64-helenos"
393 ;;
394 "riscv64")
395 LINUX_TARGET="riscv64-unknown-linux-gnu"
396 HELENOS_TARGET="riscv64-helenos"
397 ;;
398 "sparc64")
399 LINUX_TARGET="sparc64-linux-gnu"
400 HELENOS_TARGET="sparc64-helenos"
401 ;;
402 *)
403 check_error 1 "No target known for $1."
404 ;;
405 esac
406}
407
408build_target() {
409 PLATFORM="$1"
410 # This sets the *_TARGET variables
411 set_target_from_platform "$PLATFORM"
412 if $USE_HELENOS_TARGET; then
413 TARGET="$HELENOS_TARGET"
414 else
415 TARGET="$LINUX_TARGET"
416 fi
417
418 WORKDIR="${BASEDIR}/${PLATFORM}"
419 BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
420 GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
421 OBJDIR="${WORKDIR}/gcc-obj"
422 GDBDIR="${WORKDIR}/gdb-${GDB_VERSION}"
423
424 if [ -z "${CROSS_PREFIX}" ] ; then
425 CROSS_PREFIX="/usr/local/cross"
426 fi
427 if [ -z "${CROSS_HELENOS_PREFIX}" ] ; then
428 CROSS_HELENOS_PREFIX="/usr/local/cross-helenos"
429 fi
430
431 if $USE_HELENOS_TARGET; then
432 PREFIX="${CROSS_HELENOS_PREFIX}/${PLATFORM}"
433 else
434 PREFIX="${CROSS_PREFIX}/${PLATFORM}"
435 fi
436
437 echo ">>> Downloading tarballs"
438 source_check "${BASEDIR}/${BINUTILS}"
439 source_check "${BASEDIR}/${GCC}"
440 source_check "${BASEDIR}/${GDB}"
441
442 echo ">>> Removing previous content"
443 $REAL_INSTALL && cleanup_dir "${PREFIX}"
444 cleanup_dir "${WORKDIR}"
445
446 $REAL_INSTALL && create_dir "${PREFIX}" "destination directory"
447 create_dir "${OBJDIR}" "GCC object directory"
448
449 check_dirs "${PREFIX}" "${WORKDIR}"
450
451 echo ">>> Unpacking tarballs"
452 cd "${WORKDIR}"
453 check_error $? "Change directory failed."
454
455 unpack_tarball "${BASEDIR}/${BINUTILS}" "binutils"
456 unpack_tarball "${BASEDIR}/${GCC}" "GCC"
457 unpack_tarball "${BASEDIR}/${GDB}" "GDB"
458
459 echo ">>> Applying patches"
460 for p in $BINUTILS_PATCHES; do
461 patch_sources "${SRCDIR}/${p}" 0 "binutils"
462 done
463 for p in $GCC_PATCHES; do
464 patch_sources "${SRCDIR}/${p}" 0 "GCC"
465 done
466 for p in $GDB_PATCHES; do
467 patch_sources "${SRCDIR}/${p}" 0 "GDB"
468 done
469
470 echo ">>> Processing binutils (${PLATFORM})"
471 cd "${BINUTILSDIR}"
472 check_error $? "Change directory failed."
473
474 change_title "binutils: configure (${PLATFORM})"
475 CFLAGS=-Wno-error ./configure \
476 "--target=${TARGET}" \
477 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
478 --disable-nls --disable-werror
479 check_error $? "Error configuring binutils."
480
481 change_title "binutils: make (${PLATFORM})"
482 make all
483 check_error $? "Error compiling binutils."
484
485 change_title "binutils: install (${PLATFORM})"
486 if $REAL_INSTALL; then
487 make install
488 else
489 make install "DESTDIR=${INSTALL_DIR}"
490 fi
491 check_error $? "Error installing binutils."
492
493
494 echo ">>> Processing GCC (${PLATFORM})"
495 cd "${OBJDIR}"
496 check_error $? "Change directory failed."
497
498 change_title "GCC: configure (${PLATFORM})"
499 PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" "${GCCDIR}/configure" \
500 "--target=${TARGET}" \
501 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
502 --with-gnu-as --with-gnu-ld --disable-nls --disable-threads \
503 --enable-languages=c,objc,c++,obj-c++ \
504 --disable-multilib --disable-libgcj --without-headers \
505 --disable-shared --enable-lto --disable-werror
506 check_error $? "Error configuring GCC."
507
508 change_title "GCC: make (${PLATFORM})"
509 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-gcc
510 check_error $? "Error compiling GCC."
511
512 change_title "GCC: install (${PLATFORM})"
513 if $REAL_INSTALL; then
514 PATH="${PATH}:${PREFIX}/bin" make install-gcc
515 else
516 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-gcc "DESTDIR=${INSTALL_DIR}"
517 fi
518 check_error $? "Error installing GCC."
519
520
521 # No GDB support for RISC-V so far
522 if [ "$PLATFORM" != "riscv64" ] ; then
523 echo ">>> Processing GDB (${PLATFORM})"
524 cd "${GDBDIR}"
525 check_error $? "Change directory failed."
526
527 change_title "GDB: configure (${PLATFORM})"
528 PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" ./configure \
529 "--target=${TARGET}" \
530 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
531 --enable-werror=no
532 check_error $? "Error configuring GDB."
533
534 change_title "GDB: make (${PLATFORM})"
535 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all
536 check_error $? "Error compiling GDB."
537
538 change_title "GDB: make (${PLATFORM})"
539 if $REAL_INSTALL ; then
540 PATH="${PATH}:${PREFIX}/bin" make install
541 else
542 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install "DESTDIR=${INSTALL_DIR}"
543 fi
544 check_error $? "Error installing GDB."
545 fi
546
547
548 cd "${BASEDIR}"
549 check_error $? "Change directory failed."
550
551 echo ">>> Cleaning up"
552 cleanup_dir "${WORKDIR}"
553
554 echo
555 echo ">>> Cross-compiler for ${TARGET} installed."
556}
557
558while [ "$#" -gt 1 ]; do
559 case "$1" in
560 --no-install)
561 REAL_INSTALL=false
562 shift
563 ;;
564 --helenos-target)
565 USE_HELENOS_TARGET=true
566 shift
567 ;;
568 *)
569 show_usage
570 ;;
571 esac
572done
573
574if [ "$#" -lt "1" ]; then
575 show_usage
576fi
577
578case "$1" in
579 amd64|arm32|ia32|ia64|mips32|mips32eb|mips64|ppc32|ppc64|riscv64|sparc64)
580 prepare
581 build_target "$1"
582 ;;
583 "all")
584 prepare
585 build_target "amd64"
586 build_target "arm32"
587 build_target "ia32"
588 build_target "ia64"
589 build_target "mips32"
590 build_target "mips32eb"
591 build_target "mips64"
592 build_target "ppc32"
593 build_target "ppc64"
594 build_target "riscv64"
595 build_target "sparc64"
596 ;;
597 "parallel")
598 prepare
599 build_target "amd64" &
600 build_target "arm32" &
601 build_target "ia32" &
602 build_target "ia64" &
603 build_target "mips32" &
604 build_target "mips32eb" &
605 build_target "mips64" &
606 build_target "ppc32" &
607 build_target "ppc64" &
608 build_target "riscv64" &
609 build_target "sparc64" &
610 wait
611 ;;
612 "2-way")
613 prepare
614 build_target "amd64" &
615 build_target "arm32" &
616 wait
617
618 build_target "ia32" &
619 build_target "ia64" &
620 wait
621
622 build_target "mips32" &
623 build_target "mips32eb" &
624 wait
625
626 build_target "mips64" &
627 build_target "ppc32" &
628 wait
629
630 build_target "riscv64" &
631 build_target "ppc64" &
632 wait
633
634 build_target "sparc64" &
635 wait
636 ;;
637 *)
638 show_usage
639 ;;
640esac
Note: See TracBrowser for help on using the repository browser.