source: mainline/tools/toolchain.sh@ f3287e5

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since f3287e5 was f3287e5, checked in by Vojtech Horky <vojtechhorky@…>, 12 years ago

Mark HelenOS-specific toolchain as experimental

  • Property mode set to 100755
File size: 14.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
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.patch"
62
63BASEDIR="`pwd`"
64BINUTILS="binutils-${BINUTILS_VERSION}${BINUTILS_RELEASE}.tar.bz2"
65GCC="gcc-${GCC_VERSION}.tar.bz2"
66GDB="gdb-${GDB_VERSION}.tar.bz2"
67
68REAL_INSTALL=true
69USE_HELENOS_TARGET=false
70INSTALL_DIR="${BASEDIR}/PKG"
71
72#
73# Check if the library described in the argument
74# exists and has acceptable version.
75#
76check_dependency() {
77 DEPENDENCY="$1"
78 HEADER="$2"
79 BODY="$3"
80
81 FNAME="/tmp/conftest-$$"
82
83 echo "#include ${HEADER}" > "${FNAME}.c"
84 echo >> "${FNAME}.c"
85 echo "int main()" >> "${FNAME}.c"
86 echo "{" >> "${FNAME}.c"
87 echo "${BODY}" >> "${FNAME}.c"
88 echo " return 0;" >> "${FNAME}.c"
89 echo "}" >> "${FNAME}.c"
90
91 cc -c -o "${FNAME}.o" "${FNAME}.c" 2> "${FNAME}.log"
92 RC="$?"
93
94 if [ "$RC" -ne "0" ] ; then
95 echo " ${DEPENDENCY} not found, too old or compiler error."
96 echo " Please recheck manually the source file \"${FNAME}.c\"."
97 echo " The compilation of the toolchain is probably going to fail,"
98 echo " you have been warned."
99 echo
100 echo " ===== Compiler output ====="
101 cat "${FNAME}.log"
102 echo " ==========================="
103 echo
104 else
105 echo " ${DEPENDENCY} found"
106 rm -f "${FNAME}.log" "${FNAME}.o" "${FNAME}.c"
107 fi
108}
109
110check_dependecies() {
111 echo ">>> Basic dependency check"
112 check_dependency "GMP" "<gmp.h>" "${GMP_MAIN}"
113 check_dependency "MPFR" "<mpfr.h>" "${MPFR_MAIN}"
114 check_dependency "MPC" "<mpc.h>" "${MPC_MAIN}"
115 echo
116}
117
118check_error() {
119 if [ "$1" -ne "0" ]; then
120 echo
121 echo "Script failed: $2"
122
123 exit 1
124 fi
125}
126
127check_md5() {
128 FILE="$1"
129 SUM="$2"
130
131 COMPUTED="`md5sum "${FILE}" | cut -d' ' -f1`"
132 if [ "${SUM}" != "${COMPUTED}" ] ; then
133 echo
134 echo "Checksum of ${FILE} does not match."
135
136 exit 2
137 fi
138}
139
140show_usage() {
141 echo "Cross-compiler toolchain build script"
142 echo
143 echo "Syntax:"
144 echo " $0 [--no-install] [--helenos-target] <platform>"
145 echo
146 echo "Possible target platforms are:"
147 echo " amd64 AMD64 (x86-64, x64)"
148 echo " arm32 ARM"
149 echo " ia32 IA-32 (x86, i386)"
150 echo " ia64 IA-64 (Itanium)"
151 echo " mips32 MIPS little-endian 32b"
152 echo " mips32eb MIPS big-endian 32b"
153 echo " mips64 MIPS little-endian 64b"
154 echo " ppc32 32-bit PowerPC"
155 echo " ppc64 64-bit PowerPC"
156 echo " sparc64 SPARC V9"
157 echo " all build all targets"
158 echo " parallel same as 'all', but all in parallel"
159 echo " 2-way same as 'all', but 2-way parallel"
160 echo
161 echo "The toolchain is installed into directory specified by the"
162 echo "CROSS_PREFIX environment variable. If the variable is not"
163 echo "defined, /usr/local/cross/ is used as default."
164 echo
165 echo "If --no-install is present, the toolchain still uses the"
166 echo "CROSS_PREFIX as the target directory but the installation"
167 echo "copies the files into PKG/ subdirectory without affecting"
168 echo "the actual root file system. That is only useful if you do"
169 echo "not want to run the script under the super user."
170 echo
171 echo "The --helenos-target will build HelenOS-specific toolchain"
172 echo "(i.e. it will use *-helenos-* triplet instead of *-linux-*)."
173 echo "This toolchain is installed into /usr/local/cross-helenos by"
174 echo "default. The settings can be changed by setting environment"
175 echo "variable CROSS_HELENOS_PREFIX."
176 echo "Using the HelenOS-specific toolchain is still an experimental"
177 echo "feature that is not fully supported."
178 echo
179
180 exit 3
181}
182
183change_title() {
184 echo -en "\e]0;$1\a"
185}
186
187show_countdown() {
188 TM="$1"
189
190 if [ "${TM}" -eq 0 ] ; then
191 echo
192 return 0
193 fi
194
195 echo -n "${TM} "
196 change_title "${TM}"
197 sleep 1
198
199 TM="`expr "${TM}" - 1`"
200 show_countdown "${TM}"
201}
202
203show_dependencies() {
204 echo "IMPORTANT NOTICE:"
205 echo
206 echo "For a successful compilation and use of the cross-compiler"
207 echo "toolchain you need at least the following dependencies."
208 echo
209 echo "Please make sure that the dependencies are present in your"
210 echo "system. Otherwise the compilation process might fail after"
211 echo "a few seconds or minutes."
212 echo
213 echo " - SED, AWK, Flex, Bison, gzip, bzip2, Bourne Shell"
214 echo " - gettext, zlib, Texinfo, libelf, libgomp"
215 echo " - terminfo"
216 echo " - GNU Multiple Precision Library (GMP)"
217 echo " - GNU Make"
218 echo " - GNU tar"
219 echo " - GNU Coreutils"
220 echo " - GNU Sharutils"
221 echo " - MPFR"
222 echo " - MPC"
223 echo " - Parma Polyhedra Library (PPL)"
224 echo " - ClooG-PPL"
225 echo " - native C compiler, assembler and linker"
226 echo " - native C library with headers"
227 echo
228}
229
230download_fetch() {
231 SOURCE="$1"
232 FILE="$2"
233 CHECKSUM="$3"
234
235 if [ ! -f "${FILE}" ]; then
236 change_title "Downloading ${FILE}"
237 wget -c "${SOURCE}${FILE}"
238 check_error $? "Error downloading ${FILE}."
239 fi
240
241 check_md5 "${FILE}" "${CHECKSUM}"
242}
243
244source_check() {
245 FILE="$1"
246
247 if [ ! -f "${FILE}" ]; then
248 echo
249 echo "File ${FILE} not found."
250
251 exit 4
252 fi
253}
254
255cleanup_dir() {
256 DIR="$1"
257
258 if [ -d "${DIR}" ]; then
259 change_title "Removing ${DIR}"
260 echo " >>> Removing ${DIR}"
261 rm -fr "${DIR}"
262 fi
263}
264
265create_dir() {
266 DIR="$1"
267 DESC="$2"
268
269 change_title "Creating ${DESC}"
270 echo ">>> Creating ${DESC}"
271
272 mkdir -p "${DIR}"
273 test -d "${DIR}"
274 check_error $? "Unable to create ${DIR}."
275}
276
277check_dirs() {
278 OUTSIDE="$1"
279 BASE="$2"
280 ORIGINAL="`pwd`"
281
282 cd "${OUTSIDE}"
283 check_error $? "Unable to change directory to ${OUTSIDE}."
284 ABS_OUTSIDE="`pwd`"
285
286 cd "${BASE}"
287 check_error $? "Unable to change directory to ${BASE}."
288 ABS_BASE="`pwd`"
289
290 cd "${ORIGINAL}"
291 check_error $? "Unable to change directory to ${ORIGINAL}."
292
293 BASE_LEN="${#ABS_BASE}"
294 OUTSIDE_TRIM="${ABS_OUTSIDE:0:${BASE_LEN}}"
295
296 if [ "${OUTSIDE_TRIM}" == "${ABS_BASE}" ] ; then
297 echo
298 echo "CROSS_PREFIX cannot reside within the working directory."
299
300 exit 5
301 fi
302}
303
304unpack_tarball() {
305 FILE="$1"
306 DESC="$2"
307
308 change_title "Unpacking ${DESC}"
309 echo " >>> Unpacking ${DESC}"
310
311 tar -xjf "${FILE}"
312 check_error $? "Error unpacking ${DESC}."
313}
314
315patch_sources() {
316 PATCH_FILE="$1"
317 PATCH_STRIP="$2"
318 DESC="$3"
319
320 change_title "Patching ${DESC}"
321 echo " >>> Patching ${DESC} with ${PATCH_FILE}"
322
323 patch -t "-p${PATCH_STRIP}" <"$PATCH_FILE"
324 check_error $? "Error patching ${DESC}."
325}
326
327prepare() {
328 show_dependencies
329 check_dependecies
330 show_countdown 10
331
332 BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
333 GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
334 GDB_SOURCE="ftp://ftp.gnu.org/gnu/gdb/"
335
336 download_fetch "${BINUTILS_SOURCE}" "${BINUTILS}" "33adb18c3048d057ac58d07a3f1adb38"
337 download_fetch "${GCC_SOURCE}" "${GCC}" "3b2386c114cd74185aa3754b58a79304"
338 download_fetch "${GDB_SOURCE}" "${GDB}" "fbc4dab4181e6e9937075b43a4ce2732"
339}
340
341set_target_from_platform() {
342 case "$1" in
343 "amd64")
344 LINUX_TARGET="amd64-linux-gnu"
345 HELENOS_TARGET="amd64-helenos"
346 ;;
347 "arm32")
348 LINUX_TARGET="arm-linux-gnueabi"
349 HELENOS_TARGET="arm-helenos-gnueabi"
350 ;;
351 "ia32")
352 LINUX_TARGET="i686-pc-linux-gnu"
353 HELENOS_TARGET="i686-pc-helenos"
354 ;;
355 "ia64")
356 LINUX_TARGET="ia64-pc-linux-gnu"
357 HELENOS_TARGET="ia64-pc-helenos"
358 ;;
359 "mips32")
360 LINUX_TARGET="mipsel-linux-gnu"
361 HELENOS_TARGET="mipsel-helenos"
362 ;;
363 "mips32eb")
364 LINUX_TARGET="mips-linux-gnu"
365 HELENOS_TARGET="mips-helenos"
366 ;;
367 "mips64")
368 LINUX_TARGET="mips64el-linux-gnu"
369 HELENOS_TARGET="mips64el-helenos"
370 ;;
371 "ppc32")
372 LINUX_TARGET="ppc-linux-gnu"
373 HELENOS_TARGET="ppc-helenos"
374 ;;
375 "ppc64")
376 LINUX_TARGET="ppc64-linux-gnu"
377 HELENOS_TARGET="ppc64-helenos"
378 ;;
379 "sparc64")
380 LINUX_TARGET="sparc64-linux-gnu"
381 HELENOS_TARGET="sparc64-helenos"
382 ;;
383 *)
384 check_error 1 "No target known for $1."
385 ;;
386 esac
387}
388
389build_target() {
390 PLATFORM="$1"
391 # This sets the *_TARGET variables
392 set_target_from_platform "$PLATFORM"
393 if $USE_HELENOS_TARGET; then
394 TARGET="$HELENOS_TARGET"
395 else
396 TARGET="$LINUX_TARGET"
397 fi
398
399 WORKDIR="${BASEDIR}/${PLATFORM}"
400 BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
401 GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
402 OBJDIR="${WORKDIR}/gcc-obj"
403 GDBDIR="${WORKDIR}/gdb-${GDB_VERSION}"
404
405 if [ -z "${CROSS_PREFIX}" ] ; then
406 CROSS_PREFIX="/usr/local/cross"
407 fi
408 if [ -z "${CROSS_HELENOS_PREFIX}" ] ; then
409 CROSS_HELENOS_PREFIX="/usr/local/cross-helenos"
410 fi
411
412 if $USE_HELENOS_TARGET; then
413 PREFIX="${CROSS_HELENOS_PREFIX}/${PLATFORM}"
414 else
415 PREFIX="${CROSS_PREFIX}/${PLATFORM}"
416 fi
417
418 echo ">>> Downloading tarballs"
419 source_check "${BASEDIR}/${BINUTILS}"
420 source_check "${BASEDIR}/${GCC}"
421 source_check "${BASEDIR}/${GDB}"
422
423 echo ">>> Removing previous content"
424 $REAL_INSTALL && cleanup_dir "${PREFIX}"
425 cleanup_dir "${WORKDIR}"
426
427 $REAL_INSTALL && create_dir "${PREFIX}" "destination directory"
428 create_dir "${OBJDIR}" "GCC object directory"
429
430 check_dirs "${PREFIX}" "${WORKDIR}"
431
432 echo ">>> Unpacking tarballs"
433 cd "${WORKDIR}"
434 check_error $? "Change directory failed."
435
436 unpack_tarball "${BASEDIR}/${BINUTILS}" "binutils"
437 unpack_tarball "${BASEDIR}/${GCC}" "GCC"
438 unpack_tarball "${BASEDIR}/${GDB}" "GDB"
439
440 echo ">>> Applying patches"
441 for p in $BINUTILS_PATCHES; do
442 patch_sources "${BASEDIR}/${p}" 0 "binutils"
443 done
444 for p in $GCC_PATCHES; do
445 patch_sources "${BASEDIR}/${p}" 0 "GCC"
446 done
447 for p in $GDB_PATCHES; do
448 patch_sources "${BASEDIR}/${p}" 0 "GDB"
449 done
450
451 echo ">>> Processing binutils (${PLATFORM})"
452 cd "${BINUTILSDIR}"
453 check_error $? "Change directory failed."
454
455 change_title "binutils: configure (${PLATFORM})"
456 CFLAGS=-Wno-error ./configure \
457 "--target=${TARGET}" \
458 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
459 --disable-nls --disable-werror
460 check_error $? "Error configuring binutils."
461
462 change_title "binutils: make (${PLATFORM})"
463 make all
464 check_error $? "Error compiling binutils."
465
466 change_title "binutils: install (${PLATFORM})"
467 if $REAL_INSTALL; then
468 make install
469 else
470 make install "DESTDIR=${INSTALL_DIR}"
471 fi
472 check_error $? "Error installing binutils."
473
474
475 echo ">>> Processing GCC (${PLATFORM})"
476 cd "${OBJDIR}"
477 check_error $? "Change directory failed."
478
479 change_title "GCC: configure (${PLATFORM})"
480 PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" "${GCCDIR}/configure" \
481 "--target=${TARGET}" \
482 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
483 --with-gnu-as --with-gnu-ld --disable-nls --disable-threads \
484 --enable-languages=c,objc,c++,obj-c++ \
485 --disable-multilib --disable-libgcj --without-headers \
486 --disable-shared --enable-lto --disable-werror
487 check_error $? "Error configuring GCC."
488
489 change_title "GCC: make (${PLATFORM})"
490 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-gcc
491 check_error $? "Error compiling GCC."
492
493 change_title "GCC: install (${PLATFORM})"
494 if $REAL_INSTALL; then
495 PATH="${PATH}:${PREFIX}/bin" make install-gcc
496 else
497 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-gcc "DESTDIR=${INSTALL_DIR}"
498 fi
499 check_error $? "Error installing GCC."
500
501
502 echo ">>> Processing GDB (${PLATFORM})"
503 cd "${GDBDIR}"
504 check_error $? "Change directory failed."
505
506 change_title "GDB: configure (${PLATFORM})"
507 PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" ./configure \
508 "--target=${TARGET}" \
509 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-"
510 check_error $? "Error configuring GDB."
511
512 change_title "GDB: make (${PLATFORM})"
513 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all
514 check_error $? "Error compiling GDB."
515
516 change_title "GDB: make (${PLATFORM})"
517 if $REAL_INSTALL; then
518 PATH="${PATH}:${PREFIX}/bin" make install
519 else
520 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install "DESTDIR=${INSTALL_DIR}"
521 fi
522 check_error $? "Error installing GDB."
523
524
525 cd "${BASEDIR}"
526 check_error $? "Change directory failed."
527
528 echo ">>> Cleaning up"
529 cleanup_dir "${WORKDIR}"
530
531 echo
532 echo ">>> Cross-compiler for ${TARGET} installed."
533}
534
535while [ "$#" -gt 1 ]; do
536 case "$1" in
537 --no-install)
538 REAL_INSTALL=false
539 shift
540 ;;
541 --helenos-target)
542 USE_HELENOS_TARGET=true
543 shift
544 ;;
545 *)
546 show_usage
547 ;;
548 esac
549done
550
551if [ "$#" -lt "1" ]; then
552 show_usage
553fi
554
555case "$1" in
556 amd64|arm32|ia32|ia64|mips32|mips32eb|mips64|ppc32|ppc64|sparc64)
557 prepare
558 build_target "$1"
559 ;;
560 "all")
561 prepare
562 build_target "amd64"
563 build_target "arm32"
564 build_target "ia32"
565 build_target "ia64"
566 build_target "mips32"
567 build_target "mips32eb"
568 build_target "mips64"
569 build_target "ppc32"
570 build_target "ppc64"
571 build_target "sparc64"
572 ;;
573 "parallel")
574 prepare
575 build_target "amd64" &
576 build_target "arm32" &
577 build_target "ia32" &
578 build_target "ia64" &
579 build_target "mips32" &
580 build_target "mips32eb" &
581 build_target "mips64" &
582 build_target "ppc32" &
583 build_target "ppc64" &
584 build_target "sparc64" &
585 wait
586 ;;
587 "2-way")
588 prepare
589 build_target "amd64" &
590 build_target "arm32" &
591 wait
592
593 build_target "ia32" &
594 build_target "ia64" &
595 wait
596
597 build_target "mips32" &
598 build_target "mips32eb" &
599 wait
600
601 build_target "mips64" &
602 build_target "ppc32" &
603 wait
604
605 build_target "ppc64" &
606 build_target "sparc64" &
607 wait
608 ;;
609 *)
610 show_usage
611 ;;
612esac
Note: See TracBrowser for help on using the repository browser.