cookutils view cross @ rev 1150

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