source: mainline/tools/toolchain.sh@ fd9f4ffe

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since fd9f4ffe was 951f6b9e, checked in by Jakub Jermar <jakub@…>, 8 years ago

Allow building only toolchains needed for developing HelenOS

Use ./toolchain.sh essential to build only targets for which HelenOS has
a build profile.

  • Property mode set to 100755
File size: 15.6 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 cd "${OUTSIDE}"
286 check_error $? "Unable to change directory to ${OUTSIDE}."
287 ABS_OUTSIDE="`pwd`"
288
289 cd "${BASE}"
290 check_error $? "Unable to change directory to ${BASE}."
291 ABS_BASE="`pwd`"
292
293 cd "${ORIGINAL}"
294 check_error $? "Unable to change directory to ${ORIGINAL}."
295
296 BASE_LEN="${#ABS_BASE}"
297 OUTSIDE_TRIM="${ABS_OUTSIDE:0:${BASE_LEN}}"
298
299 if [ "${OUTSIDE_TRIM}" == "${ABS_BASE}" ] ; then
300 echo
301 echo "CROSS_PREFIX cannot reside within the working directory."
302
303 exit 5
304 fi
305}
306
307unpack_tarball() {
308 FILE="$1"
309 DESC="$2"
310
311 change_title "Unpacking ${DESC}"
312 echo " >>> Unpacking ${DESC}"
313
314 case "${FILE}" in
315 *.gz)
316 tar -xzf "${FILE}"
317 ;;
318 *.xz)
319 tar -xJf "${FILE}"
320 ;;
321 *.bz2)
322 tar -xjf "${FILE}"
323 ;;
324 *)
325 check_error 1 "Don't know how to unpack ${DESC}."
326 ;;
327 esac
328 check_error $? "Error unpacking ${DESC}."
329}
330
331patch_sources() {
332 PATCH_FILE="$1"
333 PATCH_STRIP="$2"
334 DESC="$3"
335
336 change_title "Patching ${DESC}"
337 echo " >>> Patching ${DESC} with ${PATCH_FILE}"
338
339 patch -t "-p${PATCH_STRIP}" <"$PATCH_FILE"
340 check_error $? "Error patching ${DESC}."
341}
342
343prepare() {
344 show_dependencies
345 check_dependecies
346 show_countdown 10
347
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/"
351
352 download_fetch "${BINUTILS_SOURCE}" "${BINUTILS}" "9e8340c96626b469a603c15c9d843727"
353 download_fetch "${GCC_SOURCE}" "${GCC}" "6bf56a2bca9dac9dbbf8e8d1036964a8"
354 download_fetch "${GDB_SOURCE}" "${GDB}" "06c8f40521ed65fe36ebc2be29b56942"
355}
356
357set_target_from_platform() {
358 case "$1" in
359 "amd64")
360 LINUX_TARGET="amd64-linux-gnu"
361 HELENOS_TARGET="amd64-helenos"
362 ;;
363 "arm32")
364 LINUX_TARGET="arm-linux-gnueabi"
365 HELENOS_TARGET="arm-helenos-gnueabi"
366 ;;
367 "ia32")
368 LINUX_TARGET="i686-pc-linux-gnu"
369 HELENOS_TARGET="i686-pc-helenos"
370 ;;
371 "ia64")
372 LINUX_TARGET="ia64-pc-linux-gnu"
373 HELENOS_TARGET="ia64-pc-helenos"
374 ;;
375 "mips32")
376 LINUX_TARGET="mipsel-linux-gnu"
377 HELENOS_TARGET="mipsel-helenos"
378 ;;
379 "mips32eb")
380 LINUX_TARGET="mips-linux-gnu"
381 HELENOS_TARGET="mips-helenos"
382 ;;
383 "mips64")
384 LINUX_TARGET="mips64el-linux-gnu"
385 HELENOS_TARGET="mips64el-helenos"
386 ;;
387 "ppc32")
388 LINUX_TARGET="ppc-linux-gnu"
389 HELENOS_TARGET="ppc-helenos"
390 ;;
391 "ppc64")
392 LINUX_TARGET="ppc64-linux-gnu"
393 HELENOS_TARGET="ppc64-helenos"
394 ;;
395 "riscv64")
396 LINUX_TARGET="riscv64-unknown-linux-gnu"
397 HELENOS_TARGET="riscv64-helenos"
398 ;;
399 "sparc64")
400 LINUX_TARGET="sparc64-linux-gnu"
401 HELENOS_TARGET="sparc64-helenos"
402 ;;
403 *)
404 check_error 1 "No target known for $1."
405 ;;
406 esac
407}
408
409build_target() {
410 PLATFORM="$1"
411
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"
418 fi
419
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}"
425
426 if [ -z "${CROSS_PREFIX}" ] ; then
427 CROSS_PREFIX="/usr/local/cross"
428 fi
429 if [ -z "${CROSS_HELENOS_PREFIX}" ] ; then
430 CROSS_HELENOS_PREFIX="/usr/local/cross-helenos"
431 fi
432
433 if $USE_HELENOS_TARGET ; then
434 PREFIX="${CROSS_HELENOS_PREFIX}/${PLATFORM}"
435 else
436 PREFIX="${CROSS_PREFIX}/${PLATFORM}"
437 fi
438
439 echo ">>> Downloading tarballs"
440 source_check "${BASEDIR}/${BINUTILS}"
441 source_check "${BASEDIR}/${GCC}"
442 source_check "${BASEDIR}/${GDB}"
443
444 echo ">>> Removing previous content"
445 $REAL_INSTALL && cleanup_dir "${PREFIX}"
446 cleanup_dir "${WORKDIR}"
447
448 $REAL_INSTALL && create_dir "${PREFIX}" "destination directory"
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
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 if $REAL_INSTALL ; then
489 make install
490 else
491 make install "DESTDIR=${INSTALL_DIR}"
492 fi
493 check_error $? "Error installing binutils."
494
495
496 echo ">>> Processing GCC (${PLATFORM})"
497 cd "${OBJDIR}"
498 check_error $? "Change directory failed."
499
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."
509
510 change_title "GCC: make (${PLATFORM})"
511 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-gcc
512 check_error $? "Error compiling GCC."
513
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}"
519 fi
520 check_error $? "Error installing GCC."
521
522
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."
528
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."
535
536 change_title "GDB: make (${PLATFORM})"
537 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all
538 check_error $? "Error compiling GDB."
539
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}"
545 fi
546 check_error $? "Error installing GDB."
547 fi
548
549
550 cd "${BASEDIR}"
551 check_error $? "Change directory failed."
552
553 echo ">>> Cleaning up"
554 cleanup_dir "${WORKDIR}"
555
556 echo
557 echo ">>> Cross-compiler for ${TARGET} installed."
558}
559
560while [ "$#" -gt 1 ] ; do
561 case "$1" in
562 --no-install)
563 REAL_INSTALL=false
564 shift
565 ;;
566 --helenos-target)
567 USE_HELENOS_TARGET=true
568 shift
569 ;;
570 *)
571 show_usage
572 ;;
573 esac
574done
575
576if [ "$#" -lt "1" ] ; then
577 show_usage
578fi
579
580case "$1" in
581 amd64|arm32|ia32|ia64|mips32|mips32eb|mips64|ppc32|ppc64|riscv64|sparc64)
582 prepare
583 build_target "$1"
584 ;;
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"
598 ;;
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"
609 ;;
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
624 ;;
625 "2-way")
626 prepare
627 build_target "amd64" &
628 build_target "arm32" &
629 wait
630
631 build_target "ia32" &
632 build_target "ia64" &
633 wait
634
635 build_target "mips32" &
636 build_target "mips32eb" &
637 wait
638
639 build_target "mips64" &
640 build_target "ppc32" &
641 wait
642
643 build_target "riscv64" &
644 build_target "ppc64" &
645 wait
646
647 build_target "sparc64" &
648 wait
649 ;;
650 *)
651 show_usage
652 ;;
653esac
Note: See TracBrowser for help on using the repository browser.