4 # Copyright (c) 2009 Martin Decky
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
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.
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.
32 #define GCC_GMP_VERSION_NUM(a, b, c) \
33 (((a) << 16L) | ((b) << 8) | (c))
35 #define GCC_GMP_VERSION \
36 GCC_GMP_VERSION_NUM(__GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL)
38 #if GCC_GMP_VERSION < GCC_GMP_VERSION_NUM(4, 3, 2)
44 #if MPFR_VERSION < MPFR_VERSION_NUM(2, 4, 2)
50 #if MPC_VERSION < MPC_VERSION_NUM(0, 8, 1)
56 isl_ctx_get_max_operations (isl_ctx_alloc ());
59 BINUTILS_VERSION
="2.28"
61 ## BINUTILS_PATCHES="toolchain-binutils-2.23.1.patch"
63 ## GCC_PATCHES="toolchain-gcc-4.8.1-targets.patch toolchain-gcc-4.8.1-headers.patch"
65 ## GDB_PATCHES="toolchain-gdb-7.6.1.patch"
69 SRCDIR
="$(readlink -f $(dirname "$0"))"
70 BINUTILS
="binutils-${BINUTILS_VERSION}${BINUTILS_RELEASE}.tar.bz2"
71 GCC
="gcc-${GCC_VERSION}.tar.bz2"
72 GDB
="gdb-${GDB_VERSION}.tar.gz"
73 ISL
="isl-${ISL_VERSION}.tar.bz2"
76 USE_HELENOS_TARGET
=false
80 # Check if the library described in the argument
81 # exists and has acceptable version.
88 FNAME
="/tmp/conftest-$$"
90 echo "#include ${HEADER}" > "${FNAME}.c"
92 echo "int main()" >> "${FNAME}.c"
93 echo "{" >> "${FNAME}.c"
94 echo "${BODY}" >> "${FNAME}.c"
95 echo " return 0;" >> "${FNAME}.c"
96 echo "}" >> "${FNAME}.c"
98 cc
$CFLAGS -c -o "${FNAME}.o" "${FNAME}.c" 2> "${FNAME}.log"
101 if [ "$RC" -ne "0" ] ; then
102 if [ "${DEPENDENCY}" == "isl" ]; then
105 echo " isl not found. Will be downloaded and built with GCC."
107 echo " ${DEPENDENCY} not found, too old or compiler error."
108 echo " Please recheck manually the source file \"${FNAME}.c\"."
109 echo " The compilation of the toolchain is probably going to fail,"
110 echo " you have been warned."
112 echo " ===== Compiler output ====="
114 echo " ==========================="
118 echo " ${DEPENDENCY} found"
119 rm -f "${FNAME}.log" "${FNAME}.o" "${FNAME}.c"
123 check_dependecies
() {
124 echo ">>> Basic dependency check"
125 check_dependency
"GMP" "<gmp.h>" "${GMP_MAIN}"
126 check_dependency
"MPFR" "<mpfr.h>" "${MPFR_MAIN}"
127 check_dependency
"MPC" "<mpc.h>" "${MPC_MAIN}"
128 check_dependency
"isl" "<isl/ctx.h>" "${ISL_MAIN}"
133 if [ "$1" -ne "0" ] ; then
135 echo "Script failed: $2"
145 COMPUTED
="`md5sum "${FILE}" | cut -d' ' -f1`"
146 if [ "${SUM}" != "${COMPUTED}" ] ; then
148 echo "Checksum of ${FILE} does not match."
155 echo "Cross-compiler toolchain build script"
158 echo " $0 [--no-install] [--helenos-target] <platform>"
160 echo "Possible target platforms are:"
161 echo " amd64 AMD64 (x86-64, x64)"
162 echo " arm32 ARM 32b"
163 echo " ia32 IA-32 (x86, i386)"
164 echo " ia64 IA-64 (Itanium)"
165 echo " mips32 MIPS little-endian 32b"
166 echo " mips32eb MIPS big-endian 32b"
167 echo " mips64 MIPS little-endian 64b"
168 echo " ppc32 PowerPC 32b"
169 echo " ppc64 PowerPC 64v"
170 echo " riscv64 RISC-V 64b"
171 echo " sparc64 SPARC V9"
172 echo " all build all targets"
173 echo " essential build only targets currently needed for HelenOS development"
174 echo " parallel same as 'all', but all in parallel"
175 echo " 2-way same as 'all', but 2-way parallel"
177 echo "The toolchain is installed into directory specified by the"
178 echo "CROSS_PREFIX environment variable. If the variable is not"
179 echo "defined, /usr/local/cross/ is used as default."
181 echo "If --no-install is present, the toolchain still uses the"
182 echo "CROSS_PREFIX as the target directory but the installation"
183 echo "copies the files into PKG/ subdirectory without affecting"
184 echo "the actual root file system. That is only useful if you do"
185 echo "not want to run the script under the super user."
187 echo "The --helenos-target will build HelenOS-specific toolchain"
188 echo "(i.e. it will use *-helenos-* triplet instead of *-linux-*)."
189 echo "This toolchain is installed into /usr/local/cross-helenos by"
190 echo "default. The settings can be changed by setting environment"
191 echo "variable CROSS_HELENOS_PREFIX."
192 echo "Using the HelenOS-specific toolchain is still an experimental"
193 echo "feature that is not fully supported."
206 if [ "${TM}" -eq 0 ] ; then
215 TM
="`expr "${TM}" - 1`"
216 show_countdown
"${TM}"
219 show_dependencies
() {
220 echo "IMPORTANT NOTICE:"
222 echo "For a successful compilation and use of the cross-compiler"
223 echo "toolchain you need at least the following dependencies."
225 echo "Please make sure that the dependencies are present in your"
226 echo "system. Otherwise the compilation process might fail after"
227 echo "a few seconds or minutes."
229 echo " - SED, AWK, Flex, Bison, gzip, bzip2, Bourne Shell"
230 echo " - gettext, zlib, Texinfo, libelf, libgomp"
231 echo " - GNU Make, Coreutils, Sharutils, tar"
232 echo " - GNU Multiple Precision Library (GMP)"
235 echo " - integer point manipulation library (isl)"
236 echo " - native C and C++ compiler, assembler and linker"
237 echo " - native C and C++ standard library with headers"
246 if [ ! -f "${FILE}" ] ; then
247 change_title
"Downloading ${FILE}"
248 wget
-c "${SOURCE}${FILE}" -O "${FILE}".part
249 check_error $?
"Error downloading ${FILE}."
251 mv "${FILE}".part
"${FILE}"
254 check_md5
"${FILE}" "${CHECKSUM}"
260 if [ ! -f "${FILE}" ] ; then
262 echo "File ${FILE} not found."
271 if [ -d "${DIR}" ] ; then
272 change_title
"Removing ${DIR}"
273 echo " >>> Removing ${DIR}"
282 change_title
"Creating ${DESC}"
283 echo ">>> Creating ${DESC}"
287 check_error $?
"Unable to create ${DIR}."
295 mkdir
-p "${OUTSIDE}"
298 check_error $?
"Unable to change directory to ${OUTSIDE}."
302 check_error $?
"Unable to change directory to ${BASE}."
306 check_error $?
"Unable to change directory to ${ORIGINAL}."
308 BASE_LEN
="${#ABS_BASE}"
309 OUTSIDE_TRIM
="${ABS_OUTSIDE:0:${BASE_LEN}}"
311 if [ "${OUTSIDE_TRIM}" == "${ABS_BASE}" ] ; then
313 echo "CROSS_PREFIX cannot reside within the working directory."
323 change_title
"Unpacking ${DESC}"
324 echo " >>> Unpacking ${DESC}"
337 check_error
1 "Don't know how to unpack ${DESC}."
340 check_error $?
"Error unpacking ${DESC}."
348 change_title
"Patching ${DESC}"
349 echo " >>> Patching ${DESC} with ${PATCH_FILE}"
351 patch -t "-p${PATCH_STRIP}" <"$PATCH_FILE"
352 check_error $?
"Error patching ${DESC}."
360 BINUTILS_SOURCE
="ftp://ftp.gnu.org/gnu/binutils/"
361 GCC_SOURCE
="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
362 GDB_SOURCE
="ftp://ftp.gnu.org/gnu/gdb/"
363 ISL_SOURCE
="http://isl.gforge.inria.fr/"
365 download_fetch
"${BINUTILS_SOURCE}" "${BINUTILS}" "9e8340c96626b469a603c15c9d843727"
366 download_fetch
"${GCC_SOURCE}" "${GCC}" "6bf56a2bca9dac9dbbf8e8d1036964a8"
367 download_fetch
"${GDB_SOURCE}" "${GDB}" "06c8f40521ed65fe36ebc2be29b56942"
370 download_fetch
"${ISL_SOURCE}" "${ISL}" "11436d6b205e516635b666090b94ab32"
374 set_target_from_platform
() {
377 LINUX_TARGET
="amd64-unknown-elf"
378 HELENOS_TARGET
="amd64-helenos"
381 LINUX_TARGET
="arm-linux-gnueabi"
382 HELENOS_TARGET
="arm-helenos-gnueabi"
385 LINUX_TARGET
="i686-pc-linux-gnu"
386 HELENOS_TARGET
="i686-pc-helenos"
389 LINUX_TARGET
="ia64-pc-linux-gnu"
390 HELENOS_TARGET
="ia64-pc-helenos"
393 LINUX_TARGET
="mipsel-linux-gnu"
394 HELENOS_TARGET
="mipsel-helenos"
397 LINUX_TARGET
="mips-linux-gnu"
398 HELENOS_TARGET
="mips-helenos"
401 LINUX_TARGET
="mips64el-linux-gnu"
402 HELENOS_TARGET
="mips64el-helenos"
405 LINUX_TARGET
="ppc-linux-gnu"
406 HELENOS_TARGET
="ppc-helenos"
409 LINUX_TARGET
="ppc64-linux-gnu"
410 HELENOS_TARGET
="ppc64-helenos"
413 LINUX_TARGET
="riscv64-unknown-linux-gnu"
414 HELENOS_TARGET
="riscv64-helenos"
417 LINUX_TARGET
="sparc64-linux-gnu"
418 HELENOS_TARGET
="sparc64-helenos"
421 check_error
1 "No target known for $1."
429 # This sets the *_TARGET variables
430 set_target_from_platform
"$PLATFORM"
431 if $USE_HELENOS_TARGET ; then
432 TARGET
="$HELENOS_TARGET"
434 TARGET
="$LINUX_TARGET"
437 WORKDIR
="${BASEDIR}/${TARGET}"
438 INSTALL_DIR
="${WORKDIR}/PKG"
439 BINUTILSDIR
="${WORKDIR}/binutils-${BINUTILS_VERSION}"
440 GCCDIR
="${WORKDIR}/gcc-${GCC_VERSION}"
441 ISLDIR
="${WORKDIR}/isl-${ISL_VERSION}"
442 OBJDIR
="${WORKDIR}/gcc-obj"
443 GDBDIR
="${WORKDIR}/gdb-${GDB_VERSION}"
445 if [ -z "${CROSS_PREFIX}" ] ; then
446 CROSS_PREFIX
="/usr/local/cross"
449 PREFIX
="${CROSS_PREFIX}/${TARGET}"
451 echo ">>> Downloading tarballs"
452 source_check
"${BASEDIR}/${BINUTILS}"
453 source_check
"${BASEDIR}/${GCC}"
454 source_check
"${BASEDIR}/${GDB}"
456 source_check
"${BASEDIR}/${ISL}"
459 echo ">>> Removing previous content"
460 cleanup_dir
"${WORKDIR}"
462 create_dir
"${OBJDIR}" "GCC object directory"
464 check_dirs
"${PREFIX}" "${WORKDIR}"
466 echo ">>> Unpacking tarballs"
468 check_error $?
"Change directory failed."
470 unpack_tarball
"${BASEDIR}/${BINUTILS}" "binutils"
471 unpack_tarball
"${BASEDIR}/${GCC}" "GCC"
472 unpack_tarball
"${BASEDIR}/${GDB}" "GDB"
474 unpack_tarball
"${BASEDIR}/${ISL}" "isl"
475 mv "${ISLDIR}" "${GCCDIR}"/isl
478 echo ">>> Applying patches"
479 for p
in $BINUTILS_PATCHES ; do
480 patch_sources
"${SRCDIR}/${p}" 0 "binutils"
482 for p
in $GCC_PATCHES ; do
483 patch_sources
"${SRCDIR}/${p}" 0 "GCC"
485 for p
in $GDB_PATCHES ; do
486 patch_sources
"${SRCDIR}/${p}" 0 "GDB"
489 echo ">>> Processing binutils (${PLATFORM})"
491 check_error $?
"Change directory failed."
493 change_title
"binutils: configure (${PLATFORM})"
494 CFLAGS
=-Wno-error .
/configure \
495 "--target=${TARGET}" \
496 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
497 --disable-nls --disable-werror --enable-gold \
498 --enable-deterministic-archives
499 check_error $?
"Error configuring binutils."
501 change_title
"binutils: make (${PLATFORM})"
503 check_error $?
"Error compiling binutils."
505 change_title
"binutils: install (${PLATFORM})"
506 make install "DESTDIR=${INSTALL_DIR}"
507 check_error $?
"Error installing binutils."
510 echo ">>> Processing GCC (${PLATFORM})"
512 check_error $?
"Change directory failed."
514 change_title
"GCC: configure (${PLATFORM})"
515 PATH
="$PATH:${INSTALL_DIR}/${PREFIX}/bin" "${GCCDIR}/configure" \
516 "--target=${TARGET}" \
517 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
518 --with-gnu-as --with-gnu-ld --disable-nls --disable-threads \
519 --enable-languages=c
,objc
,c
++,obj-c
++ \
520 --disable-multilib --disable-libgcj --without-headers \
521 --disable-shared --enable-lto --disable-werror
522 check_error $?
"Error configuring GCC."
524 change_title
"GCC: make (${PLATFORM})"
525 PATH
="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-gcc
526 check_error $?
"Error compiling GCC."
528 change_title
"GCC: install (${PLATFORM})"
529 PATH
="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-gcc "DESTDIR=${INSTALL_DIR}"
530 check_error $?
"Error installing GCC."
533 # No GDB support for RISC-V so far
534 if [ "$PLATFORM" != "riscv64" ] ; then
535 echo ">>> Processing GDB (${PLATFORM})"
537 check_error $?
"Change directory failed."
539 change_title
"GDB: configure (${PLATFORM})"
540 PATH
="$PATH:${INSTALL_DIR}/${PREFIX}/bin" .
/configure \
541 "--target=${TARGET}" \
542 "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" \
543 --enable-werror=no
--without-guile
544 check_error $?
"Error configuring GDB."
546 change_title
"GDB: make (${PLATFORM})"
547 PATH
="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all
548 check_error $?
"Error compiling GDB."
550 change_title
"GDB: make (${PLATFORM})"
551 PATH
="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install "DESTDIR=${INSTALL_DIR}"
552 check_error $?
"Error installing GDB."
555 # Symlink clang and lld to the install path.
556 CLANG
=`which clang 2> /dev/null || echo "/usr/bin/clang"`
557 LLD
=`which ld.lld 2> /dev/null || echo "/usr/bin/ld.lld"`
559 ln -s $CLANG "${INSTALL_DIR}/${PREFIX}/bin/${TARGET}-clang"
560 ln -s $LLD "${INSTALL_DIR}/${PREFIX}/bin/${TARGET}-ld.lld"
562 if $REAL_INSTALL ; then
563 echo ">>> Moving to the destination directory."
564 cleanup_dir
"${PREFIX}"
565 echo mv "${INSTALL_DIR}/${PREFIX}" "${PREFIX}"
566 mv "${INSTALL_DIR}/${PREFIX}" "${PREFIX}"
570 check_error $?
"Change directory failed."
572 echo ">>> Cleaning up"
573 cleanup_dir
"${WORKDIR}"
576 echo ">>> Cross-compiler for ${TARGET} installed."
579 while [ "$#" -gt 1 ] ; do
586 USE_HELENOS_TARGET
=true
595 if [ "$#" -lt "1" ] ; then
600 amd64|arm32|ia32|ia64|mips32|mips32eb|mips64|ppc32|ppc64|riscv64|sparc64
)
610 build_target
"mips32"
611 build_target
"mips32eb"
612 build_target
"mips64"
615 build_target
"riscv64"
616 build_target
"sparc64"
624 build_target
"mips32"
625 build_target
"mips32eb"
627 build_target
"sparc64"
631 build_target
"amd64" &
632 build_target
"arm32" &
633 build_target
"ia32" &
634 build_target
"ia64" &
635 build_target
"mips32" &
636 build_target
"mips32eb" &
637 build_target
"mips64" &
638 build_target
"ppc32" &
639 build_target
"ppc64" &
640 build_target
"riscv64" &
641 build_target
"sparc64" &
646 build_target
"amd64" &
647 build_target
"arm32" &
650 build_target
"ia32" &
651 build_target
"ia64" &
654 build_target
"mips32" &
655 build_target
"mips32eb" &
658 build_target
"mips64" &
659 build_target
"ppc32" &
662 build_target
"riscv64" &
663 build_target
"ppc64" &
666 build_target
"sparc64" &