source: mainline/tools/toolchain.sh@ 5a01f7d

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 5a01f7d was 530f2de, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

toolchain.sh: Instead of depending on system libraries, use GCC's own facilities to download and build prerequisites.

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