[doit] fix hard tab indent
[toolchains.git] / doit
blob3874b7e85b1f674f11e91bb1dce826e32562a730
1 #!/usr/bin/env bash
3 OS=`uname`
4 HOSTARCH=`uname -m`
5 PARALLEL=
6 FETCH=0
7 QUIET=0
8 STRIP=0
9 GNU_MIRROR=https://mirrors.kernel.org/gnu
10 # Get absolute path, will spawn a subshell then exit so our pwd is retained
11 SCRIPTROOT=$(cd "$(dirname $0)" && pwd)
12 PATCHES=$SCRIPTROOT/patches/
14 # Cause errors in pipes to return failure when necessary
15 set -o pipefail
17 function err() {
18 echo "doit: error during build"
19 if [ "$QUIET" = "1" ]; then
20 echo "doit: dumping last 50 lines of build log..."
21 echo "doit: see $OUTDIR/build.log for the full details"
22 tail -50 $OUTDIR/build.log
24 exit 1
27 trap err ERR
29 function help()
31 echo "Options"
32 echo " -a <arch list> architectures to build"
33 echo " example: -a 'arm' or -a 'arm i386 x86_64' for multiple"
34 echo " -c use compilation cache (ccache must be installed)"
35 echo " -f fetch source releases from upstream"
36 echo " -h|-? display this help message"
37 echo " -j<#> use <#> parallel workers to build"
38 echo " -o <dir> output directory"
39 echo " -q make the build quieter"
40 echo " -s strip the binaries"
41 exit 1
44 function log()
46 if [ "$QUIET" = "1" ]; then
47 "$@" >> $OUTDIR/build.log 2>&1
48 else
49 "$@" 2>&1 | tee -a $OUTDIR/build.log
53 function download-archive()
55 local name="$1"
56 local ver="$2"
57 local ext="$3"
58 local subdir="$4"
60 local filename="$name-$ver.tar.$ext"
62 if [ ! -f "$ARCHIVES/$filename" ]; then
63 echo "fetching $name-$ver"
64 log wget -P "$ARCHIVES" -N "$GNU_MIRROR/$name/$subdir$filename"
65 else
66 log echo "$filename already downloaded, skipping"
70 function extract-tool()
72 #echo "extract-tool " $1 $2 $3 $4
74 TARFILE=${1}-${2}.tar$3
75 TARGETDIR=${1}-${2}
76 HASH="$4"
77 PATCH="$5"
78 if [ -f ${TARGETDIR}/.extracted ]; then
79 log echo "$TARFILE already extracted into $TARGETDIR, skipping"
80 return 0
82 if [ ! -f $ARCHIVES/$TARFILE ]; then
83 log echo "error, missing $TARFILE"
84 exit 1
87 echo "checking $TARFILE integrity"
88 if [ "$(shasum -a 256 -b "$ARCHIVES/$TARFILE" | cut -f1 -d' ')" != "$HASH" ]; then
89 log echo "$TARFILE failed integrity check"
90 exit 1
93 echo extracting $TARFILE
94 pushd $OUTDIR
95 rm -rf $TARGETDIR
96 tar xf $ARCHIVES/$TARFILE || exit 1
98 if [ -n "$PATCH" ]; then
99 log echo patching $1
100 log patch -d $TARGETDIR -p1 < "$PATCH" || exit 1
103 touch $TARGETDIR/.extracted || exit 1
104 popd
107 MAKE=make
108 if [ "$OS" = "Linux" ]; then
109 COUNT=`grep processor /proc/cpuinfo | wc -l`
110 PARALLEL=-j`expr $COUNT + $COUNT`
112 if [ "$OS" = "Darwin" ]; then
113 PARALLEL=-j`sysctl -n hw.ncpu`
114 export CXXFLAGS="-fbracket-depth=1024 -O2"
116 if [ "$OS" = "FreeBSD" ]; then
117 PARALLEL=-j`sysctl -n hw.ncpu`
118 export CXXFLAGS="-fbracket-depth=1024 -O2"
119 MAKE=gmake
122 if [ "$HOSTARCH" = "amd64" ]; then
123 HOSTARCH=x86_64
126 if [ $# == "0" ]; then
127 help
130 while getopts a:cfhj:o:qs? arg
132 case $arg in
133 a ) ARCHES=$OPTARG ;;
134 c ) CCACHE=1 ;;
135 j ) PARALLEL="-j$OPTARG" ;;
136 f ) FETCH=1 ;;
137 o ) OUTDIR=$OPTARG ;;
138 q ) QUIET=1 ;;
139 s ) STRIP=1 ;;
140 h ) help ;;
141 ? ) help ;;
142 * ) echo "unrecognized option '$arg'" ; exit 1 ;;
143 esac
144 done
147 if [ -z "$ARCHES" ]; then
148 echo need to specify architectures to build
149 echo ie -a "arm sh"
150 exit 1
153 if [ -z "$OUTDIR" ]; then
154 OUTDIR=`pwd`
156 ARCHIVES=$OUTDIR/archives
158 if [ -z $(which makeinfo) ]; then
159 echo makeinfo not found. On debian/ubuntu this is provided by the texinfo package.
160 exit 1
163 export CC="cc"
164 export CXX="c++"
166 if [ "$CCACHE" = "1" ]; then
167 export CC="ccache $CC"
168 export CXX="ccache $CXX"
171 log date
172 log echo "ARCHES='$ARCHES' PARALLEL='$PARALLEL' FETCH='$FETCH' CCACHE='$CCACHE'"
173 # load GCCVER and BINVER
174 . toolvers
176 if [ "$FETCH" = "1" ]; then
177 download-archive binutils $BINVER bz2
178 download-archive gcc $GCCVER xz "gcc-$GCCVER/"
179 download-archive gdb $GDBVER xz
180 download-archive mpfr $MPFRVER bz2
181 download-archive mpc $MPCVER gz
182 download-archive gmp $GMPVER bz2
185 if [ ! -f $OUTDIR/.extracted-stamp ]; then
186 extract-tool binutils $BINVER .bz2 $BINHASH
187 extract-tool gcc $GCCVER .xz $GCCHASH $PATCHES/gcc-patch.txt
188 extract-tool gdb $GDBVER .xz $GDBHASH $PATCHES/gdb-patch.txt
189 extract-tool gmp $GMPVER .bz2 $GMPHASH
190 extract-tool mpc $MPCVER .gz $MPCHASH
191 extract-tool mpfr $MPFRVER .bz2 $MPFRHASH
192 touch $OUTDIR/.extracted-stamp
195 # link the last three libs into gcc
196 pushd $OUTDIR/gcc-$GCCVER
197 ln -sf ../gmp-$GMPVER gmp
198 ln -sf ../mpc-$MPCVER mpc
199 ln -sf ../mpfr-$MPFRVER mpfr
200 popd
202 for ARCH in $ARCHES; do
203 echo building for arch \"$ARCH\"
204 if [ "$ARCH" == "arm" ]; then
205 TARGET=arm-eabi
206 else
207 TARGET=$ARCH-elf
210 INSTALLPATH=$OUTDIR/$TARGET-$GCCVER-$OS-$HOSTARCH
211 BINBUILDPATH=$OUTDIR/build-binutils-$BINVER-$ARCH-$OS-$HOSTARCH
212 GCCBUILDPATH=$OUTDIR/build-gcc-$GCCVER-$ARCH-$OS-$HOSTARCH
213 GDBBUILDPATH=$OUTDIR/build-gdb-$GDBVER-$ARCH-$OS-$HOSTARCH
214 export PATH=$INSTALLPATH/bin:$PATH
216 # Building Binutils
217 if [ ! -f $BINBUILDPATH/built.txt ]; then
218 echo building binutils
219 mkdir -p $BINBUILDPATH
220 pushd $BINBUILDPATH
221 log ../binutils-$BINVER/configure --target=$TARGET --prefix=$INSTALLPATH --disable-werror
222 log $MAKE $PARALLEL
223 log $MAKE install
224 touch built.txt
225 popd
228 # Building GCC
229 if [ ! -f $GCCBUILDPATH/built.txt ]; then
230 echo building gcc
231 ARCH_OPTIONS=
232 if [ $ARCH == "arm" ]; then
233 ARCH_OPTIONS="--with-cpu=arm926ej-s --with-fpu=vfp"
236 mkdir -p $GCCBUILDPATH
237 pushd $GCCBUILDPATH
238 log ../gcc-$GCCVER/configure --target=$TARGET --prefix=$INSTALLPATH --enable-languages=c,c++ $ARCH_OPTIONS --disable-werror
239 log $MAKE all-gcc $PARALLEL
240 log $MAKE all-target-libgcc $PARALLEL
241 log $MAKE install-gcc
242 log $MAKE install-target-libgcc
243 touch built.txt
244 popd
247 if [ ! -f $GDBBUILDPATH/built.txt ]; then
248 case "$TARGET" in
249 aarch64-elf) EXTRA_TARGETS="--enable-targets=arm-eabi" ;;
250 *) EXTRA_TARGETS="" ;;
251 esac
253 echo building gdb
254 mkdir -p $GDBBUILDPATH
255 pushd $GDBBUILDPATH
256 log ../gdb-$GDBVER/configure --target=$TARGET --prefix=$INSTALLPATH --disable-werror $EXTRA_TARGETS
257 log $MAKE $PARALLEL
258 log $MAKE install
259 touch built.txt
260 popd
263 # Optionally strip the binaries
264 if [ "${STRIP}" = "1" ]; then
265 find "${INSTALLPATH}/bin" -type f -exec strip {} \;
266 for filename in $(find "${INSTALLPATH}/libexec" -type f); do
267 (file "${filename}" | grep -q ELF) && strip "${filename}"
268 done
270 done
272 echo all done