cookutils view cross @ rev 425

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