source: mainline/tools/toolchain.sh@ 0d1d0ea

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

Use more appropriate cross-compiler installation locations

The toolchain.sh and configure.sh scripts use the
$XDG_DATA_HOME/HelenOS/cross (i.e. $HOME/.local/share/HelenOS/cross)
location by default now. This allows the cross-compiler to be
installed without super user privileges and thus hopefully lowers the
entry barrier for newcomers.

To install the cross-compiler to a system-wide location, run the
toolchain.sh script with the —system-wide option. The default
system-wide location is /opt/HelenOS/cross now.

The configure.sh script falls back to /opt/HelenOS/cross and the
previously used /usr/local/cross. Thus recompiling an already
installed cross-compiler toolchain is not necessary.

The possibility to override the cross-compiler location using
$CROSS_PREFIX or having the cross-compiler available in $PATH
retained.

  • Property mode set to 100755
File size: 15.4 KB
Line 
1#!/bin/sh
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_GDB_GIT="https://github.com/HelenOS/binutils-gdb.git"
32
33BINUTILS_BRANCH="binutils-2_31_1-helenos"
34BINUTILS_VERSION="2.31.1"
35
36GDB_BRANCH="gdb-8_2-helenos"
37GDB_VERSION="8.2"
38
39GCC_GIT="https://github.com/HelenOS/gcc.git"
40GCC_BRANCH="8_2_0-helenos"
41GCC_VERSION="8.2.0"
42
43BASEDIR="$PWD"
44SRCDIR="$(readlink -f $(dirname "$0"))"
45
46SYSTEM_INSTALL=false
47REAL_INSTALL=true
48USE_HELENOS_TARGET=true
49
50check_error() {
51 if [ "$1" -ne "0" ] ; then
52 echo
53 echo "Script failed: $2"
54
55 exit 1
56 fi
57}
58
59show_usage() {
60 echo "HelenOS cross-compiler toolchain build script"
61 echo
62 echo "Syntax:"
63 echo " $0 [--system-wide] [--no-install] [--non-helenos-target] <platform>"
64 echo " $0 [--system-wide] --test-version [<platform>]"
65 echo
66 echo "Possible target platforms are:"
67 echo " amd64 AMD64 (x86-64, x64)"
68 echo " arm32 ARM 32b"
69 echo " arm64 AArch64"
70 echo " ia32 IA-32 (x86, i386)"
71 echo " ia64 IA-64 (Itanium)"
72 echo " mips32 MIPS little-endian 32b"
73 echo " mips32eb MIPS big-endian 32b"
74 echo " ppc32 PowerPC 32b"
75 echo " riscv64 RISC-V 64b"
76 echo " sparc64 SPARC V9"
77 echo " all build all targets"
78 echo " essential build only targets currently needed for HelenOS development"
79 echo " parallel same as 'all', but all in parallel"
80 echo " 2-way same as 'all', but 2-way parallel"
81 echo
82 echo "The toolchain target installation directory is determined by matching"
83 echo "the first of the following conditions:"
84 echo
85 echo " (1) If the \$CROSS_PREFIX environment variable is set, then it is"
86 echo " used as the target installation directory."
87 echo " (2) If the --system-wide option is used, then /opt/HelenOS/cross"
88 echo " is used as the target installation directory. This usually"
89 echo " requires running this script with super user privileges."
90 echo " (3) In other cases, \$XDG_DATA_HOME/HelenOS/cross is used as the"
91 echo " target installation directory. If the \$XDG_DATA_HOME environment"
92 echo " variable is not set, then the default value of \$HOME/.local/share"
93 echo " is assumed."
94 echo
95 echo "If the --no-install option is used, the toolchain still uses the"
96 echo "target installation directory as determined above, but the files"
97 echo "are actually copied into the PKG/ subdirectory during the installation"
98 echo "without affecting the actual target file system. This might be useful"
99 echo "when preparing a system-wide installation, but avoiding running this"
100 echo "script under the super user."
101 echo
102 echo "The --non-helenos-target option will build non-HelenOS-specific"
103 echo "toolchain (i.e. it will use *-linux-* triplet instead of *-helenos)."
104 echo "Using this toolchain for building HelenOS is not supported."
105 echo
106 echo "The --test-version mode tests the currently installed version of the"
107 echo "toolchain."
108
109 exit 3
110}
111
112set_cross_prefix() {
113 if [ -z "$CROSS_PREFIX" ] ; then
114 if $SYSTEM_INSTALL ; then
115 CROSS_PREFIX="/opt/HelenOS/cross"
116 else
117 if [ -z "$XDG_DATA_HOME" ] ; then
118 XDG_DATA_HOME="$HOME/.local/share"
119 fi
120 CROSS_PREFIX="$XDG_DATA_HOME/HelenOS/cross"
121 fi
122 fi
123}
124
125test_version() {
126 set_cross_prefix
127
128 echo "HelenOS cross-compiler toolchain build script"
129 echo
130 echo "Testing the version of the installed software in $CROSS_PREFIX"
131 echo
132
133 if [ -z "$1" ] || [ "$1" = "all" ] ; then
134 PLATFORMS='amd64 arm32 arm64 ia32 ia64 mips32 mips32eb ppc32 riscv64 sparc64'
135 else
136 PLATFORMS="$1"
137 fi
138
139 for PLATFORM in $PLATFORMS ; do
140 set_target_from_platform "$PLATFORM"
141 PREFIX="${CROSS_PREFIX}/bin/${HELENOS_TARGET}"
142
143 echo "== $PLATFORM =="
144 test_app_version "Binutils" "ld" "GNU ld (.*) \([.0-9]*\)" "$BINUTILS_VERSION"
145 test_app_version "GCC" "gcc" "gcc version \([.0-9]*\)" "$GCC_VERSION"
146 test_app_version "GDB" "gdb" "GNU gdb (.*)[[:space:]]\+\([.0-9]*\)" "$GDB_VERSION"
147 done
148}
149
150test_app_version() {
151 PKGNAME="$1"
152 APPNAME="$2"
153 REGEX="$3"
154 INS_VERSION="$4"
155
156 APP="${PREFIX}-${APPNAME}"
157 if [ ! -e $APP ]; then
158 echo "- $PKGNAME is missing"
159 else
160 VERSION=`${APP} -v 2>&1 | sed -n "s:^${REGEX}.*:\1:p"`
161
162 if [ -z "$VERSION" ]; then
163 echo "- $PKGNAME Unexpected output"
164 return 1
165 fi
166
167 if [ "$INS_VERSION" = "$VERSION" ]; then
168 echo "+ $PKGNAME is up-to-date ($INS_VERSION)"
169 else
170 echo "- $PKGNAME ($VERSION) is outdated ($INS_VERSION)"
171 fi
172 fi
173}
174
175change_title() {
176 printf "\e]0;$1\a"
177}
178
179show_countdown() {
180 TM="$1"
181
182 if [ "${TM}" -eq 0 ] ; then
183 echo
184 return 0
185 fi
186
187 printf "${TM} "
188 change_title "${TM}"
189 sleep 1
190
191 TM="`expr "${TM}" - 1`"
192 show_countdown "${TM}"
193}
194
195show_dependencies() {
196 set_cross_prefix
197
198 echo "HelenOS cross-compiler toolchain build script"
199 echo
200 echo "Installing software to $CROSS_PREFIX"
201 echo
202 echo
203 echo "IMPORTANT NOTICE:"
204 echo
205 echo "For a successful compilation and use of the cross-compiler"
206 echo "toolchain you need at least the following dependencies."
207 echo
208 echo "Please make sure that the dependencies are present in your"
209 echo "system. Otherwise the compilation process might fail after"
210 echo "a few seconds or minutes."
211 echo
212 echo " - SED, AWK, Flex, Bison, gzip, bzip2, Bourne Shell"
213 echo " - gettext, zlib, Texinfo, libelf, libgomp"
214 echo " - GNU Make, Coreutils, Sharutils, tar"
215 echo " - native C and C++ compiler, assembler and linker"
216 echo " - native C and C++ standard library with headers"
217 echo
218}
219
220cleanup_dir() {
221 DIR="$1"
222
223 if [ -d "${DIR}" ] ; then
224 change_title "Removing ${DIR}"
225 echo " >>> Removing ${DIR}"
226 rm -fr "${DIR}"
227 fi
228}
229
230create_dir() {
231 DIR="$1"
232 DESC="$2"
233
234 change_title "Creating ${DESC}"
235 echo ">>> Creating ${DESC}"
236
237 mkdir -p "${DIR}"
238 test -d "${DIR}"
239 check_error $? "Unable to create ${DIR}."
240}
241
242check_dirs() {
243 OUTSIDE="$1"
244 BASE="$2"
245 ORIGINAL="$PWD"
246
247 cd "${BASE}"
248 check_error $? "Unable to change directory to ${BASE}."
249 ABS_BASE="$PWD"
250 cd "${ORIGINAL}"
251 check_error $? "Unable to change directory to ${ORIGINAL}."
252
253 mkdir -p "${OUTSIDE}"
254 cd "${OUTSIDE}"
255 check_error $? "Unable to change directory to ${OUTSIDE}."
256
257 while [ "${#PWD}" -gt "${#ABS_BASE}" ]; do
258 cd ..
259 done
260
261 if [ "$PWD" = "$ABS_BASE" ]; then
262 echo
263 echo "CROSS_PREFIX cannot reside within the working directory."
264
265 exit 5
266 fi
267
268 cd "${ORIGINAL}"
269 check_error $? "Unable to change directory to ${ORIGINAL}."
270}
271
272prepare() {
273 show_dependencies
274 show_countdown 10
275
276 mkdir -p "${BASEDIR}/downloads"
277 cd "${BASEDIR}/downloads"
278 check_error $? "Change directory failed."
279
280 change_title "Downloading sources"
281 echo ">>> Downloading sources"
282 git clone --depth 1 -b "$BINUTILS_BRANCH" "$BINUTILS_GDB_GIT" "binutils-$BINUTILS_VERSION"
283 git clone --depth 1 -b "$GDB_BRANCH" "$BINUTILS_GDB_GIT" "gdb-$GDB_VERSION"
284 git clone --depth 1 -b "$GCC_BRANCH" "$GCC_GIT" "gcc-$GCC_VERSION"
285
286 # If the directory already existed, pull upstream changes.
287 git -C "binutils-$BINUTILS_VERSION" pull
288 git -C "gdb-$GDB_VERSION" pull
289 git -C "gcc-$GCC_VERSION" pull
290
291 change_title "Downloading GCC prerequisites"
292 echo ">>> Downloading GCC prerequisites"
293 cd "gcc-${GCC_VERSION}"
294 ./contrib/download_prerequisites
295 cd ..
296}
297
298set_target_from_platform() {
299 case "$1" in
300 "arm32")
301 GNU_ARCH="arm"
302 ;;
303 "arm64")
304 GNU_ARCH="aarch64"
305 ;;
306 "ia32")
307 GNU_ARCH="i686"
308 ;;
309 "mips32")
310 GNU_ARCH="mipsel"
311 ;;
312 "mips32eb")
313 GNU_ARCH="mips"
314 ;;
315 "ppc32")
316 GNU_ARCH="ppc"
317 ;;
318 *)
319 GNU_ARCH="$1"
320 ;;
321 esac
322
323 HELENOS_TARGET="${GNU_ARCH}-helenos"
324
325 case "$1" in
326 "arm32")
327 LINUX_TARGET="${GNU_ARCH}-linux-gnueabi"
328 ;;
329 *)
330 LINUX_TARGET="${GNU_ARCH}-linux-gnu"
331 ;;
332 esac
333}
334
335build_target() {
336 PLATFORM="$1"
337
338 # This sets the *_TARGET variables
339 set_target_from_platform "$PLATFORM"
340 if $USE_HELENOS_TARGET ; then
341 TARGET="$HELENOS_TARGET"
342 else
343 TARGET="$LINUX_TARGET"
344 fi
345
346 WORKDIR="${BASEDIR}/${TARGET}"
347 INSTALL_DIR="${BASEDIR}/PKG"
348 BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
349 GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
350 GDBDIR="${WORKDIR}/gdb-${GDB_VERSION}"
351
352 # This sets the CROSS_PREFIX variable
353 set_cross_prefix
354
355 if [ -z "$JOBS" ] ; then
356 JOBS="`nproc`"
357 fi
358
359 PREFIX="${CROSS_PREFIX}"
360
361 echo ">>> Removing previous content"
362 cleanup_dir "${WORKDIR}"
363 mkdir -p "${WORKDIR}"
364 check_dirs "${PREFIX}" "${WORKDIR}"
365
366 if $USE_HELENOS_TARGET ; then
367 change_title "Creating build sysroot"
368 echo ">>> Creating build sysroot"
369 mkdir -p "${WORKDIR}/sysroot/include"
370 mkdir "${WORKDIR}/sysroot/lib"
371 ARCH="$PLATFORM"
372 if [ "$ARCH" = "mips32eb" ]; then
373 ARCH=mips32
374 fi
375
376 cp -r -L -t "${WORKDIR}/sysroot/include" \
377 ${SRCDIR}/../abi/include/* \
378 ${SRCDIR}/../uspace/lib/c/arch/${ARCH}/include/* \
379 ${SRCDIR}/../uspace/lib/c/include/*
380 check_error $? "Failed to create build sysroot."
381 fi
382
383
384 echo ">>> Processing binutils (${PLATFORM})"
385 mkdir -p "${BINUTILSDIR}"
386 cd "${BINUTILSDIR}"
387 check_error $? "Change directory failed."
388
389 change_title "binutils: configure (${PLATFORM})"
390 CFLAGS="-Wno-error -fcommon" "${BASEDIR}/downloads/binutils-${BINUTILS_VERSION}/configure" \
391 "--target=${TARGET}" \
392 "--prefix=${PREFIX}" \
393 "--program-prefix=${TARGET}-" \
394 --disable-nls \
395 --disable-werror \
396 --enable-gold \
397 --enable-deterministic-archives \
398 --disable-gdb \
399 --with-sysroot
400 check_error $? "Error configuring binutils."
401
402 change_title "binutils: make (${PLATFORM})"
403 make all -j$JOBS
404 check_error $? "Error compiling binutils."
405
406 change_title "binutils: install (${PLATFORM})"
407 make install "DESTDIR=${INSTALL_DIR}"
408 check_error $? "Error installing binutils."
409
410
411 echo ">>> Processing GCC (${PLATFORM})"
412 mkdir -p "${GCCDIR}"
413 cd "${GCCDIR}"
414 check_error $? "Change directory failed."
415
416 if $USE_HELENOS_TARGET ; then
417 SYSROOT=--with-sysroot --with-build-sysroot="${WORKDIR}/sysroot"
418 else
419 SYSROOT=--without-headers
420 fi
421
422 change_title "GCC: configure (${PLATFORM})"
423 PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" "${BASEDIR}/downloads/gcc-${GCC_VERSION}/configure" \
424 "--target=${TARGET}" \
425 "--prefix=${PREFIX}" \
426 "--program-prefix=${TARGET}-" \
427 --with-gnu-as \
428 --with-gnu-ld \
429 --disable-nls \
430 --enable-languages=c,c++,go \
431 --enable-lto \
432 --disable-shared \
433 --disable-werror \
434 $SYSROOT
435 check_error $? "Error configuring GCC."
436
437 change_title "GCC: make (${PLATFORM})"
438 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-gcc -j$JOBS
439 check_error $? "Error compiling GCC."
440
441 if $USE_HELENOS_TARGET ; then
442 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-target-libgcc -j$JOBS
443 check_error $? "Error compiling libgcc."
444 # TODO: libatomic and libstdc++ need some extra care
445 # PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-target-libatomic -j$JOBS
446 # check_error $? "Error compiling libatomic."
447 # PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-target-libstdc++-v3 -j$JOBS
448 # check_error $? "Error compiling libstdc++."
449 fi
450
451 change_title "GCC: install (${PLATFORM})"
452 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-gcc "DESTDIR=${INSTALL_DIR}"
453 if $USE_HELENOS_TARGET ; then
454 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-target-libgcc "DESTDIR=${INSTALL_DIR}"
455 # PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-target-libatomic "DESTDIR=${INSTALL_DIR}"
456 # PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-target-libstdc++-v3 "DESTDIR=${INSTALL_DIR}"
457 fi
458 check_error $? "Error installing GCC."
459
460
461 echo ">>> Processing GDB (${PLATFORM})"
462 mkdir -p "${GDBDIR}"
463 cd "${GDBDIR}"
464 check_error $? "Change directory failed."
465
466 change_title "GDB: configure (${PLATFORM})"
467 CFLAGS="-fcommon" PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" "${BASEDIR}/downloads/gdb-${GDB_VERSION}/configure" \
468 "--target=${TARGET}" \
469 "--prefix=${PREFIX}" \
470 "--program-prefix=${TARGET}-" \
471 --enable-werror=no
472 check_error $? "Error configuring GDB."
473
474 change_title "GDB: make (${PLATFORM})"
475 PATH="${PATH}:${PREFIX}/bin:${INSTALL_DIR}/${PREFIX}/bin" make all-gdb -j$JOBS
476 check_error $? "Error compiling GDB."
477
478 change_title "GDB: make (${PLATFORM})"
479 PATH="${PATH}:${INSTALL_DIR}/${PREFIX}/bin" make install-gdb "DESTDIR=${INSTALL_DIR}"
480 check_error $? "Error installing GDB."
481
482 # Symlink clang and lld to the install path.
483 CLANG="`which clang 2> /dev/null || echo "/usr/bin/clang"`"
484 LLD="`which ld.lld 2> /dev/null || echo "/usr/bin/ld.lld"`"
485
486 ln -s $CLANG "${INSTALL_DIR}/${PREFIX}/bin/${TARGET}-clang"
487 ln -s $LLD "${INSTALL_DIR}/${PREFIX}/bin/${TARGET}-ld.lld"
488
489 if $REAL_INSTALL ; then
490 echo ">>> Moving to the destination directory."
491 cp -r -t "${PREFIX}" "${INSTALL_DIR}/${PREFIX}/"*
492 fi
493
494 cd "${BASEDIR}"
495 check_error $? "Change directory failed."
496
497 echo ">>> Cleaning up"
498 cleanup_dir "${WORKDIR}"
499
500 echo
501 echo ">>> Cross-compiler for ${TARGET} installed."
502}
503
504while [ "$#" -gt 1 ] ; do
505 case "$1" in
506 --system-wide)
507 SYSTEM_INSTALL=true
508 shift
509 ;;
510 --test-version)
511 test_version "$2"
512 exit
513 ;;
514 --no-install)
515 REAL_INSTALL=false
516 shift
517 ;;
518 --non-helenos-target)
519 USE_HELENOS_TARGET=false
520 shift
521 ;;
522 *)
523 show_usage
524 ;;
525 esac
526done
527
528if [ "$#" -lt "1" ] ; then
529 show_usage
530fi
531
532case "$1" in
533 --test-version)
534 test_version
535 exit
536 ;;
537 amd64|arm32|arm64|ia32|ia64|mips32|mips32eb|ppc32|riscv64|sparc64)
538 prepare
539 build_target "$1"
540 ;;
541 "all")
542 prepare
543 build_target "amd64"
544 build_target "arm32"
545 build_target "arm64"
546 build_target "ia32"
547 build_target "ia64"
548 build_target "mips32"
549 build_target "mips32eb"
550 build_target "ppc32"
551 build_target "riscv64"
552 build_target "sparc64"
553 ;;
554 "essential")
555 prepare
556 build_target "amd64"
557 build_target "arm32"
558 build_target "arm64"
559 build_target "ia32"
560 build_target "ia64"
561 build_target "mips32"
562 build_target "mips32eb"
563 build_target "ppc32"
564 build_target "sparc64"
565 ;;
566 "parallel")
567 prepare
568 build_target "amd64" &
569 build_target "arm32" &
570 build_target "arm64" &
571 build_target "ia32" &
572 build_target "ia64" &
573 build_target "mips32" &
574 build_target "mips32eb" &
575 build_target "ppc32" &
576 build_target "riscv64" &
577 build_target "sparc64" &
578 wait
579 ;;
580 "2-way")
581 prepare
582 build_target "amd64" &
583 build_target "arm32" &
584 wait
585
586 build_target "arm64" &
587 build_target "ia32" &
588 wait
589
590 build_target "ia64" &
591 build_target "mips32" &
592 wait
593
594 build_target "mips32eb" &
595 build_target "ppc32" &
596 wait
597
598 build_target "riscv64" &
599 build_target "sparc64" &
600 wait
601 ;;
602 *)
603 show_usage
604 ;;
605esac
Note: See TracBrowser for help on using the repository browser.