-
Notifications
You must be signed in to change notification settings - Fork 12
/
build-toolchain.sh
executable file
·340 lines (276 loc) · 7.34 KB
/
build-toolchain.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
#!/bin/bash
#
# OpeniBoot Toolchain builder
#
######### Setup Variables ###########
MYDIR="$PWD/`dirname $0`"
if uname | grep -iq "darwin"; then
declare -i CPU="$(sysctl -an hw.logicalcpu) +1"
else
declare -i CPU="$(cat /proc/cpuinfo | grep processor | wc -l) + 1"
fi
# Package Verions
PKG_NAMES[0]="binutils-2.17.tar.bz2"
PKG_NAMES[1]="gcc-4.1.1.tar.bz2"
PKG_NAMES[2]="newlib-1.14.0.tar.gz"
# Package URLs
PKG_URLS[0]="http://ftp.gnu.org/gnu/binutils/binutils-2.17.tar.bz2"
PKG_URLS[1]="http://ftp.gnu.org/gnu/gcc/gcc-4.1.1/gcc-4.1.1.tar.bz2"
PKG_URLS[2]="ftp://sourceware.org/pub/newlib/newlib-1.14.0.tar.gz"
# Package Patches
PATCH_GCC411_ARMELF="t-arm-elf.patch"
PATCH_NEWLIB_MAKEINFO="newlib-1.14.0-missing-makeinfo.patch"
if [ -z "$IPHONELINUXDEV" ]; then
PREFIX=/usr/local
if uname | grep -iq "darwin"; then
NEEDROOT=0
else
NEEDROOT=1
fi
else
PREFIX="$IPHONELINUXDEV"
NEEDROOT=0
fi
export PATH="$PATH:$PREFIX/bin"
# Check for different toolchain prefix
if [ -z "$TOOLCHAIN_PATH" ]; then
TOOLCHAIN_PATH="/tmp/ipl-toolchain"
fi
#LOG FILE
BUILDLOG=build.log
######### Helper functions ###########
usage() {
echo "Usage: ./build-toolchain.sh clean | make [stage]"
echo " if stage is included the build will begin from"
echo " there instead of from the beginning"
exit 1
}
# Holds the value of the current stage so that checkRet can echo it if it fails
CURRENT_STAGE=""
checkRet() {
# Die if return code != 0
if [ $? -ne 0 ]; then
if [ -n "$CURRENT_STAGE" ]; then
echo "$1 (stage: $CURRENT_STAGE)"
else
echo "$1"
fi
exit 1
fi
}
log() {
#execute command redirecting to the log file
"$@" >> $TOOLCHAIN_PATH/$BUILDLOG 2>&1
}
# Create log file
echo > $TOOLCHAIN_PATH/$BUILDLOG
STAGE=$2
STAGE_MSG=""
stage() {
# if $STAGE is not empty then only execute stage if it matches, clearing afterwards
# Sets $CURRENT_STAGE and executes the stage
if [ -n "$STAGE" -a "$STAGE" != "$1" ]; then
STAGE_MSG=""
return 0
fi
STAGE=""
CURRENT_STAGE="$1"
echo -en "$STAGE_MSG"
STAGE_MSG=""
stage_$1
}
#Stores a message that will be printed before the next stage
#if the next stage is run
msg() {
STAGE_MSG="$STAGE_MSG$@\n"
}
######### Quick tests ###########
if [ "$NEEDROOT" == "1" -a "$(id -u)" != "0" ]; then
echo "This script must be run as root" 1>&2
exit 1
fi
# check for make or clean
case "$1" in
make);; #good, move on through
clean)
echo "Removing temporary files"
rm -rf $TOOLCHAIN_PATH
checkRet "Failed to remove $TOOLCHAIN_PATH"
echo "Done"
exit 0
;;
*) #bad
usage
esac
######### Build stages ###########
stage_setup() {
# Create tmp dirs
echo "- Creating default directories"
cd $MYDIR
for dir in binutils-build gcc-build newlib-build src; do
mkdir -p $TOOLCHAIN_PATH/$dir
checkRet "failed to create $TOOLCHAIN_PATH/$dir"
echo " - $TOOLCHAIN_PATH/$dir"
done
# Copy patch files
cp $MYDIR/*.patch $TOOLCHAIN_PATH
}
stage_download() {
echo "- Downloading packages"
for pkg in 0 1 2; do
if [ -e $TOOLCHAIN_PATH/src/${PKG_NAMES[$pkg]} ];
then
echo " - ${PKG_NAMES[$pkg]} exists"
else
# Download to a .tmp file so that if the download is interupted
# we don't think that the file is downloaded
echo " - Downloading ${PKG_NAMES[$pkg]}"
log wget ${PKG_URLS[$pkg]} -O $TOOLCHAIN_PATH/src/${PKG_NAMES[$pkg]}.tmp
checkRet "Failed to retrive ${PKG_NAMES[$pkg]}"
mv $TOOLCHAIN_PATH/src/${PKG_NAMES[$pkg]}{.tmp,} # move file.tmp to file
echo " - ${PKG_NAMES[$pkg]} download complete"
fi
done
}
stage_binutils_extract() {
echo "- Extracting binutils"
cd $TOOLCHAIN_PATH
log tar -jxvf $TOOLCHAIN_PATH/src/${PKG_NAMES[0]}
checkRet "Failed to extract package ${PKG_NAMES[0]}"
}
stage_binutils_configure() {
echo "- Configuring binutils"
cd $TOOLCHAIN_PATH/binutils-build
log ../binutils-2.17/configure --target=arm-elf --prefix=$PREFIX \
--enable-interwork --enable-multilib --disable-werror
checkRet "Failed to configure binutils"
}
stage_binutils_build() {
echo "- Building binutils"
cd $TOOLCHAIN_PATH/binutils-build
log make -j$CPU all
checkRet "Failed to build binutils"
}
stage_binutils_install() {
echo "- Installing binutils"
cd $TOOLCHAIN_PATH/binutils-build
log make -j$CPU install
checkRet "Failed to install binutils"
}
stage_gcc_extract() {
echo "- Extracting GCC"
cd $TOOLCHAIN_PATH
log tar -jxvf $TOOLCHAIN_PATH/src/${PKG_NAMES[1]}
checkRet "Failed to extract package ${PKG_NAMES[1]}"
}
stage_newlib_extract() {
echo "- Extracting Newlib dependency for gcc"
cd $TOOLCHAIN_PATH
log tar -zxvf $TOOLCHAIN_PATH/src/${PKG_NAMES[2]}
checkRet "Failed to extract package ${PKG_NAMES[2]}"
}
stage_gcc_patch() {
echo "- Patching GCC for t-arm-elf"
cd $TOOLCHAIN_PATH
log patch -p0 < $PATCH_GCC411_ARMELF
checkRet "Failed to apply patch for t-arm-elf"
}
stage_gcc_configure() {
echo "- Configuring GCC"
cd $TOOLCHAIN_PATH/gcc-build
log ../gcc-4.1.1/configure --target=arm-elf --prefix=$PREFIX \
--enable-interwork --enable-multilib --with-fpu=vfp \
--enable-languages="c,c++" --with-newlib \
--with-headers=../newlib-1.14.0/newlib/libc/include --disable-werror
checkRet "Failed to configure gcc"
}
stage_gcc_build() {
echo "- Building GCC part 1"
cd $TOOLCHAIN_PATH/gcc-build
log make -j$CPU all-gcc
checkRet "Failed to build GCC part 1"
}
stage_gcc_install() {
echo "- Installing GCC part 1"
cd $TOOLCHAIN_PATH/gcc-build
log make -j$CPU install-gcc
checkRet "Failed to install GCC part 1"
}
stage_newlib_patch() {
echo "- Patching Newlib for makeinfo"
cd $TOOLCHAIN_PATH
log patch -p0 < $PATCH_NEWLIB_MAKEINFO
checkRet "Failed to apply patch for newlib makeinfo"
}
stage_newlib_configure() {
echo "- Configuring Newlib"
cd $TOOLCHAIN_PATH/newlib-build
log ../newlib-1.14.0/configure --target=arm-elf --prefix=$PREFIX \
--enable-interwork --enable-multilib --disable-werror
checkRet "Failed to configure newlib"
}
stage_makesymlink() {
echo "- Making arm-elf-cc symlink"
cd $TOOLCHAIN_PATH/newlib-build
ln -s arm-elf-gcc $PREFIX/bin/arm-elf-cc
checkRet "Failed to create symlink"
}
stage_newlib_build() {
echo "- Building Newlib"
cd $TOOLCHAIN_PATH/newlib-build
log make -j$CPU all
checkRet "Failed to build newlib"
}
stage_newlib_install() {
echo "- Installing NewLib"
cd $TOOLCHAIN_PATH/newlib-build
log make -j$CPU install
checkRet "Failed to install newlib"
}
stage_gcc_build2() {
echo "- Building GCC part 2"
cd $TOOLCHAIN_PATH/gcc-build
log make -j$CPU all
checkRet "Failed to build GCC part 2"
}
stage_gcc_install2() {
echo "- Installing GCC part 2"
cd $TOOLCHAIN_PATH/gcc-build
log make -j$CPU install
checkRet "Failed to install GCC part 2"
}
echo "======================================="
stage setup
stage download
msg "Starting Binutils"
stage binutils_extract
stage binutils_configure
stage binutils_build
stage binutils_install
msg "Completed Binutils"
msg "Starting GCC Part 1"
stage gcc_extract
stage newlib_extract
stage gcc_patch
stage gcc_configure
stage gcc_build
stage gcc_install
msg "Completed GCC Part 1"
msg "Starting Newlib"
stage newlib_patch
stage newlib_configure
stage makesymlink
stage newlib_build
stage newlib_install
msg "Completed NewLib"
msg "Starting GCC Part 2"
stage gcc_build2
stage gcc_install2
if [ -n "$STAGE" ]; then
echo "Error: unknown stage $STAGE"
usage
fi
echo "Completed GCC Part 2"
echo "Toolchain install successful"
echo "======================================="
echo