source: mainline/tools/toolchain.sh@ 11af58b

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

toolchain.sh: Make archive unpacking compression-algorithm agnostic

  • Property mode set to 100755
File size: 15.1 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
55BINUTILS_VERSION="2.23.1"
56BINUTILS_RELEASE=""
57BINUTILS_PATCHES="toolchain-binutils-2.23.1.patch"
58GCC_VERSION="4.8.1"
59GCC_PATCHES="toolchain-gcc-4.8.1-targets.patch toolchain-gcc-4.8.1-headers.patch"
60GDB_VERSION="7.6.1"
61GDB_PATCHES="toolchain-gdb-7.6.1.patch"
62
63BASEDIR="`pwd`"
64SRCDIR="$(readlink -f $(dirname "$0"))"
65BINUTILS="binutils-${BINUTILS_VERSION}${BINUTILS_RELEASE}.tar.bz2"
66GCC="gcc-${GCC_VERSION}.tar.bz2"
67GDB="gdb-${GDB_VERSION}.tar.bz2"
68
69REAL_INSTALL=true
70USE_HELENOS_TARGET=false
71INSTALL_DIR="${BASEDIR}/PKG"
72
73#
74# Check if the library described in the argument
75# exists and has acceptable version.
76#
77check_dependency() {
78 DEPENDENCY="$1"
79 HEADER="$2"
80 BODY="$3"
81
82 FNAME="/tmp/conftest-$$"
83
84 echo "#include ${HEADER}" > "${FNAME}.c"
85 echo >> "${FNAME}.c"
86 echo "int main()" >> "${FNAME}.c"
87 echo "{" >> "${FNAME}.c"
88 echo "${BODY}" >> "${FNAME}.c"
89 echo " return 0;" >> "${FNAME}.c"
90 echo "}" >> "${FNAME}.c"
91
92 cc -c -o "${FNAME}.o" "${FNAME}.c" 2> "${FNAME}.log"
93 RC="$?"
94
95 if [ "$RC" -ne "0" ] ; then
96 echo " ${DEPENDENCY} not found, too old or compiler error."
97 echo " Please recheck manually the source file \"${FNAME}.c\"."
98 echo " The compilation of the toolchain is probably going to fail,"
99 echo " you have been warned."
100 echo
101 echo " ===== Compiler output ====="
102 cat "${FNAME}.log"
103 echo " ==========================="
104 echo
105 else
106 echo " ${DEPENDENCY} found"
107 rm -f "${FNAME}.log" "${FNAME}.o" "${FNAME}.c"
108 fi
109}
110
111check_dependecies() {
112 echo ">>> Basic dependency check"
113 check_dependency "GMP" "<gmp.h>" "${GMP_MAIN}"
114 check_dependency "MPFR" "<mpfr.h>" "${MPFR_MAIN}"
115 check_dependency "MPC" "<mpc.h>" "${MPC_MAIN}"
116 echo
117}
118
119check_error() {
120 if [ "$1" -ne "0" ]; then
121 echo
122 echo "Script failed: $2"
123
124 exit 1
125 fi
126}
127
128check_md5() {
129 FILE="$1"
130 SUM="$2"
131
132 COMPUTED="`md5sum "${FILE}" | cut -d' ' -f1`"
133 if [ "${SUM}" != "${COMPUTED}" ] ; then
134 echo
135 echo "Checksum of ${FILE} does not match."
136
137 exit 2
138 fi
139}
140
141show_usage() {
142 echo "Cross-compiler toolchain build script"
143 echo
144 echo "Syntax:"
145 echo " $0 [--no-install] [--helenos-target] <platform>"
146 echo
147 echo "Possible target platforms are:"
148 echo " amd64 AMD64 (x86-64, x64)"
149 echo " arm32 ARM"
150 echo " ia32 IA-32 (x86, i386)"
151 echo " ia64 IA-64 (Itanium)"
152 echo " mips32 MIPS little-endian 32b"
153 echo " mips32eb MIPS big-endian 32b"
154 echo " mips64 MIPS little-endian 64b"
155 echo " ppc32 32-bit PowerPC"
156 echo " ppc64 64-bit PowerPC"
157 echo " sparc32 SPARC V8"
158 echo " sparc64 SPARC V9"
159 echo " all build all targets"
160 echo " parallel same as 'all', but all in parallel"
161 echo " 2-way same as 'all', but 2-way parallel"
162 echo
163 echo "The toolchain is installed into directory specified by the"
164 echo "CROSS_PREFIX environment variable. If the variable is not"
165 echo "defined, /usr/local/cross/ is used as default."
166 echo
167 echo "If --no-install is present, the toolchain still uses the"
168 echo "CROSS_PREFIX as the target directory but the installation"
169 echo "copies the files into PKG/ subdirectory without affecting"
170 echo "the actual root file system. That is only useful if you do"
171 echo "not want to run the script under the super user."
172 echo
173 echo "The --helenos-target will build HelenOS-specific toolchain"
174 echo "(i.e. it will use *-helenos-* triplet instead of *-linux-*)."
175 echo "This toolchain is installed into /usr/local/cross-helenos by"
176 echo "default. The settings can be changed by setting environment"
177 echo "variable CROSS_HELENOS_PREFIX."
178 echo "Using the HelenOS-specific toolchain is still an experimental"
179 echo "feature that is not fully supported."
180 echo
181
182 exit 3
183}
184
185change_title() {
186 echo -en "\e]0;$1\a"
187}
188
189show_countdown() {
190 TM="$1"
191
192 if [ "${TM}" -eq 0 ] ; then
193 echo
194 return 0
195 fi
196
197 echo -n "${TM} "
198 change_title "${TM}"
199 sleep 1
200
201 TM="`expr "${TM}" - 1`"
202 show_countdown "${TM}"
203}
204
205show_dependencies() {
206 echo "IMPORTANT NOTICE:"
207 echo
208 echo "For a successful compilation and use of the cross-compiler"
209 echo "toolchain you need at least the following dependencies."
210 echo
211 echo "Please make sure that the dependencies are present in your"
212 echo "system. Otherwise the compilation process might fail after"
213 echo "a few seconds or minutes."
214 echo
215 echo " - SED, AWK, Flex, Bison, gzip, bzip2, Bourne Shell"
216 echo " - gettext, zlib, Texinfo, libelf, libgomp"
217 echo " - terminfo"
218 echo " - GNU Multiple Precision Library (GMP)"
219 echo " - GNU Make"
220 echo " - GNU tar"
221 echo " - GNU Coreutils"
222 echo " - GNU Sharutils"
223 echo " - MPFR"
224 echo " - MPC"
225 echo " - Parma Polyhedra Library (PPL)"
226 echo " - ClooG-PPL"
227 echo " - native C compiler, assembler and linker"
228 echo " - native C 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}" "33adb18c3048d057ac58d07a3f1adb38"
352 download_fetch "${GCC_SOURCE}" "${GCC}" "3b2386c114cd74185aa3754b58a79304"
353 download_fetch "${GDB_SOURCE}" "${GDB}" "fbc4dab4181e6e9937075b43a4ce2732"
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 "sparc32")
395 LINUX_TARGET="sparc-leon3-linux-gnu"
396 HELENOS_TARGET="sparc-leon3-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 echo ">>> Processing GDB (${PLATFORM})"
522 cd "${GDBDIR}"
523 check_error $? "Change directory failed."
524
525 change_title "GDB: configure (${PLATFORM})"
526 PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" ./configure \
527 "--target=${TARGET}" \
528 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
529 --enable-werror=no
530 check_error $? "Error configuring GDB."
531
532 change_title "GDB: make (${PLATFORM})"
533 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all
534 check_error $? "Error compiling GDB."
535
536 change_title "GDB: make (${PLATFORM})"
537 if $REAL_INSTALL; then
538 PATH="${PATH}:${PREFIX}/bin" make install
539 else
540 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install "DESTDIR=${INSTALL_DIR}"
541 fi
542 check_error $? "Error installing GDB."
543
544
545 cd "${BASEDIR}"
546 check_error $? "Change directory failed."
547
548 echo ">>> Cleaning up"
549 cleanup_dir "${WORKDIR}"
550
551 echo
552 echo ">>> Cross-compiler for ${TARGET} installed."
553}
554
555while [ "$#" -gt 1 ]; do
556 case "$1" in
557 --no-install)
558 REAL_INSTALL=false
559 shift
560 ;;
561 --helenos-target)
562 USE_HELENOS_TARGET=true
563 shift
564 ;;
565 *)
566 show_usage
567 ;;
568 esac
569done
570
571if [ "$#" -lt "1" ]; then
572 show_usage
573fi
574
575case "$1" in
576 amd64|arm32|ia32|ia64|mips32|mips32eb|mips64|ppc32|ppc64|sparc32|sparc64)
577 prepare
578 build_target "$1"
579 ;;
580 "all")
581 prepare
582 build_target "amd64"
583 build_target "arm32"
584 build_target "ia32"
585 build_target "ia64"
586 build_target "mips32"
587 build_target "mips32eb"
588 build_target "mips64"
589 build_target "ppc32"
590 build_target "ppc64"
591 build_target "sparc32"
592 build_target "sparc64"
593 ;;
594 "parallel")
595 prepare
596 build_target "amd64" &
597 build_target "arm32" &
598 build_target "ia32" &
599 build_target "ia64" &
600 build_target "mips32" &
601 build_target "mips32eb" &
602 build_target "mips64" &
603 build_target "ppc32" &
604 build_target "ppc64" &
605 build_target "sparc32" &
606 build_target "sparc64" &
607 wait
608 ;;
609 "2-way")
610 prepare
611 build_target "amd64" &
612 build_target "arm32" &
613 wait
614
615 build_target "ia32" &
616 build_target "ia64" &
617 wait
618
619 build_target "mips32" &
620 build_target "mips32eb" &
621 wait
622
623 build_target "mips64" &
624 build_target "ppc32" &
625 wait
626
627 build_target "ppc64" &
628 build_target "sparc32" &
629 wait
630
631 build_target "sparc64" &
632 wait
633 ;;
634 *)
635 show_usage
636 ;;
637esac
Note: See TracBrowser for help on using the repository browser.