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