cookutils view cross @ rev 680

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