cookutils view cross @ rev 480
cook: Fixed what needs sourcing.
author | Christopher Rogers <slaxemulator@gmail.com> |
---|---|
date | Mon Jun 11 12:13:37 2012 +0000 (2012-06-11) |
parents | 175bd828c332 |
children | a8797a6edd21 |
line source
1 #!/bin/sh
2 #
3 # Cross - Help build a cross toolchain on SliTaz.
4 #
5 # Copyright 2012 (C) SliTaz GNU/Linux - BSD License
6 # Author: Christophe Lincoln <pankso@slitaz.org>
7 #
8 . /lib/libtaz.sh
10 [ -f "/etc/slitaz/cross.conf" ] && . /etc/slitaz/cross.conf
11 [ -f "cross.conf" ] && . ./cross.conf
13 # Handle --config=/path/to/cross.conf
14 [ "$config" ] && . $config
15 source=$WORK/source
16 tools=$WORK/tools
17 sysroot=$WORK/sysroot
18 logdir=$WORK/log
20 # Help and usage.
21 usage() {
22 cat << EOT
24 Usage: $(basename $0) command --option
26 Commands:
27 howto Man alike and howto
28 info Display cross-tools info
29 testsuite Execute a small testsuite
30 check Check build host environment
31 download Download necessary sources
32 show-log Show a compile log
33 binutils Compile Binutils
34 linux-headers Install Kernel headers
35 gcc-static Compile GCC static
36 glibc Compile GNU Glibc
37 gcc-final Compile final GCC
38 compile Compile everything at once
39 clean Clean-up build environment
40 clean-tools Clean: $tools
41 gen-prebuilt Create a prebuilt toolchain archive
43 EOT
44 }
46 # Prebuilt README
47 prebuilt_readme() {
48 echo -n "Creating toolchain README..."
49 cat >> $package/README << EOT
51 SliTaz Prebuilt $ARCH cross toolchain
52 ================================================================================
53 Move this $ARCH cross compilation toolchain to /usr/cross then add tools
54 to your PATH environment and test the toolchain:
56 # mv $ARCH /cross
57 # export PATH=\$PATH:/cross/$ARCH/tools/bin
59 # echo 'int main() { return 0; }' > test.c
60 # $TARGET-gcc -v -o test.out test.c
61 # readelf -h test.out
63 ================================================================================
65 EOT
66 status
67 }
69 # Make sure we have all directories.
70 init_compile() {
71 unset CFLAGS CXXFLAGS
72 export LC_ALL=POSIX LANG=POSIX
73 export PATH=$PATH:$tools/bin
74 export CROSS_COMPILE=${TARGET}-
75 mkdir -p $source $logdir $sysroot $tools
76 echo "Tools prefix : --prefix=$tools "
77 echo "Target sysroot : --with-sysroot=$sysroot"
78 cd $source
79 }
81 # Get source if not yet in $SRC.
82 download_src() {
83 mkdir -p $SRC && cd $SRC
84 [ -f "$BINUTILS_TARBALL" ] || wget $BINUTILS_WGET
85 [ -f "$LINUX_TARBALL" ] || wget $LINUX_WGET
86 [ -f "$GLIBC_TARBALL" ] || wget $GLIBC_WGET
87 [ -f "$GCC_TARBALL" ] || wget $GCC_WGET
88 }
90 # 1. Binutils
91 binutils() {
92 init_compile
93 rm -rf binutils-$BINUTILS_VERSION
94 echo "Extracting: $BINUTILS_TARBALL"
95 tar xjf $SRC/$BINUTILS_TARBALL
96 echo "Configure: $BINUTILS_ARGS"
97 cd binutils-$BINUTILS_VERSION
98 ./configure \
99 --prefix=$tools \
100 --target=$TARGET \
101 --enable-plugins \
102 --enable-threads \
103 --enable-targets=$BUILD_SYSTEM \
104 --with-sysroot=$sysroot \
105 $BINUTILS_ARGS &&
106 make || exit 1
107 make install
108 echo "cross: binutils compiled on: $(date)"
109 }
111 # 2. Kernel headers could use CROSS_COMPILE but gcc is not yet built.
112 linux_headers() {
113 init_compile
114 if [ ! -d "linux-$LINUX_VERSION" ]; then
115 echo "Extracting: $LINUX_TARBALL"
116 tar xjf $SRC/$LINUX_TARBALL
117 fi
118 rm -rf linux-headers
119 cd linux-$LINUX_VERSION
120 make mrproper
121 make ARCH=$ARCH headers_check
122 make ARCH=$ARCH headers_install \
123 INSTALL_HDR_PATH=$source/linux-headers
124 rm $source/linux-headers/include/.*install*
125 echo "Copying headers to: $sysroot/usr"
126 cp -a $source/linux-headers/* $sysroot/usr
127 }
129 # 2.1 Glibc headers needed to compile x86_64 gcc-static.
130 glibc_headers() {
131 init_compile
132 echo "Extracting: $GLIBC_TARBALL"
133 tar xjf $SRC/$GLIBC_TARBALL
134 rm -rf glibc-headers
135 mkdir glibc-headers && cd glibc-headers
136 libc_cv_forced_unwind=yes \
137 libc_cv_c_cleanup=yes \
138 ../glibc-$GLIBC_VERSION/configure \
139 --prefix=/usr \
140 --host=$TARGET \
141 --with-headers=$sysroot/usr/include \
142 --without-cvs \
143 --disable-sanity-checks \
144 --enable-kernel=2.6.32 &&
145 make -k install-headers install_root=$sysroot
146 # Fixes
147 mkdir -p $sysroot/usr/include/gnu
148 touch $sysroot/usr/include/gnu/stubs.h
149 cp bits/stdio_lim.h $sysroot/usr/include/bits
150 }
152 # 3. GCC static (first pass)
153 gcc_static() {
154 init_compile
155 echo "Extracting: $GCC_TARBALL"
156 tar xjf $SRC/$GCC_TARBALL
157 echo "Configure: $GCC_STATIC_ARGS"
158 rm -rf gcc-static
159 mkdir gcc-static && cd gcc-static
160 ../gcc-$GCC_VERSION/configure \
161 --prefix=$tools \
162 --libexec=$tools/lib \
163 --target=$TARGET \
164 --disable-shared \
165 --disable-threads \
166 --disable-libgomp \
167 --disable-libmudflap \
168 --disable-libssp \
169 --without-headers \
170 --with-newlib \
171 --with-sysroot=$sysroot \
172 $GCC_STATIC_ARGS &&
173 make all-gcc all-target-libgcc || exit 1
174 make install-gcc install-target-libgcc
175 echo "cross: gcc-static compiled on: $(date)"
176 }
178 # 4. GNU Glibc
179 glibc() {
180 init_compile
181 echo "Extracting: $GLIBC_TARBALL"
182 tar xjf $SRC/$GLIBC_TARBALL
183 echo "Configure: $GLIBC_ARGS"
184 # Some arch may need glibc-ports and custom CFLAGS
185 case "$ARCH" in
186 arm)
187 export CFLAGS="-march=armv6 -O2"
188 [ -f "$SRC/glibc-ports-$GLIBC_VERSION.tar.bz2" ] || wget \
189 http://ftp.gnu.org/gnu/libc/glibc-ports-$GLIBC_VERSION.tar.bz2 \
190 -O $SRC/glibc-ports-$GLIBC_VERSION.tar.bz2 || exit 1
191 echo "Extracting: glibc-ports-$GLIBC_VERSION.tar.bz2"
192 rm -rf glibc-$GLIBC_VERSION/ports
193 tar xjf $SRC/glibc-ports-$GLIBC_VERSION.tar.bz2
194 mv glibc-ports-$GLIBC_VERSION glibc-$GLIBC_VERSION/ports
195 libexec=/usr/lib/glibc ;;
196 x86_64)
197 #export CFLAGS="-march=nocona -O2 -pipe"
198 ccflags="-m64"
199 libexec=/usr/lib64/glibc ;;
200 esac
201 # Disable linking to libgcc_eh
202 cd glibc-$GLIBC_VERSION
203 cp Makeconfig Makeconfig.orig
204 sed -e 's/-lgcc_eh//g' Makeconfig.orig > Makeconfig
205 cd ..
206 echo "CFLAGS: $CFLAGS"
207 rm -rf glibc-build
208 mkdir -p glibc-build && cd glibc-build
209 BUILD_CC="gcc" \
210 CC="${TARGET}-gcc $ccflags" \
211 AR="${TARGET}-ar" \
212 RANLIB="${TARGET}-ranlib" \
213 libc_cv_forced_unwind=yes \
214 libc_cv_c_cleanup=yes \
215 ../glibc-$GLIBC_VERSION/configure \
216 --prefix=/usr \
217 --libexec=$libexec \
218 --host=$TARGET \
219 --with-headers=$sysroot/usr/include \
220 --with-binutils=$tools/bin \
221 --enable-kernel=2.6.32 \
222 $GLIBC_ARGS &&
223 make || exit 1
224 make install_root=$sysroot install
225 # Symlink lib64 to lib
226 case "$ARCH" in
227 x86_64)
228 rm -f $sysroot/lib $sysroot/usr/lib
229 cd $sysroot && ln -s lib64 lib
230 cd usr && ln -s lib64 lib ;;
231 esac
232 echo "cross: glibc compiled on: $(date)"
233 }
235 # 4. Eglibc: always use --prefix=/usr
236 eglibc() {
237 init_compile
238 rm -rf eglibc-build eglibc-$EGLIBC_VERSION
239 echo "Extracting: $EGLIBC_TARBALL"
240 tar xjf $SRC/$EGLIBC_TARBALL
241 # Some arch may need glibc-ports and custom CFLAGS
242 case "$ARCH" in
243 arm)
244 export CFLAGS="-march=armv6 -O2"
245 if [ ! -d "$source/eglibc-ports-$EGLIBC_VERSION" ]; then
246 echo "Cloning $EGLIBC_WGET/ports"
247 svn co $EGLIBC_WGET/ports eglibc-ports-$EGLIBC_VERSION >/dev/null
248 fi
249 cp -a eglibc-ports-$EGLIBC_VERSION eglibc-$EGLIBC_VERSION/ports
250 libexec=/usr/lib/eglibc ;;
251 x86_64)
252 #export CFLAGS="-march=nocona -O2 -pipe"
253 ccflags="-m64"
254 libexec=/usr/lib64/eglibc ;;
255 esac
256 # Disable linking to libgcc_eh
257 cd eglibc-$EGLIBC_VERSION
258 cp Makeconfig Makeconfig.orig
259 sed -e 's/-lgcc_eh//g' Makeconfig.orig > Makeconfig
260 cd ..
261 mkdir -p eglibc-build && cd eglibc-build
262 # config.cache
263 cat > config.cache << EOT
264 libc_cv_forced_unwind=yes
265 libc_cv_c_cleanup=yes
266 libc_cv_gnu89_inline=yes
267 EOT
268 BUILD_CC="gcc" \
269 CC="${TARGET}-gcc $ccflags" \
270 AR="${TARGET}-ar" \
271 RANLIB="${TARGET}-ranlib" \
272 ../eglibc-$EGLIBC_VERSION/configure \
273 --prefix=/usr \
274 --libexec=$libexec \
275 --host=$TARGET \
276 --with-headers=$sysroot/usr/include \
277 --with-binutils=$tools/bin \
278 --enable-kernel=2.6.32 \
279 --with-__thread \
280 --without-gd \
281 --without-cvs \
282 --cache-file=config.cache \
283 $EGLIBC_ARGS &&
284 make || exit 1
285 make install_root=$sysroot install
286 # The rpc headers (RPC is no longer in eglibc <2.13)
287 #
288 #if [ "$EGLIBC_VERSION" -gt "2.13" ]; then
289 #rpcsvc = "bootparam_prot.x nlm_prot.x rstat.x \
290 #yppasswd.x klm_prot.x rex.x sm_inter.x mount.x \
291 #rusers.x spray.x nfs_prot.x rquota.x key_prot.x"
292 #cd sunrpc/rpcsvc
293 #for r in ${rpcsvc}; do
294 #h=$(echo $r|sed -e's,\.x$,.h,')
295 #rpcgen -h $r -o $h || echo "unable to generate header for $r"
296 #done
297 #fi
298 }
300 # 5. GCC final
301 gcc_final() {
302 init_compile
303 if [ ! -d "gcc-$GCC_VERSION" ]; then
304 echo "Extracting: $GCC_TARBALL"
305 tar xjf $SRC/$GCC_TARBALL
306 fi
307 echo "Configure: $GCC_FINAL_ARGS"
308 rm -rf gcc-build
309 mkdir -p gcc-build && cd gcc-build
310 AR=ar \
311 ../gcc-$GCC_VERSION/configure \
312 --prefix=$tools \
313 --libexec=$tools/lib \
314 --target=$TARGET \
315 --enable-shared \
316 --enable-c99 \
317 --enable-long-long \
318 --enable-__cxa_atexit \
319 --with-system-zlib \
320 --enable-plugin \
321 --disable-multilib \
322 --disable-libssp \
323 --disable-checking \
324 --disable-werror \
325 --with-pkgversion="SliTaz" \
326 --with-bugurl="https://bugs.slitaz.org/" \
327 --with-sysroot=$sysroot \
328 $GCC_FINAL_ARGS &&
329 make AS_FOR_TARGET="${TARGET}-as" \
330 LD_FOR_TARGET="${TARGET}-ld" || exit 1
331 make install
332 echo "cross: GCC final compiled on: $(date)"
333 }
335 #
336 # Commands
337 #
339 case "$1" in
340 howto|man)
341 doc=/usr/share/doc/cookutils/cross.txt
342 [ -f "$doc" ] && less -E $doc ;;
343 info)
344 init_compile
345 CC=${TARGET}-gcc
346 echo -e "\nCross Toolchain information" && separator
347 [ "$config" ] && echo "Config file : $config"
348 cat << EOT
349 Target arch : $ARCH
350 C Compiler : $CC
351 Build directory : $WORK
352 Tools prefix : $tools/bin
353 Arch sysroot : $sysroot
354 EOT
355 separator && echo ""
356 echo "GCC version" && separator
357 if [ -x "$tools/bin/$CC" ]; then
358 $CC -v
359 else
360 echo "No C compiler. To build a toolchain run: cross compile"
361 echo "Missing: $tools/bin/$CC"
362 fi
363 separator && echo "" ;;
364 testsuite)
365 init_compile
366 echo "[COMPILING] $TARGET-gcc -v -Wall -o test.out test.c" \
367 | tee $logdir/testsuite.log
368 echo 'int main() { return 0; }' > test.c
369 $TARGET-gcc -v -Wall -o test.out test.c 2>&1 | tee -a $logdir/testsuite.log
370 if [ -x /usr/bin/file ]; then
371 echo -e "\n[CHECKING] file test.out" | tee -a $logdir/testsuite.log
372 file test.out | tee -a $logdir/testsuite.log
373 fi
374 echo -e "\n[CHECKING] readelf -h test.out" | tee -a $logdir/testsuite.log
375 readelf -h test.out | tee -a $logdir/testsuite.log ;;
376 check)
377 echo "Checking: build system packages"
378 for pkg in slitaz-toolchain mpfr mpfr-dev gmp gmp-dev mpc-library \
379 gawk autoconf; do
380 if [ ! -d "/var/lib/tazpkg/installed/$pkg" ]; then
381 echo "Missing packages: $pkg"
382 if [ -x /usr/sbin/spk-add ]; then
383 spk-add $pkg
384 else
385 tazpkg -gi $pkg
386 fi
387 fi
388 done
389 echo "Using: --with-sysroot=$sysroot" ;;
390 download)
391 download_src ;;
392 show-log)
393 pkg=$2
394 log=$logdir/$pkg.log
395 if [ ! -f "$log" ]; then
396 echo "No log file found for: $pkg" && exit 1
397 fi
398 less -E $log ;;
399 binutils)
400 rm -f $logdir/binutils.log
401 binutils 2>&1 | tee $logdir/binutils.log ;;
402 linux-headers)
403 linux_headers 2>&1 | tee $logdir/linux-headers.log ;;
404 glibc-headers)
405 glibc_headers 2>&1 | tee $logdir/glibc-headers.log ;;
406 gcc-static)
407 gcc_static 2>&1 | tee $logdir/gcc-static.log ;;
408 glibc)
409 glibc 2>&1 | tee $logdir/glibc.log ;;
410 eglibc)
411 eglibc 2>&1 | tee $logdir/eglibc.log ;;
412 gcc-final)
413 gcc_final 2>&1 | tee $logdir/gcc-final.log ;;
414 compile)
415 # Compile the full toolchain.
416 time=$(date +%s)
417 init_compile
418 echo "Compile start: $(date)" | tee $logdir/compile.log
419 download_src
420 binutils 2>&1 | tee $logdir/binutils.log
421 case "$ARCH" in
422 x86_64) glibc_headers 2>&1 | tee $logdir/glibc-headers.log ;;
423 esac
424 gcc_static 2>&1 | tee $logdir/gcc-static.log
425 linux_headers 2>&1 | tee $logdir/linux-headers.log
426 case "$ARCH" in
427 arm) eglibc 2>&1 | tee $logdir/eglibc.log ;;
428 x86_64) glibc 2>&1 | tee $logdir/glibc.log ;;
429 esac
430 gcc_final 2>&1 | tee $logdir/gcc-final.log
431 echo ""
432 echo "Compile end : $(date)" | tee -a $logdir/compile.log
433 time=$(($(date +%s) - $time))
434 sec=$time
435 div=$(( ($time + 30) / 60))
436 [ "$div" != 0 ] && min="~ ${div}m"
437 echo "Build time : ${sec}s $min" | tee -a $logdir/compile.log
438 echo "" ;;
439 clean)
440 echo -n "Removing all source files..."
441 rm -rf $WORK/source && status
442 [ "$log" ] && rm -f $WORK/log/*.log ;;
443 clean-tools)
444 # Remove crap :-)
445 init_compile
446 echo "Cleaning : $tools ($(du -sh $tools | awk '{print $1}'))"
447 for file in share/info share/man share/local
448 do
449 echo -n "Removing : $file"
450 rm -rf $tools/$file && status
451 done
452 echo -n "Stripping : shared libs and binaries"
453 find $tools/bin -type f -exec strip -s '{}' 2>/dev/null \;
454 find $tools/lib -name cc1* -exec strip -s '{}' 2>/dev/null \;
455 find $tools/lib -name lto* -exec strip -s '{}' 2>/dev/null \;
456 find $sysroot -name "*.so*" -exec ${TARGET}-strip -s '{}' 2>/dev/null \;
457 sleep 1 && status
458 echo -n "Tools size : " && du -sh $tools | awk '{print $1}' ;;
459 gen-prebuilt)
460 # Create a prebuilt cross toolchain tarball.
461 init_compile
462 date=$(date "+%Y%m%d")
463 package="slitaz-$ARCH-toolchain-$date"
464 tarball="$package.tar.bz2"
465 cd /cross
466 mkdir -p $package/$ARCH || exit 1
467 echo ""
468 echo -n "Copying $ARCH to: $package"
469 cp -a $ARCH/tools $package/$ARCH
470 cp -a $ARCH/sysroot $package/$ARCH
471 status
472 prebuilt_readme
473 echo -n "Creating prebuilt $ARCH toolchain tarball..."
474 tar cjf $tarball $package
475 status
476 rm -rf $package
477 size=$(du -sh $tarball | awk '{print $1}')
478 echo "Tarball path: $(pwd)/$tarball"
479 echo "Tarball size: $size"
480 echo "" ;;
481 *)
482 usage ;;
483 esac