source: mainline/tools/toolchain.sh@ a4170d5

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

better support for non-standard configurations

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