cookutils view cross @ rev 831
Add doc/cookutils.fr.html
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Sat Sep 24 18:06:50 2016 +0200 (2016-09-24) |
parents | f2cd25cd9120 |
children | 3f0ca4492ec7 |
line source
1 #!/bin/sh
2 #
3 # Cross - Help build a cross toolchain on SliTaz.
4 #
5 # Copyright 2012-2015 (C) SliTaz GNU/Linux - BSD License
6 # Author: Christophe Lincoln <pankso@slitaz.org>
7 #
9 . /lib/libtaz.sh
11 [ -f "/etc/slitaz/cross.conf" ] && . /etc/slitaz/cross.conf
12 [ -f "cross.conf" ] && . ./cross.conf
15 # Handle --config=/path/to/cross.conf
17 [ "$config" ] && . $config
18 source="$WORK/source"
19 tools="$WORK/tools"
20 sysroot="$WORK/sysroot"
21 logdir="$WORK/log"
24 # Cross-tools tarballs
26 binutils_tarball="binutils-$BINUTILS_VERSION.tar.bz2"
27 linux_tarball="linux-$LINUX_VERSION.tar.xz"
28 glibc_tarball="glibc-$GLIBC_VERSION.tar.bz2"
29 eglibc_tarball="eglibc-$EGLIBC_VERSION.tar.bz2"
30 gcc_tarball="gcc-$GCC_VERSION.tar.bz2"
31 libtool_tarball="libtool-$LIBTOOL_VERSION.tar.gz"
34 # Cross-tools URLs
36 binutils_wget="http://ftp.gnu.org/gnu/binutils/$binutils_tarball"
37 linux_wget="http://www.kernel.org/pub/linux/kernel/v3.x/$linux_tarball"
38 glibc_wget="http://ftp.gnu.org/gnu/libc/$glibc_tarball"
39 eglibc_wget="http://mirror.slitaz.org/arm/src/$eglibc_tarball"
40 eglibc_svn="svn://svn.eglibc.org/branches/eglibc-2_14"
41 gcc_wget="http://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/$gcc_tarball"
42 libtool_wget="ftp://sunsite.cnlab-switch.ch/mirror/gnu/libtool/$libtool_tarball"
45 # Help and usage.
47 usage() {
48 cat <<EOT
50 Usage: $(basename $0) command --option
52 Commands:
53 howto Man[like] page and howto
54 info Display cross-tools info
55 testsuite Execute a small testsuite
56 [arch]-setup Setup build host environment
57 download Download necessary sources
58 show-log Show a package compile log
59 binutils Compile Binutils
60 linux-headers Install Kernel headers
61 gcc-static Compile GCC static
62 glibc Compile GNU Glibc library
63 eglibc Compile EGlibc libc library
64 gcc-final Compile final GCC
65 compile Compile everything at once
66 libtool Cross GNU Libtool (test in receipt LIBTOOL=)
67 clean Clean-up build environment
68 clean-tools Clean: $tools
69 gen-prebuilt Create a prebuilt toolchain archive
71 EOT
72 }
75 # Prebuilt README
77 prebuilt_readme() {
78 echo -n 'Creating toolchain README...'
79 cat >> $package/README <<EOT
81 SliTaz Prebuilt $ARCH cross toolchain
82 ================================================================================
83 Move this $ARCH cross compilation toolchain to /usr/cross then add tools
84 to your PATH environment and test the toolchain:
86 # mv $ARCH /cross
87 # export PATH=\$PATH:/cross/$ARCH/tools/bin
89 # echo 'int main() { return 0; }' > test.c
90 # $TARGET-gcc -v -o test.out test.c
91 # readelf -h test.out
93 ================================================================================
95 EOT
96 status
97 }
100 # Make sure we have all directories.
102 init_compile() {
103 unset CFLAGS CXXFLAGS
104 export LC_ALL=POSIX LANG=POSIX
105 export PATH=$PATH:$tools/bin
106 export CROSS_COMPILE=${TARGET}-
107 mkdir -p $source $logdir $sysroot $tools
108 echo "Tools prefix : --prefix=$tools "
109 echo "Target sysroot : --with-sysroot=$sysroot"
110 cd $source
111 }
114 # Some arch may need custom CFLAGS to build Glibc/Eglibc
116 init_cflags() {
117 case "$ARCH" in
118 arm|armv6) export CFLAGS="-O2 -march=armv6" ;;
119 armv6hf) export CFLAGS="-O2 -march=armv6j" ;;
120 armv7) export CFLAGS="-Os -march=armv7-a" ;;
121 esac
122 }
125 # Get source if not yet in $SRC.
127 download_src() {
128 mkdir -p $SRC; cd $SRC
129 [ -f "$binutils_tarball" ] || wget $binutils_wget
130 [ -f "$linux_tarball" ] || wget --no-check-certificate $linux_wget
131 [ -f "$glibc_tarball" ] || wget $glibc_wget
132 [ -f "$eglibc_tarball" ] || wget $eglibc_wget
133 [ -f "$gcc_tarball" ] || wget $gcc_wget
134 [ -f "$libtool_tarball" ] || wget $libtool_wget
135 }
138 # 1. Binutils
140 binutils() {
141 init_compile
142 rm -rf binutils-$BINUTILS_VERSION
143 echo "Extracting: $binutils_tarball"
144 tar -xjf $SRC/$binutils_tarball
145 echo "Configure: $BINUTILS_ARGS"
146 cd binutils-$BINUTILS_VERSION
147 ./configure \
148 --prefix=$tools \
149 --target=$TARGET \
150 --enable-plugins \
151 --enable-threads \
152 --enable-targets=$BUILD_SYSTEM \
153 --with-sysroot=$sysroot \
154 $BINUTILS_ARGS &&
155 make || exit 1
156 make install
157 echo "cross: binutils compiled on: $(date)"
158 }
161 # 2. Kernel headers could use CROSS_COMPILE but gcc is not yet built.
163 linux_headers() {
164 init_compile
165 if [ ! -d "linux-$LINUX_VERSION" ]; then
166 echo "Extracting: $linux_tarball"
167 tar -xJf $SRC/$linux_tarball
168 fi
169 case "$ARCH" in
170 armv6hf) KARCH='arm' ;;
171 *) KARCH="$ARCH" ;;
172 esac
173 rm -rf linux-headers
174 cd linux-$LINUX_VERSION
175 make CROSS_COMPILE="" mrproper
176 make ARCH=$KARCH headers_check
177 make ARCH=$KARCH headers_install \
178 INSTALL_HDR_PATH=$source/linux-headers
179 rm $source/linux-headers/include/.*install*
180 echo "Copying headers to: $sysroot/usr"
181 mkdir -p $sysroot/usr
182 cp -a $source/linux-headers/* $sysroot/usr
183 }
186 # 2.1 Glibc headers needed to compile x86_64 gcc-static.
188 glibc_headers() {
189 init_compile
190 echo "Extracting: $glibc_tarball"
191 tar -xjf $SRC/$glibc_tarball
192 rm -rf glibc-headers
193 mkdir glibc-headers; cd glibc-headers
194 libc_cv_forced_unwind=yes \
195 libc_cv_c_cleanup=yes \
196 ../glibc-$GLIBC_VERSION/configure \
197 --prefix=/usr \
198 --host=$TARGET \
199 --with-headers=$sysroot/usr/include \
200 --without-cvs \
201 --disable-sanity-checks \
202 --enable-kernel=2.6.32 &&
203 make -k install-headers install_root=$sysroot
204 # Fixes
205 mkdir -p $sysroot/usr/include/gnu
206 touch $sysroot/usr/include/gnu/stubs.h
208 # Fixe error: bits/stdio_lim.h not found
209 #cp bits/stdio_lim.h $sysroot/usr/include/bits
210 cp /usr/include/bits/stdio_lim.h $sysroot/usr/include/bits
211 }
214 # 3. GCC static (first pass)
216 gcc_static() {
217 init_compile
218 echo "Extracting: $gcc_tarball"
219 tar -xjf $SRC/$gcc_tarball
220 echo "Configure: $GCC_STATIC_ARGS"
221 rm -rf gcc-static
222 mkdir gcc-static; cd gcc-static
223 ../gcc-$GCC_VERSION/configure \
224 --prefix=$tools \
225 --libexec=$tools/lib \
226 --target=$TARGET \
227 --disable-shared \
228 --disable-threads \
229 --disable-libgomp \
230 --disable-libmudflap \
231 --disable-libssp \
232 --without-headers \
233 --with-newlib \
234 --with-sysroot=$sysroot \
235 $GCC_STATIC_ARGS &&
236 make all-gcc all-target-libgcc || exit 1
237 make install-gcc install-target-libgcc
238 echo "cross: gcc-static compiled on: $(date)"
239 }
242 # 4. GNU Glibc: TODO Improve ARM support
244 glibc() {
245 init_compile
246 echo "Extracting: $glibc_tarball"
247 tar -xjf $SRC/$glibc_tarball
248 echo "Configure: $GLIBC_ARGS"
249 # Some arch may need glibc-ports and custom CFLAGS
250 case "$ARCH" in
251 arm*)
252 export CFLAGS='-march=armv6 -O2'
253 [ -f "$SRC/glibc-ports-$GLIBC_VERSION.tar.bz2" ] || wget \
254 http://ftp.gnu.org/gnu/libc/glibc-ports-$GLIBC_VERSION.tar.bz2 \
255 -O $SRC/glibc-ports-$GLIBC_VERSION.tar.bz2 || exit 1
256 echo "Extracting: glibc-ports-$GLIBC_VERSION.tar.bz2"
257 rm -rf glibc-$GLIBC_VERSION/ports
258 tar -xjf $SRC/glibc-ports-$GLIBC_VERSION.tar.bz2
259 mv glibc-ports-$GLIBC_VERSION glibc-$GLIBC_VERSION/ports
260 libexec='/usr/lib/glibc' ;;
261 x86_64)
262 #export CFLAGS="-02 -march=generic -pipe"
263 ccflags='-m64'
264 libexec='/usr/lib64/glibc' ;;
265 esac
266 # Disable linking to libgcc_eh
267 cd glibc-$GLIBC_VERSION
268 cp Makeconfig Makeconfig.orig
269 sed -e 's/-lgcc_eh//g' Makeconfig.orig > Makeconfig
270 cd ..
271 echo "CFLAGS: $CFLAGS"
272 rm -rf glibc-build
273 mkdir -p glibc-build; cd glibc-build
274 BUILD_CC="gcc" \
275 CC="${TARGET}-gcc $ccflags" \
276 AR="${TARGET}-ar" \
277 RANLIB="${TARGET}-ranlib" \
278 libc_cv_forced_unwind=yes \
279 libc_cv_c_cleanup=yes \
280 ../glibc-$GLIBC_VERSION/configure \
281 --prefix=/usr \
282 --libexec=$libexec \
283 --host=$TARGET \
284 --with-headers=$sysroot/usr/include \
285 --with-binutils=$tools/bin \
286 --enable-kernel=2.6.32 \
287 $GLIBC_ARGS &&
288 make || exit 1
289 make install_root=$sysroot install
290 # Symlink lib64 to lib
291 case "$ARCH" in
292 x86_64)
293 rm -f $sysroot/lib $sysroot/usr/lib
294 cd $sysroot; ln -s lib64 lib
295 cd usr; ln -s lib64 lib ;;
296 esac
297 echo "cross: glibc compiled on: $(date)"
298 }
301 # 4. eglibc: always use --prefix=/usr
303 eglibc() {
304 init_compile
305 init_cflags
306 rm -rf eglibc-build eglibc-$EGLIBC_VERSION
307 if [ ! -f "$SRC/$eglibc_tarball" ]; then
308 echo "Missing: $SRC/$eglibc_tarball"
309 exit 1
310 fi
311 echo "Extracting: $eglibc_tarball"
312 tar -xjf $SRC/$eglibc_tarball || exit 1
313 case "$ARCH" in
314 arm*)
315 if [ ! -d "$source/eglibc-ports-$EGLIBC_VERSION" ]; then
316 echo "Cloning $eglibc_svn/ports"
317 svn co $eglibc_svn/ports eglibc-ports-$EGLIBC_VERSION >/dev/null
318 fi
319 cp -a eglibc-ports-$EGLIBC_VERSION eglibc-$EGLIBC_VERSION/ports
320 libexec='/usr/lib/eglibc' ;;
321 x86_64)
322 #export CFLAGS="-march=nocona -O2 -pipe"
323 ccflags='-m64'
324 libexec='/usr/lib64/eglibc' ;;
325 esac
326 # Disable linking to libgcc_eh
327 cd eglibc-$EGLIBC_VERSION
328 cp Makeconfig Makeconfig.orig
329 sed -e 's/-lgcc_eh//g' Makeconfig.orig > Makeconfig
330 cd ..
331 echo "CFLAGS: $CFLAGS"
332 mkdir -p eglibc-build; cd eglibc-build
333 # config.cache
334 cat > config.cache <<EOT
335 libc_cv_forced_unwind=yes
336 libc_cv_c_cleanup=yes
337 libc_cv_gnu89_inline=yes
338 EOT
339 BUILD_CC='gcc' \
340 CC="${TARGET}-gcc $ccflags" \
341 AR="${TARGET}-ar" \
342 RANLIB="${TARGET}-ranlib" \
343 ../eglibc-$EGLIBC_VERSION/configure \
344 --prefix=/usr \
345 --libexec=$libexec \
346 --host=$TARGET \
347 --with-headers=$sysroot/usr/include \
348 --with-binutils=$tools/bin \
349 --enable-kernel=2.6.32 \
350 --with-__thread \
351 --without-gd \
352 --without-cvs \
353 --cache-file=config.cache \
354 $EGLIBC_ARGS &&
355 make || exit 1
356 make install_root=$sysroot install || exit 1
357 # Sep files for packaging
358 make install_root=$source/eglibc-install install || exit 1
359 echo "cross: eglibc compiled on: $(date)"
360 }
363 # 5. GCC final
365 gcc_final() {
366 init_compile
367 if [ ! -d "gcc-$GCC_VERSION" ]; then
368 echo "Extracting: $gcc_tarball"
369 tar -xjf $SRC/$gcc_tarball
370 fi
371 echo "Configure: $GCC_FINAL_ARGS"
372 rm -rf gcc-build
373 mkdir -p gcc-build; cd gcc-build
374 AR=ar \
375 ../gcc-$GCC_VERSION/configure \
376 --prefix=$tools \
377 --libexec=$tools/lib \
378 --target=$TARGET \
379 --enable-shared \
380 --enable-c99 \
381 --enable-long-long \
382 --enable-__cxa_atexit \
383 --with-system-zlib \
384 --enable-plugin \
385 --disable-multilib \
386 --disable-libssp \
387 --disable-checking \
388 --disable-werror \
389 --with-pkgversion="SliTaz" \
390 --with-bugurl="http://bugs.slitaz.org/" \
391 --with-sysroot=$sysroot \
392 $GCC_FINAL_ARGS &&
393 make AS_FOR_TARGET="${TARGET}-as" \
394 LD_FOR_TARGET="${TARGET}-ld" || exit 1
395 make install
396 echo "cross: GCC final compiled on: $(date)"
397 }
400 # A cross libtool should avoid some shared libs path/format bugs
402 cross_libtool() {
403 init_compile
404 [ "$clean" ] && rm -rf libtool-${LIBTOOL_VERSION}
405 if [ ! -d "libtool-$LIBTOOL_VERSION" ]; then
406 echo "Extracting: $libtool_tarball"
407 tar -xzf $SRC/$libtool_tarball
408 fi
409 cd libtool-${LIBTOOL_VERSION}
410 ./configure \
411 --prefix=$tools \
412 --host=${TARGET} \
413 --program-prefix=${TARGET}- &&
414 make || exit 1
415 make install
416 echo "cross: Cross libtool compiled on: $(date)"
417 }
420 #
421 # Commands
422 #
424 case "$1" in
425 howto|man)
426 doc='/usr/share/doc/cookutils/cross.txt'
427 [ -f "$doc" ] && less -E $doc ;;
429 info)
430 init_compile
431 init_cflags
432 CC=${TARGET}-gcc
433 echo -e '\nCross Toolchain information'; separator
434 [ "$config" ] && echo "Config file : $config"
435 cat <<EOT
436 Target arch : $ARCH
437 C Compiler : $CC
438 CFLAGS : $CFLAGS
439 Build directory : $WORK
440 Tools prefix : $tools/bin
441 Arch sysroot : $sysroot
442 EOT
443 separator; newline
444 echo 'GCC version'; separator
445 if [ -x "$tools/bin/$CC" ]; then
446 $CC -v
447 else
448 echo 'No C compiler. To build a toolchain run: cross compile'
449 echo "Missing: $tools/bin/$CC"
450 fi
451 separator; newline ;;
453 testsuite)
454 init_compile
455 echo "[COMPILING] $TARGET-gcc -v -Wall -o test.out test.c" \
456 | tee $logdir/testsuite.log
457 echo 'int main() { return 0; }' > test.c
458 $TARGET-gcc -v -Wall -o test.out test.c 2>&1 | tee -a $logdir/testsuite.log
459 if [ -x /usr/bin/file ]; then
460 echo -e "\n[CHECKING] file test.out" | tee -a $logdir/testsuite.log
461 file test.out | tee -a $logdir/testsuite.log
462 fi
463 echo -e "\n[CHECKING] readelf -h test.out" | tee -a $logdir/testsuite.log
464 readelf -h test.out | tee -a $logdir/testsuite.log ;;
466 *setup)
467 data='/usr/share/cross'
468 arch=${1%-setup}
469 [ "$arch" == 'setup' ] && arch="arm"
471 newline; echo 'Checking: build system packages'
472 for pkg in slitaz-toolchain mpfr mpfr-dev gmp gmp-dev mpc-library \
473 gawk autoconf; do
474 if [ ! -d "/var/lib/tazpkg/installed/$pkg" ]; then
475 echo "Missing packages: $pkg"
476 if [ -x /usr/sbin/spk-add ]; then
477 spk-add $pkg
478 else
479 tazpkg -gi $pkg
480 fi
481 fi
482 done
483 echo "Getting $arch cross.conf"
484 cp -f ${data}/cross-${arch}.conf /etc/slitaz/cross.conf
485 cook ${arch}-setup
486 newline ;;
488 download)
489 download_src ;;
491 show-log)
492 pkg=$2
493 log=$logdir/$pkg.log
494 if [ ! -f "$log" ]; then
495 echo "No log file found for: $pkg"
496 exit 1
497 fi
498 less -E $log ;;
500 binutils)
501 rm -f $logdir/binutils.log
502 binutils 2>&1 | tee $logdir/binutils.log ;;
504 linux-headers)
505 linux_headers 2>&1 | tee $logdir/linux-headers.log ;;
507 glibc-headers)
508 glibc_headers 2>&1 | tee $logdir/glibc-headers.log ;;
510 gcc-static)
511 gcc_static 2>&1 | tee $logdir/gcc-static.log ;;
513 glibc)
514 glibc 2>&1 | tee $logdir/glibc.log ;;
516 eglibc)
517 eglibc 2>&1 | tee $logdir/eglibc.log ;;
519 gcc-final)
520 gcc_final 2>&1 | tee $logdir/gcc-final.log ;;
522 compile)
523 # Compile the full toolchain.
524 time=$(date +%s)
525 init_compile
526 echo "Compile start: $(date)" | tee $logdir/compile.log
527 download_src
528 binutils 2>&1 | tee $logdir/binutils.log
529 case "$ARCH" in
530 x86_64) glibc_headers 2>&1 | tee $logdir/glibc-headers.log ;;
531 esac
532 linux_headers 2>&1 | tee $logdir/linux-headers.log
533 gcc_static 2>&1 | tee $logdir/gcc-static.log
534 case "$ARCH" in
535 arm*) eglibc 2>&1 | tee $logdir/eglibc.log ;;
536 x86_64) glibc 2>&1 | tee $logdir/glibc.log ;;
537 esac
538 gcc_final 2>&1 | tee $logdir/gcc-final.log
539 newline
540 echo "Compile end : $(date)" | tee -a $logdir/compile.log
541 time=$(($(date +%s) - $time))
542 sec=$time
543 div=$(( ($time + 30) / 60))
544 [ "$div" != 0 ] && min="~ ${div}m"
545 echo "Build time : ${sec}s $min" | tee -a $logdir/compile.log
546 echo "" ;;
548 libtool)
549 cross_libtool 2>&1 | tee $logdir/libtool.log ;;
551 libhack)
552 # Some libxx.la files have libdir='/usr/lib' and make packages
553 # cross compilation fail. Some receipts may have got hacked to force
554 # use of libs in sysroot but 'cross libhack' should be preferred.
555 echo "Libdir: $sysroot/usr/lib"
556 for la in $(fgrep -l libdir= $sysroot/usr/lib/*.la 2>/dev/null); do
557 if fgrep -q "libdir='/usr/lib'" ${la}; then
558 echo "Cross fixing: $(basename $la)"
559 sed -i s"#libdir=.*#libdir='/cross/$ARCH/sysroot/usr/lib'#" ${la}
560 fi
561 done ;;
563 clean)
564 echo -n 'Removing all source files...'
565 rm -rf $WORK/source; status
566 [ "$log" ] && rm -f $WORK/log/*.log ;;
568 clean-tools)
569 # Remove crap :-)
570 init_compile
571 echo "Cleaning : $tools ($(du -sh $tools | awk '{print $1}'))"
572 for file in share/info share/man share/local; do
573 echo -n "Removing : $file"
574 rm -rf $tools/$file; status
575 done
576 echo -n "Stripping : shared libs and binaries"
577 find $tools/bin -type f -exec strip -s '{}' 2>/dev/null \;
578 find $tools/lib -name cc1* -exec strip -s '{}' 2>/dev/null \;
579 find $tools/lib -name lto* -exec strip -s '{}' 2>/dev/null \;
580 find $sysroot -name "*.so*" -exec ${TARGET}-strip -s '{}' 2>/dev/null \;
581 sleep 1; status
582 echo -n "Tools size : "; du -sh $tools | awk '{print $1}' ;;
584 gen-prebuilt)
585 # Create a prebuilt cross toolchain tarball.
586 init_compile
587 date=$(date "+%Y%m%d")
588 package="slitaz-$ARCH-toolchain-$date"
589 tarball="$package.tar.bz2"
590 cd /cross
591 mkdir -p $package/$ARCH || exit 1
592 newline
593 echo -n "Copying $ARCH to: $package"
594 cp -a $ARCH/tools $package/$ARCH
595 cp -a $ARCH/sysroot $package/$ARCH
596 status
597 prebuilt_readme
598 echo -n "Creating prebuilt $ARCH toolchain tarball..."
599 tar -cjf $tarball $package
600 status
601 rm -rf $package
602 size=$(du -sh $tarball | awk '{print $1}')
603 echo "Tarball path: $(pwd)/$tarball"
604 echo "Tarball size: $size"
605 newline ;;
607 *)
608 usage ;;
609 esac