cookutils view cross @ rev 416

cross: more clean-tools and add gen-prebuilt (for testing)
author Christophe Lincoln <pankso@slitaz.org>
date Mon May 14 14:59:53 2012 +0200 (2012-05-14)
parents 0951a386e1e6
children 0f2a3fcd0e24
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-env Check build host tools
30 download Download necessary sources
31 clean Clean-up build environment
32 clean-tools Clean: $PREFIX
33 show-log Show a compile log
34 binutils Compile Binutils
35 gcc-static Compile GCC static
36 linux-headers Install Kernel headers
37 glibc Compile GNU Glibc
38 gcc-final Compile final GCC
39 busybox Cross compile Busybox
40 compile Compile everything at once
42 EOT
43 }
45 # Make sure we have all directories.
46 init_compile() {
47 export LC_ALL=POSIX LANG=POSIX
48 [ "$SYSROOT" ] || export PATH=$PATH:$PREFIX/bin
49 export CROSS_COMPILE=${TARGET}-
50 mkdir -p $source $logdir $install
51 cd $source
52 }
54 # Get source if not yet in $SRC.
55 download_src() {
56 mkdir -p $SRC && cd $SRC
57 [ -f "binutils-$BINUTILS_VERSION.tar.bz2" ] || wget $BINUTILS_WGET
58 [ -f "linux-$LINUX_VERSION.tar.bz2" ] || wget $LINUX_WGET
59 [ -f "glibc-$GLIBC_VERSION.tar.bz2" ] || wget $GLIBC_WGET
60 [ -f "gcc-$GCC_VERSION.tar.bz2" ] || wget $GCC_WGET
61 [ -f "busybox-$BUSYBOX_VERSION.tar.bz2" ] || wget $BUSYBOX_WGET
62 }
64 # Use sysroot or not ?
65 check_sysroot() {
66 if [ "$SYSROOT" ]; then
67 PREFIX=/usr
68 HDR_PATH=$SYSROOT/usr
69 sysroot="--with-sysroot=$SYSROOT"
70 echo "Configure : $sysroot"
71 else
72 HDR_PATH=$PREFIX
73 fi
74 }
76 # 1. Binutils
77 binutils() {
78 init_compile
79 rm -rf binutils-$BINUTILS_VERSION
80 echo "Extracting: binutils-$BINUTILS_VERSION.tar.bz2"
81 tar xjf $SRC/binutils-$BINUTILS_VERSION.tar.bz2
82 : ${BINUTILS_ARGS=--enable-shared}
83 echo "Configure : $BINUTILS_ARGS"
84 check_sysroot
85 cd binutils-$BINUTILS_VERSION
86 ./configure \
87 --prefix=$PREFIX \
88 --target=$TARGET \
89 --enable-targets=$BUILD_SYSTEM \
90 $BINUTILS_ARGS $sysroot
91 make || exit 1
92 make install
93 #echo "cross: binutils compiled on: $(date)"
94 }
96 # 2. GCC static (first pass)
97 gcc_static() {
98 init_compile
99 echo "Extracting: gcc-$GCC_VERSION.tar.bz2"
100 tar xjf $SRC/gcc-$GCC_VERSION.tar.bz2
101 echo "Configure : $GCC_STATIC_ARGS"
102 check_sysroot
103 # Arch fixes and work around
104 case "$ARCH" in
105 x86_64)
106 # GCC wants Glib headers in cross environment (not tested
107 # with sysroot) Should we install glibc-headers before ?
108 [ "$SYSROOT" ] || \
109 ln -s /usr/include $PREFIX/$TARGET/include ;;
110 esac
111 rm -rf gcc-static
112 mkdir gcc-static && cd gcc-static
113 ../gcc-$GCC_VERSION/configure \
114 --prefix=$PREFIX \
115 --libexec=$PREFIX/lib \
116 --target=$TARGET \
117 --disable-shared \
118 --disable-threads \
119 --without-headers \
120 --with-newlib \
121 $GCC_STATIC_ARGS $sysroot
122 make all-gcc all-target-libgcc || exit 1
123 make install-gcc install-target-libgcc
124 cd $PREFIX/lib/gcc/$TARGET/$GCC_VERSION
125 echo "Creating symlink for static libgcc: libgcc_eh.a"
126 rm -f libgcc_eh.a && ln -s libgcc.a libgcc_eh.a
127 }
129 # 3. Kernel headers use static GCC
130 linux_headers() {
131 init_compile
132 echo "Extracting: linux-$LINUX_VERSION.tar.bz2"
133 tar xjf $SRC/linux-$LINUX_VERSION.tar.bz2
134 check_sysroot
135 cd linux-$LINUX_VERSION
136 make mrproper
137 make ARCH=$ARCH headers_check
138 make ARCH=$ARCH headers_install \
139 INSTALL_HDR_PATH=$HDR_PATH
140 }
142 # 4. GNU Glibc
143 glibc() {
144 init_compile
145 echo "Extracting: glibc-$GLIBC_VERSION.tar.bz2"
146 tar xjf $SRC/glibc-$GLIBC_VERSION.tar.bz2
147 echo "Configure : $GLIBC_ARGS"
148 [ "$continue" ] || rm -rf glibc-build
149 # Some arch may need glibc-ports and custom CFLAGS
150 case "$ARCH" in
151 arm)
152 #export CFLAGS="-march=armv6 -mtune=generic -g -O2"
153 [ -f "$SRC/glibc-ports-$GLIBC_VERSION.tar.bz2" ] || wget \
154 http://ftp.gnu.org/gnu/libc/glibc-ports-$GLIBC_VERSION.tar.bz2 \
155 -O $SRC/glibc-ports-$GLIBC_VERSION.tar.bz2 || exit 1
156 echo "Extracting: glibc-ports-$GLIBC_VERSION.tar.bz2"
157 rm -rf glibc-$GLIBC_VERSION/ports
158 tar xjf $SRC/glibc-ports-$GLIBC_VERSION.tar.bz2
159 mv glibc-ports-$GLIBC_VERSION glibc-$GLIBC_VERSION/ports ;;
160 esac
161 #echo "CFLAGS: $CFLAGS"
162 mkdir -p glibc-build && cd glibc-build
163 BUILD_CC="gcc" \
164 CC="$PREFIX/bin/$TARGET-gcc" \
165 libc_cv_forced_unwind=yes \
166 libc_cv_c_cleanup=yes \
167 ../glibc-$GLIBC_VERSION/configure \
168 --prefix=$PREFIX \
169 --host=$TARGET \
170 --with-headers=$PREFIX/include \
171 --with-binutils=$PREFIX/bin \
172 $GLIBC_ARGS
173 make || exit 1
174 make install
175 # Work around to let GCC find Glibc headers.
176 if [ "$SYSROOT" ]; then
177 cd $SYSROOT
178 ln -s usr/include sys-include
179 else
180 cd $PREFIX/$TARGET
181 rm -rf lib include
182 ln -s ../lib lib
183 ln -s ../include include
184 fi
185 #unset CFLAGS
186 }
188 # 5. GCC final
189 gcc_final() {
190 init_compile
191 if [ ! -d "gcc-$GCC_VERSION" ]; then
192 echo "Extracting: gcc-$GCC_VERSION.tar.bz2"
193 tar xjf $SRC/gcc-$GCC_VERSION.tar.bz2
194 fi
195 echo "Configure : $GCC_FINAL_ARGS"
196 check_sysroot
197 rm -rf gcc-build
198 mkdir gcc-build && cd gcc-build
199 ../gcc-$GCC_VERSION/configure \
200 --prefix=$PREFIX \
201 --libexec=$PREFIX/lib \
202 --target=$TARGET \
203 --enable-shared \
204 --enable-c99 \
205 --enable-long-long \
206 --enable-__cxa_atexit \
207 --with-pkgversion="SliTaz" \
208 $GCC_FINAL_ARGS $sysroot
209 make || exit 1
210 make install
211 }
213 # Build Busybox to we can create prebuilt tiny rootfs image and boot
214 # from NFS ?
215 cross_busybox() {
216 init_compile
217 echo "Extracting: busybox-$BUSYBOX_VERSION.tar.bz2"
218 tar xjf $SRC/busybox-$BUSYBOX_VERSION.tar.bz2
219 cd busybox-$BUSYBOX_VERSION
220 # CROSS_COMPILE is exported via init_compile.
221 make defconfig
222 make || exit 1
223 make install
224 chmod 4755 _install/bin/busybox
225 readelf -h _install/bin/busybox
226 echo "Busybox install path: $(pwd)/_install"
227 }
229 #
230 # Commands
231 #
233 case "$1" in
234 howto|man)
235 doc=/usr/share/doc/cookutils/cross.txt
236 [ -f "$doc" ] && less -E $doc ;;
237 info)
238 init_compile
239 CC=${TARGET}-gcc
240 echo -e "\nCross Toolchain information" && separator
241 [ "$config" ] && echo "Config file : $config"
242 cat << EOT
243 Target arch : $ARCH
244 C Compiler : $CC
245 Build directory : $WORK
246 EOT
247 if [ "$SYSROOT" ]; then
248 PREFIX=/usr
249 echo "Arch sysroot : $SYSROOT"
250 else
251 echo "Additional path : $PREFIX/bin"
252 fi
253 separator && echo ""
254 echo "GCC version" && separator
255 if [ -x "$PREFIX/bin/$CC" ]; then
256 $CC -v
257 else
258 echo "No C compiler. To build a toolchain run: cross compile"
259 fi
260 separator && echo "" ;;
261 testsuite)
262 init_compile
263 echo "[COMPILING] $TARGET-gcc -v -Wall -o test.out test.c" \
264 | tee $logdir/testsuite.log
265 echo 'int main() { return 0; }' > test.c
266 $TARGET-gcc -v -Wall -o test.out test.c 2>&1 | tee -a $logdir/testsuite.log
267 if [ -x /usr/bin/file ]; then
268 echo -e "\n[CHECKING] file test.out" | tee -a $logdir/testsuite.log
269 file test.out | tee -a $logdir/testsuite.log
270 fi
271 echo -e "\n[CHECKING] readelf -h test.out" | tee -a $logdir/testsuite.log
272 readelf -h test.out | tee -a $logdir/testsuite.log ;;
273 check-env)
274 for pkg in mpfr mpfr-dev gmp gmp-dev mpc-library gawk autoconf
275 do
276 if [ ! -d "/var/lib/tazpkg/installed/$pkg" ]; then
277 echo "Missing packages: $pkg"
278 [ "$install" ] && tazpkg -gi $pkg
279 fi
280 done ;;
281 download)
282 download_src ;;
283 show-log)
284 pkg=$2
285 log=$logdir/$pkg.log
286 if [ ! -f "$log" ]; then
287 echo "No log file found for: $pkg" && exit 1
288 fi
289 less -E $log ;;
290 binutils)
291 rm -f $logdir/binutils.log
292 binutils 2>&1 | tee $logdir/binutils.log ;;
293 gcc-static)
294 gcc_static 2>&1 | tee $logdir/gcc-static.log ;;
295 linux-headers)
296 linux_headers 2>&1 | tee $logdir/linux-headers.log ;;
297 glibc)
298 glibc 2>&1 | tee $logdir/glibc.log ;;
299 gcc-final)
300 gcc_final 2>&1 | tee $logdir/gcc-final.log ;;
301 busybox)
302 cross_busybox 2>&1 | tee $logdir/busybox.log ;;
303 compile)
304 # Compile the full toolchain.
305 time=$(date +%s)
306 init_compile
307 echo "Compile start: $(date)" | tee $logdir/compile.log
308 download_src
309 binutils 2>&1 | tee $logdir/binutils.log
310 gcc_static 2>&1 | tee $logdir/gcc-static.log
311 linux_headers 2>&1 | tee $logdir/linux-headers.log
312 glibc 2>&1 | tee $logdir/glibc.log
313 gcc_final 2>&1 | tee $logdir/gcc-final.log
314 echo ""
315 echo "Compile end : $(date)" | tee -a $logdir/compile.log
316 time=$(($(date +%s) - $time))
317 sec=$time
318 div=$(( ($time + 30) / 60))
319 [ "$div" != 0 ] && min="~ ${div}m"
320 echo "Build time : ${sec}s $min" | tee -a $logdir/compile.log
321 echo "" ;;
322 clean)
323 echo -n "Removing all source files..."
324 rm -rf $WORK/source/* && status
325 [ "$log" ] && rm -f $WORK/log/*.log
326 echo "To clean chroot: rm -rf $PREFIX" ;;
327 clean-tools)
328 # Remove crap :-)
329 init_compile
330 echo "Cleaning : $PREFIX ($(du -sh $PREFIX | awk '{print $1}'))"
331 for dir in info man locale
332 do
333 echo -n "Removing : $dir"
334 rm -rf $PREFIX/share && status
335 done
336 rm -f $PREFIX/lib/*-gdb.py
337 #echo -n "Stripping : shared libs"
338 #${TARGET}-strip -s $PREFIX/lib/*.so.*
339 #status
340 echo -n "Stripping : GCC libs"
341 ${TARGET}-strip -s $PREFIX/$TARGET/lib/gcc/$TARGET/*/cc1*
342 ${TARGET}-strip -s $PREFIX/$TARGET/lib/gcc/$TARGET/*/lto*
343 sleep 1 && status
344 echo -n "Stripping : binaries"
345 for bin in $PREFIX/bin/${TARGET}-*
346 do
347 [ "$bin" == "$PREFIX/bin/${TARGET}-strip" ] && continue
348 if [ -x "$bin" ]; then
349 ${TARGET}-strip -s $bin 2>/dev/null
350 fi
351 done && status
352 echo -n "Tools size : " && du -sh $PREFIX | awk '{print $1}' ;;
353 gen-rootfs)
354 #
355 # TESTING
356 #
357 # Create a bootable rootfs ? dd for an HD image ?
358 init_compile
359 rootfs=/tmp/cross/rootfs
360 tarball="rootfs.tar.bz2"
361 rm -rf $rootfs && mkdir -p $rootfs
362 cd /tmp/cross
363 echo -n "Installing SliTaz base files..."
364 tar xzf $SRC/slitaz-base-files-5.2.tar.gz
365 cp -a slitaz-base-files-*/rootfs/* $rootfs
366 status
367 echo -n "Installing Busybox..."
368 cp -a $source/busybox-$BUSYBOX_VERSION/_install/* $rootfs
369 status
370 echo -n "Creating tarball: $tarball"
371 tar cjf $tarball rootfs
372 status
373 echo -n "Moving rootfs to: $WORK"
374 mv $tarball $WORK
375 status
376 du -sh $WORK/$tarball
377 rm -rf /tmp/cross ;;
378 gen-prebuilt)
379 #
380 # TESTING
381 #
382 # Create a prebuilt cross toolchain tarball (or package ?)
383 init_compile
384 cd /usr/cross
385 tarball="slitaz-cross-$ARCH-toolchain.tar.bz2"
386 echo -n "Creating prebuilt $ARCH toolchain tarball..."
387 tar cjf $tarball $ARCH
388 status
389 mv -f $tarball $WORK
390 #echo "Tarball size: $(du -sh $WORK/$tarball | awk '{print $1}')"
391 du -sh $WORK/$tarball ;;
392 *)
393 usage ;;
394 esac