source: mainline/tools/toolchain.sh@ aefdccd

Last change on this file since aefdccd was 113fb4f, checked in by Martin Decky <martin@…>, 4 months ago

Use tar to install toolchains into the destination

Using a pair of tar invocations (reading the source path by one
instance and piping the data to a second instance that writes into
the target path) has the benefit of better preserving certain file
attributes and especially the hard links (even if the source and the
target paths reside on different physical file systems).

Preserving the hard links is important to avoid needlessly wasting
storage space.

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