cookutils view cross @ rev 423
cross: small fixe and use CROSS_PREFIX to install bdeps in a cross compile environement
author | Christophe Lincoln <pankso@slitaz.org> |
---|---|
date | Sat May 19 14:29:55 2012 +0200 (2012-05-19) |
parents | 71450d322f7b |
children | 183ef2eaddc6 |
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 $GLIBC_ARGS
234 make || exit 1
235 make install
236 # Work around to let GCC find Glibc headers.
237 if [ "$SYSROOT" ]; then
238 cd $SYSROOT
239 ln -s usr/include sys-include
240 else
241 check_include
242 fi
243 unset CFLAGS
244 echo "cross: glibc compiled on: $(date)"
245 }
247 # 5. GCC final
248 gcc_final() {
249 init_compile
250 if [ ! -d "gcc-$GCC_VERSION" ]; then
251 echo "Extracting: $GCC_TARBALL"
252 tar xjf $SRC/$GCC_TARBALL
253 fi
254 echo "Configure: $GCC_FINAL_ARGS"
255 check_sysroot
256 [ "$continue" ] || rm -rf gcc-build
257 mkdir -p gcc-build && cd gcc-build
258 ../gcc-$GCC_VERSION/configure \
259 --prefix=$PREFIX \
260 --libexec=$PREFIX/lib \
261 --target=$TARGET \
262 --enable-shared \
263 --enable-c99 \
264 --enable-long-long \
265 --enable-__cxa_atexit \
266 --with-pkgversion="SliTaz" \
267 $GCC_FINAL_ARGS $sysroot
268 make || exit 1
269 make install &&
270 echo "cross: GCC final compiled on: $(date)"
271 }
273 # Build Busybox to we can create prebuilt tiny rootfs image and boot
274 # from NFS ?
275 cross_busybox() {
276 init_compile
277 echo "Extracting: $BUSYBOX_TARBALL"
278 tar xjf $SRC/$BUSYBOX_TARBALL
279 cd busybox-$BUSYBOX_VERSION
280 # CROSS_COMPILE is exported via init_compile.
281 make defconfig
282 make || exit 1
283 make install
284 chmod 4755 _install/bin/busybox
285 readelf -h _install/bin/busybox
286 echo "cross: busybox install path: $(pwd)/_install"
287 echo "cross: busybox compiled on: $(date)"
288 }
290 #
291 # Commands
292 #
294 case "$1" in
295 howto|man)
296 doc=/usr/share/doc/cookutils/cross.txt
297 [ -f "$doc" ] && less -E $doc ;;
298 info)
299 init_compile
300 CC=${TARGET}-gcc
301 echo -e "\nCross Toolchain information" && separator
302 [ "$config" ] && echo "Config file : $config"
303 cat << EOT
304 Target arch : $ARCH
305 C Compiler : $CC
306 Build directory : $WORK
307 EOT
308 if [ "$SYSROOT" ]; then
309 PREFIX=/usr
310 echo "Arch sysroot : $SYSROOT"
311 else
312 echo "Additional path : $PREFIX/bin"
313 fi
314 separator && echo ""
315 echo "GCC version" && separator
316 if [ -x "$PREFIX/bin/$CC" ]; then
317 $CC -v
318 else
319 echo "No C compiler. To build a toolchain run: cross compile"
320 fi
321 separator && echo "" ;;
322 testsuite)
323 init_compile
324 echo "[COMPILING] $TARGET-gcc -v -Wall -o test.out test.c" \
325 | tee $logdir/testsuite.log
326 echo 'int main() { return 0; }' > test.c
327 $TARGET-gcc -v -Wall -o test.out test.c 2>&1 | tee -a $logdir/testsuite.log
328 if [ -x /usr/bin/file ]; then
329 echo -e "\n[CHECKING] file test.out" | tee -a $logdir/testsuite.log
330 file test.out | tee -a $logdir/testsuite.log
331 fi
332 echo -e "\n[CHECKING] readelf -h test.out" | tee -a $logdir/testsuite.log
333 readelf -h test.out | tee -a $logdir/testsuite.log ;;
334 check)
335 echo "Checking: build system packages"
336 for pkg in slitaz-toolchain mpfr mpfr-dev gmp gmp-dev mpc-library \
337 gawk autoconf; do
338 if [ ! -d "/var/lib/tazpkg/installed/$pkg" ]; then
339 echo "Missing packages: $pkg"
340 if [ -x /usr/sbin/spk-add ]; then
341 spk-add $pkg
342 else
343 tazpkg -gi $pkg
344 fi
345 fi
346 done
347 # See: check_include()
348 if [ "$SYSROOT" ]; then
349 echo "Using: --with-sysroot=$SYSROOT"
350 echo "WARNING: not well tested and buggy"
351 exit 0
352 fi
353 check_include ;;
354 download)
355 download_src ;;
356 show-log)
357 pkg=$2
358 log=$logdir/$pkg.log
359 if [ ! -f "$log" ]; then
360 echo "No log file found for: $pkg" && exit 1
361 fi
362 less -E $log ;;
363 binutils)
364 rm -f $logdir/binutils.log
365 binutils 2>&1 | tee $logdir/binutils.log ;;
366 gcc-static)
367 gcc_static 2>&1 | tee $logdir/gcc-static.log ;;
368 linux-headers)
369 linux_headers 2>&1 | tee $logdir/linux-headers.log ;;
370 glibc)
371 glibc 2>&1 | tee $logdir/glibc.log ;;
372 gcc-final)
373 gcc_final 2>&1 | tee $logdir/gcc-final.log ;;
374 busybox)
375 cross_busybox 2>&1 | tee $logdir/busybox.log ;;
376 compile)
377 # Compile the full toolchain.
378 time=$(date +%s)
379 init_compile
380 echo "Compile start: $(date)" | tee $logdir/compile.log
381 download_src
382 binutils 2>&1 | tee $logdir/binutils.log
383 gcc_static 2>&1 | tee $logdir/gcc-static.log
384 linux_headers 2>&1 | tee $logdir/linux-headers.log
385 glibc 2>&1 | tee $logdir/glibc.log
386 gcc_final 2>&1 | tee $logdir/gcc-final.log
387 echo ""
388 echo "Compile end : $(date)" | tee -a $logdir/compile.log
389 time=$(($(date +%s) - $time))
390 sec=$time
391 div=$(( ($time + 30) / 60))
392 [ "$div" != 0 ] && min="~ ${div}m"
393 echo "Build time : ${sec}s $min" | tee -a $logdir/compile.log
394 echo "" ;;
395 clean)
396 echo -n "Removing all source files..."
397 rm -rf $WORK/source/* && status
398 [ "$log" ] && rm -f $WORK/log/*.log
399 echo "To clean chroot: rm -rf $PREFIX" ;;
400 clean-tools)
401 # Remove crap :-)
402 init_compile
403 echo "Cleaning : $PREFIX ($(du -sh $PREFIX | awk '{print $1}'))"
404 for dir in info man locale
405 do
406 echo -n "Removing : $dir"
407 rm -rf $PREFIX/share/$dir && status
408 done
409 rm -f $PREFIX/lib/*-gdb.py
410 echo -n "Stripping : shared libs and binaries"
411 ${TARGET}-strip -s $PREFIX/lib/*.so* 2>/dev/null
412 ${TARGET}-strip -s $PREFIX/bin/* 2>/dev/null
413 ${TARGET}-strip -s $PREFIX/${TARGET}/bin/* 2>/dev/null
414 ${TARGET}-strip -s $PREFIX/$TARGET/lib/gcc/$TARGET/*/cc1*
415 ${TARGET}-strip -s $PREFIX/$TARGET/lib/gcc/$TARGET/*/lto*
416 sleep 1 && status
417 echo -n "Tools size : " && du -sh $PREFIX | awk '{print $1}' ;;
418 gen-rootfs)
419 echo "Use arm packages: basefile, boot-scripts, busybox and glibc-base"
420 echo "Install them in a rootfs: tazpkg *-arm.tazpkg --root=/my/rootfs" ;;
421 gen-prebuilt)
422 # Create a prebuilt cross toolchain tarball.
423 init_compile
424 date=$(date "+%Y%m%d")
425 package="slitaz-cross-$ARCH-toolchain-$date"
426 tarball="$package.tar.bz2"
427 cd /usr/cross
428 mkdir $package || exit 1
429 echo ""
430 echo -n "Copying $ARCH to: $package"
431 cp -a $ARCH $package
432 rm -rf $package/share $package/etc
433 status
434 prebuilt_readme
435 echo -n "Creating prebuilt $ARCH toolchain tarball..."
436 tar cjf $tarball $package
437 status
438 mv -f $tarball $WORK
439 rm -rf $package
440 size=$(du -sh $WORK/$tarball | awk '{print $1}')
441 echo "Tarball path: $WORK/$tarball"
442 echo "Tarball size: $size"
443 echo "" ;;
444 *)
445 usage ;;
446 esac