cookutils annotate cross @ rev 421

cook, cross, *.conf: improve cross compilation and small clean
author Christophe Lincoln <pankso@slitaz.org>
date Sat May 19 04:47:53 2012 +0200 (2012-05-19)
parents 9c322a61167d
children b2edbfaef132
rev   line source
pankso@361 1 #!/bin/sh
pankso@361 2 #
pankso@361 3 # Cross - Help build a cross toolchain on SliTaz.
pankso@361 4 #
pankso@361 5 # Copyright 2012 (C) SliTaz GNU/Linux - BSD License
pankso@361 6 # Author: Christophe Lincoln <pankso@slitaz.org>
pankso@361 7 #
pankso@361 8 . /lib/libtaz.sh
pankso@370 9
pankso@370 10 [ -f "/etc/slitaz/cross.conf" ] && . /etc/slitaz/cross.conf
pankso@370 11 [ -f "cross.conf" ] && . ./cross.conf
pankso@361 12
pankso@374 13 # Handle --config=/path/to/cross.conf
pankso@374 14 [ "$config" ] && . $config
pankso@412 15 source=$WORK/source
pankso@412 16 logdir=$WORK/log
pankso@412 17 install=$WORK/install
pankso@374 18
pankso@361 19 # Help and usage.
pankso@361 20 usage() {
pankso@361 21 cat << EOT
pankso@361 22
pankso@361 23 Usage: $(basename $0) command --option
pankso@361 24
pankso@361 25 Commands:
pankso@361 26 howto Man alike and howto
paul@382 27 info Display cross-tools info
pankso@361 28 testsuite Execute a small testsuite
pankso@421 29 check Check build host environment
pankso@361 30 download Download necessary sources
pankso@361 31 show-log Show a compile log
pankso@361 32 binutils Compile Binutils
pankso@421 33 linux-headers Install Kernel headers
pankso@361 34 gcc-static Compile GCC static
pankso@361 35 glibc Compile GNU Glibc
pankso@361 36 gcc-final Compile final GCC
pankso@361 37 busybox Cross compile Busybox
pankso@361 38 compile Compile everything at once
pankso@419 39 clean Clean-up build environment
pankso@419 40 clean-tools Clean: $PREFIX
pankso@419 41 gen-prebuilt Create an prebuilt toolchain archive
pankso@361 42
pankso@361 43 EOT
pankso@361 44 }
pankso@361 45
pankso@420 46 # Prebuilt README
pankso@420 47 prebuilt_readme() {
pankso@420 48 echo -n "Creating toolchain README..."
pankso@420 49 cat >> $package/README << EOT
pankso@420 50
pankso@420 51 SliTaz Prebuilt $ARCH cross toolchain
pankso@420 52 ================================================================================
pankso@420 53 Move this $ARCH cross compilation toolchain to /usr/cross then add tools
pankso@420 54 to your PATH environment and test the toolchain:
pankso@420 55
pankso@420 56 # mv $ARCH /usr/cross
pankso@420 57 # export PATH=\$PATH:/usr/cross/$ARCH/bin
pankso@420 58
pankso@420 59 # echo 'int main() { return 0; }' > test.c
pankso@420 60 # $TARGET-gcc -v -o test.out test.c
pankso@420 61 # readelf -h test.out
pankso@420 62
pankso@420 63 ================================================================================
pankso@420 64
pankso@420 65 EOT
pankso@420 66 status
pankso@420 67 }
pankso@420 68
pankso@361 69 # Make sure we have all directories.
pankso@361 70 init_compile() {
pankso@361 71 export LC_ALL=POSIX LANG=POSIX
pankso@403 72 [ "$SYSROOT" ] || export PATH=$PATH:$PREFIX/bin
pankso@400 73 export CROSS_COMPILE=${TARGET}-
pankso@361 74 mkdir -p $source $logdir $install
pankso@361 75 cd $source
pankso@361 76 }
pankso@361 77
pankso@361 78 # Get source if not yet in $SRC.
pankso@361 79 download_src() {
pankso@361 80 mkdir -p $SRC && cd $SRC
pankso@421 81 [ -f "$BINUTILS_TARBALL" ] || wget $BINUTILS_WGET
pankso@421 82 [ -f "$LINUX_TARBALL" ] || wget $LINUX_WGET
pankso@421 83 [ -f "$GLIBC_TARBALL" ] || wget $GLIBC_WGET
pankso@421 84 [ -f "$GCC_TARBALL" ] || wget $GCC_WGET
pankso@421 85 [ -f "$BUSYBOX_TARBALL" ] || wget $BUSYBOX_WGET
pankso@421 86 [ -f "$PKGCONFIG_TARBALL" ] || wget $PKGCONFIG_WGET
pankso@361 87 }
pankso@361 88
pankso@403 89 # Use sysroot or not ?
pankso@403 90 check_sysroot() {
pankso@403 91 if [ "$SYSROOT" ]; then
pankso@403 92 PREFIX=/usr
pankso@403 93 HDR_PATH=$SYSROOT/usr
pankso@403 94 sysroot="--with-sysroot=$SYSROOT"
pankso@421 95 echo "Configure: $sysroot"
pankso@403 96 else
pankso@421 97 HDR_PATH=$PREFIX/usr
pankso@421 98 fi
pankso@421 99 }
pankso@421 100
pankso@421 101 # Work around to fix GCC include search path
pankso@421 102 #
pankso@421 103 # GCC include search path is: $PREFIX/$TARGET/include, so make sure it
pankso@421 104 # is a symlink to default: $PREFIX/usr/include
pankso@421 105 #
pankso@421 106 # Glibc install headers in: $PREFIX/include, move them to usr/include
pankso@421 107 # if needed. After when we cross compile packages with cook we have
pankso@421 108 # to install build dependencies using --root=$CROSS_PREFIX and so
pankso@421 109 # default include dir is: $PREFIX/usr/include ($PREFIX is the root
pankso@421 110 # of our cross environment.
pankso@421 111 #
pankso@421 112 check_include() {
pankso@421 113 cd $PREFIX
pankso@421 114 echo "Checking: $PREFIX"
pankso@421 115 if ! readlink include >/dev/null; then
pankso@421 116 echo "Creating symlink: usr/include include"
pankso@421 117 cp -a include usr && rm -rf include
pankso@421 118 ln -s usr/include include
pankso@421 119 fi
pankso@421 120 cd $PREFIX/$TARGET
pankso@421 121 echo "Checking: $PREFIX/$TARGET"
pankso@421 122 if ! readlink include >/dev/null; then
pankso@421 123 echo "Creating symlink: ../usr/include include"
pankso@421 124 cp -a include ../usr && rm -rf include
pankso@421 125 ln -s ../usr/include include
pankso@421 126 fi
pankso@421 127 if ! readlink lib >/dev/null; then
pankso@421 128 echo "Creating symlink: ../lib lib"
pankso@421 129 rm -rf lib && ln -s ../lib lib
pankso@403 130 fi
pankso@403 131 }
pankso@403 132
pankso@361 133 # 1. Binutils
pankso@361 134 binutils() {
pankso@408 135 init_compile
pankso@411 136 rm -rf binutils-$BINUTILS_VERSION
pankso@421 137 echo "Extracting: $BINUTILS_TARBALL"
pankso@421 138 tar xjf $SRC/$BINUTILS_TARBALL
pankso@400 139 : ${BINUTILS_ARGS=--enable-shared}
pankso@421 140 echo "Configure: $BINUTILS_ARGS"
pankso@403 141 check_sysroot
pankso@361 142 cd binutils-$BINUTILS_VERSION
pankso@361 143 ./configure \
pankso@361 144 --prefix=$PREFIX \
pankso@361 145 --target=$TARGET \
pankso@361 146 --enable-targets=$BUILD_SYSTEM \
pankso@403 147 $BINUTILS_ARGS $sysroot
pankso@361 148 make || exit 1
pankso@361 149 make install
pankso@421 150 echo "cross: binutils compiled on: $(date)"
pankso@361 151 }
pankso@361 152
pankso@421 153 # 2. Kernel headers could use CROSS_COMPILE but gcc is not yet build.
pankso@421 154 # NOTE: Compile GCC static first then linux-headers ?
pankso@421 155 linux_headers() {
pankso@421 156 init_compile
pankso@421 157 echo "Extracting: $LINUX_TARBALL"
pankso@421 158 tar xjf $SRC/$LINUX_TARBALL
pankso@421 159 check_sysroot
pankso@421 160 cd linux-$LINUX_VERSION
pankso@421 161 make mrproper
pankso@421 162 make ARCH=$ARCH headers_check
pankso@421 163 make ARCH=$ARCH headers_install INSTALL_HDR_PATH=$HDR_PATH
pankso@421 164 }
pankso@421 165
pankso@421 166 # 3. GCC static (first pass)
pankso@361 167 gcc_static() {
pankso@408 168 init_compile
pankso@421 169 echo "Extracting: $GCC_TARBALL"
pankso@421 170 tar xjf $SRC/$GCC_TARBALL
pankso@421 171 echo "Configure: $GCC_STATIC_ARGS"
pankso@403 172 check_sysroot
pankso@403 173 # Arch fixes and work around
pankso@403 174 case "$ARCH" in
pankso@403 175 x86_64)
pankso@403 176 # GCC wants Glib headers in cross environment (not tested
pankso@403 177 # with sysroot) Should we install glibc-headers before ?
pankso@403 178 [ "$SYSROOT" ] || \
pankso@409 179 ln -s /usr/include $PREFIX/$TARGET/include ;;
pankso@403 180 esac
pankso@361 181 rm -rf gcc-static
pankso@361 182 mkdir gcc-static && cd gcc-static
pankso@361 183 ../gcc-$GCC_VERSION/configure \
pankso@361 184 --prefix=$PREFIX \
pankso@374 185 --libexec=$PREFIX/lib \
pankso@361 186 --target=$TARGET \
pankso@361 187 --disable-shared \
pankso@361 188 --disable-threads \
pankso@361 189 --without-headers \
pankso@361 190 --with-newlib \
pankso@403 191 $GCC_STATIC_ARGS $sysroot
pankso@361 192 make all-gcc all-target-libgcc || exit 1
pankso@361 193 make install-gcc install-target-libgcc
pankso@361 194 cd $PREFIX/lib/gcc/$TARGET/$GCC_VERSION
paul@382 195 echo "Creating symlink for static libgcc: libgcc_eh.a"
pankso@421 196 rm -f libgcc_eh.a
pankso@421 197 ln -s libgcc.a libgcc_eh.a
pankso@421 198 echo "cross: gcc-static compiled on: $(date)"
pankso@403 199 }
pankso@403 200
pankso@361 201 # 4. GNU Glibc
pankso@361 202 glibc() {
pankso@408 203 init_compile
pankso@421 204 echo "Extracting: $GLIBC_TARBALL"
pankso@421 205 tar xjf $SRC/$GLIBC_TARBALL
pankso@421 206 echo "Configure: $GLIBC_ARGS"
pankso@361 207 [ "$continue" ] || rm -rf glibc-build
pankso@400 208 # Some arch may need glibc-ports and custom CFLAGS
pankso@403 209 case "$ARCH" in
pankso@361 210 arm)
pankso@401 211 #export CFLAGS="-march=armv6 -mtune=generic -g -O2"
pankso@362 212 [ -f "$SRC/glibc-ports-$GLIBC_VERSION.tar.bz2" ] || wget \
pankso@362 213 http://ftp.gnu.org/gnu/libc/glibc-ports-$GLIBC_VERSION.tar.bz2 \
pankso@362 214 -O $SRC/glibc-ports-$GLIBC_VERSION.tar.bz2 || exit 1
pankso@361 215 echo "Extracting: glibc-ports-$GLIBC_VERSION.tar.bz2"
pankso@361 216 rm -rf glibc-$GLIBC_VERSION/ports
pankso@361 217 tar xjf $SRC/glibc-ports-$GLIBC_VERSION.tar.bz2
pankso@361 218 mv glibc-ports-$GLIBC_VERSION glibc-$GLIBC_VERSION/ports ;;
pankso@418 219 x86_64)
pankso@418 220 ccflags="-m64" ;;
pankso@361 221 esac
pankso@421 222 echo "CFLAGS: $CFLAGS"
pankso@361 223 mkdir -p glibc-build && cd glibc-build
pankso@365 224 BUILD_CC="gcc" \
pankso@418 225 CC="${TARGET}-gcc $ccflags" \
pankso@361 226 libc_cv_forced_unwind=yes \
pankso@361 227 libc_cv_c_cleanup=yes \
pankso@361 228 ../glibc-$GLIBC_VERSION/configure \
pankso@361 229 --prefix=$PREFIX \
pankso@417 230 --libexec=$PREFIX/lib/glibc \
pankso@361 231 --host=$TARGET \
pankso@421 232 --with-headers=$PREFIX/usr/include \
pankso@361 233 --with-binutils=$PREFIX/bin \
pankso@410 234 $GLIBC_ARGS
pankso@361 235 make || exit 1
pankso@361 236 make install
pankso@403 237 # Work around to let GCC find Glibc headers.
pankso@404 238 if [ "$SYSROOT" ]; then
pankso@404 239 cd $SYSROOT
pankso@404 240 ln -s usr/include sys-include
pankso@404 241 else
pankso@421 242 check_include
pankso@403 243 fi
pankso@421 244 unset CFLAGS
pankso@421 245 echo "cross: glibc compiled on: $(date)"
pankso@361 246 }
pankso@361 247
pankso@361 248 # 5. GCC final
pankso@361 249 gcc_final() {
pankso@408 250 init_compile
pankso@361 251 if [ ! -d "gcc-$GCC_VERSION" ]; then
pankso@421 252 echo "Extracting: $GCC_TARBALL"
pankso@421 253 tar xjf $SRC/$GCC_TARBALL
pankso@361 254 fi
pankso@421 255 echo "Configure: $GCC_FINAL_ARGS"
pankso@403 256 check_sysroot
pankso@421 257 [ "$continue" ] || rm -rf gcc-build
pankso@421 258 mkdir -p gcc-build && cd gcc-build
pankso@361 259 ../gcc-$GCC_VERSION/configure \
pankso@361 260 --prefix=$PREFIX \
pankso@374 261 --libexec=$PREFIX/lib \
pankso@361 262 --target=$TARGET \
pankso@361 263 --enable-shared \
pankso@361 264 --enable-c99 \
pankso@361 265 --enable-long-long \
pankso@361 266 --enable-__cxa_atexit \
pankso@400 267 --with-pkgversion="SliTaz" \
pankso@403 268 $GCC_FINAL_ARGS $sysroot
pankso@361 269 make || exit 1
pankso@421 270 make install &&
pankso@421 271 echo "cross: GCC final compiled on: $(date)"
pankso@361 272 }
pankso@361 273
paul@382 274 # Build Busybox to we can create prebuilt tiny rootfs image and boot
pankso@361 275 # from NFS ?
pankso@361 276 cross_busybox() {
pankso@408 277 init_compile
pankso@421 278 echo "Extracting: $BUSYBOX_TARBALL"
pankso@421 279 tar xjf $SRC/$BUSYBOX_TARBALL
pankso@361 280 cd busybox-$BUSYBOX_VERSION
pankso@400 281 # CROSS_COMPILE is exported via init_compile.
pankso@400 282 make defconfig
pankso@400 283 make || exit 1
pankso@400 284 make install
pankso@361 285 chmod 4755 _install/bin/busybox
pankso@361 286 readelf -h _install/bin/busybox
pankso@421 287 echo "cross: busybox install path: $(pwd)/_install"
pankso@421 288 echo "cross: busybox compiled on: $(date)"
pankso@361 289 }
pankso@361 290
pankso@361 291 #
pankso@361 292 # Commands
pankso@361 293 #
pankso@361 294
pankso@361 295 case "$1" in
pankso@361 296 howto|man)
pankso@361 297 doc=/usr/share/doc/cookutils/cross.txt
pankso@361 298 [ -f "$doc" ] && less -E $doc ;;
pankso@361 299 info)
pankso@361 300 init_compile
pankso@361 301 CC=${TARGET}-gcc
paul@382 302 echo -e "\nCross Toolchain information" && separator
pankso@374 303 [ "$config" ] && echo "Config file : $config"
pankso@361 304 cat << EOT
pankso@374 305 Target arch : $ARCH
pankso@374 306 C Compiler : $CC
pankso@374 307 Build directory : $WORK
pankso@361 308 EOT
pankso@403 309 if [ "$SYSROOT" ]; then
pankso@404 310 PREFIX=/usr
pankso@403 311 echo "Arch sysroot : $SYSROOT"
pankso@403 312 else
pankso@403 313 echo "Additional path : $PREFIX/bin"
pankso@403 314 fi
pankso@361 315 separator && echo ""
pankso@361 316 echo "GCC version" && separator
pankso@404 317 if [ -x "$PREFIX/bin/$CC" ]; then
pankso@374 318 $CC -v
pankso@374 319 else
pankso@374 320 echo "No C compiler. To build a toolchain run: cross compile"
pankso@374 321 fi
pankso@361 322 separator && echo "" ;;
pankso@361 323 testsuite)
pankso@361 324 init_compile
pankso@361 325 echo "[COMPILING] $TARGET-gcc -v -Wall -o test.out test.c" \
pankso@361 326 | tee $logdir/testsuite.log
pankso@361 327 echo 'int main() { return 0; }' > test.c
pankso@361 328 $TARGET-gcc -v -Wall -o test.out test.c 2>&1 | tee -a $logdir/testsuite.log
pankso@361 329 if [ -x /usr/bin/file ]; then
pankso@361 330 echo -e "\n[CHECKING] file test.out" | tee -a $logdir/testsuite.log
pankso@361 331 file test.out | tee -a $logdir/testsuite.log
pankso@361 332 fi
pankso@361 333 echo -e "\n[CHECKING] readelf -h test.out" | tee -a $logdir/testsuite.log
pankso@361 334 readelf -h test.out | tee -a $logdir/testsuite.log ;;
pankso@421 335 check)
pankso@421 336 echo "Checking: build system packages"
pankso@421 337 for pkg in slitaz-toolchain mpfr mpfr-dev gmp gmp-dev mpc-library \
pankso@421 338 gawk autoconf; do
pankso@361 339 if [ ! -d "/var/lib/tazpkg/installed/$pkg" ]; then
pankso@361 340 echo "Missing packages: $pkg"
pankso@421 341 if [ -x /usr/sbin/spk-add ]; then
pankso@421 342 spk-add $pkg
pankso@421 343 else
pankso@421 344 tazpkg -gi $pkg
pankso@421 345 fi
pankso@361 346 fi
pankso@421 347 done
pankso@421 348 # See: check_include()
pankso@421 349 if [ "$SYSROOT" ]; then
pankso@421 350 echo "Using: --with-sysroot=$SYSROOT"
pankso@421 351 echo "WARNING: not well tested and buggy"
pankso@421 352 exit 0
pankso@421 353 fi
pankso@421 354 check_include ;;
pankso@361 355 download)
pankso@361 356 download_src ;;
pankso@361 357 show-log)
pankso@361 358 pkg=$2
pankso@371 359 log=$logdir/$pkg.log
pankso@371 360 if [ ! -f "$log" ]; then
pankso@371 361 echo "No log file found for: $pkg" && exit 1
pankso@371 362 fi
pankso@371 363 less -E $log ;;
pankso@361 364 binutils)
pankso@412 365 rm -f $logdir/binutils.log
pankso@361 366 binutils 2>&1 | tee $logdir/binutils.log ;;
pankso@403 367 gcc-static)
pankso@403 368 gcc_static 2>&1 | tee $logdir/gcc-static.log ;;
pankso@361 369 linux-headers)
pankso@363 370 linux_headers 2>&1 | tee $logdir/linux-headers.log ;;
pankso@361 371 glibc)
pankso@361 372 glibc 2>&1 | tee $logdir/glibc.log ;;
pankso@361 373 gcc-final)
pankso@361 374 gcc_final 2>&1 | tee $logdir/gcc-final.log ;;
pankso@361 375 busybox)
pankso@361 376 cross_busybox 2>&1 | tee $logdir/busybox.log ;;
pankso@361 377 compile)
pankso@400 378 # Compile the full toolchain.
pankso@400 379 time=$(date +%s)
pankso@361 380 init_compile
pankso@361 381 echo "Compile start: $(date)" | tee $logdir/compile.log
pankso@361 382 download_src
pankso@361 383 binutils 2>&1 | tee $logdir/binutils.log
pankso@403 384 gcc_static 2>&1 | tee $logdir/gcc-static.log
pankso@361 385 linux_headers 2>&1 | tee $logdir/linux-headers.log
pankso@361 386 glibc 2>&1 | tee $logdir/glibc.log
pankso@361 387 gcc_final 2>&1 | tee $logdir/gcc-final.log
pankso@361 388 echo ""
pankso@365 389 echo "Compile end : $(date)" | tee -a $logdir/compile.log
pankso@400 390 time=$(($(date +%s) - $time))
pankso@400 391 sec=$time
pankso@400 392 div=$(( ($time + 30) / 60))
pankso@400 393 [ "$div" != 0 ] && min="~ ${div}m"
pankso@401 394 echo "Build time : ${sec}s $min" | tee -a $logdir/compile.log
pankso@361 395 echo "" ;;
pankso@416 396 clean)
pankso@416 397 echo -n "Removing all source files..."
pankso@416 398 rm -rf $WORK/source/* && status
pankso@416 399 [ "$log" ] && rm -f $WORK/log/*.log
pankso@416 400 echo "To clean chroot: rm -rf $PREFIX" ;;
pankso@371 401 clean-tools)
pankso@371 402 # Remove crap :-)
pankso@371 403 init_compile
pankso@416 404 echo "Cleaning : $PREFIX ($(du -sh $PREFIX | awk '{print $1}'))"
pankso@371 405 for dir in info man locale
pankso@371 406 do
pankso@416 407 echo -n "Removing : $dir"
pankso@419 408 rm -rf $PREFIX/share/$dir && status
pankso@371 409 done
pankso@416 410 rm -f $PREFIX/lib/*-gdb.py
pankso@419 411 echo -n "Stripping : shared libs and binaries"
pankso@419 412 ${TARGET}-strip -s $PREFIX/lib/*.so* 2>/dev/null
pankso@419 413 ${TARGET}-strip -s $PREFIX/bin/* 2>/dev/null
pankso@419 414 ${TARGET}-strip -s $PREFIX/${TARGET}/bin/* 2>/dev/null
pankso@416 415 ${TARGET}-strip -s $PREFIX/$TARGET/lib/gcc/$TARGET/*/cc1*
pankso@416 416 ${TARGET}-strip -s $PREFIX/$TARGET/lib/gcc/$TARGET/*/lto*
pankso@416 417 sleep 1 && status
pankso@416 418 echo -n "Tools size : " && du -sh $PREFIX | awk '{print $1}' ;;
pankso@366 419 gen-rootfs)
pankso@419 420 echo "Use arm packages: basefile, boot-scripts, busybox and glibc-base"
pankso@419 421 echo "Install them in a rootfs: tazpkg *-arm.tazpkg --root=/my/rootfs" ;;
pankso@416 422 gen-prebuilt)
pankso@420 423 # Create a prebuilt cross toolchain tarball.
pankso@416 424 init_compile
pankso@420 425 date=$(date "+%Y%m%d")
pankso@420 426 package="slitaz-cross-$ARCH-toolchain-$date"
pankso@419 427 tarball="$package.tar.bz2"
pankso@416 428 cd /usr/cross
pankso@419 429 mkdir $package || exit 1
pankso@419 430 echo ""
pankso@419 431 echo -n "Copying $ARCH to: $package"
pankso@419 432 cp -a $ARCH $package
pankso@419 433 rm -rf $package/share $package/etc
pankso@419 434 status
pankso@420 435 prebuilt_readme
pankso@416 436 echo -n "Creating prebuilt $ARCH toolchain tarball..."
pankso@419 437 tar cjf $tarball $package
pankso@416 438 status
pankso@416 439 mv -f $tarball $WORK
pankso@419 440 rm -rf $package
pankso@419 441 size=$(du -sh $WORK/$tarball | awk '{print $1}')
pankso@419 442 echo "Tarball path: $WORK/$tarball"
pankso@419 443 echo "Tarball size: $size"
pankso@419 444 echo "" ;;
pankso@361 445 *)
pankso@361 446 usage ;;
pankso@361 447 esac
pankso@361 448