cookutils view cross @ rev 453

cross: small fix
author Christophe Lincoln <pankso@slitaz.org>
date Thu May 31 15:37:15 2012 +0200 (2012-05-31)
parents baf7550d0e44
children 175bd828c332
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 tools=$WORK/tools
17 sysroot=$WORK/sysroot
18 logdir=$WORK/log
20 # Help and usage.
21 usage() {
22 cat << EOT
24 Usage: $(basename $0) command --option
26 Commands:
27 howto Man alike and howto
28 info Display cross-tools info
29 testsuite Execute a small testsuite
30 check Check build host environment
31 download Download necessary sources
32 show-log Show a compile log
33 binutils Compile Binutils
34 linux-headers Install Kernel headers
35 gcc-static Compile GCC static
36 glibc Compile GNU Glibc
37 gcc-final Compile final GCC
38 compile Compile everything at once
39 clean Clean-up build environment
40 clean-tools Clean: $tools
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 /cross
57 # export PATH=\$PATH:/cross/$ARCH/tools/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 unset CFLAGS CXXFLAGS
72 export LC_ALL=POSIX LANG=POSIX
73 export PATH=$PATH:$tools/bin
74 export CROSS_COMPILE=${TARGET}-
75 mkdir -p $source $logdir $sysroot $tools
76 echo "Tools prefix : --prefix=$tools "
77 echo "Target sysroot : --with-sysroot=$sysroot"
78 cd $source
79 }
81 # Get source if not yet in $SRC.
82 download_src() {
83 mkdir -p $SRC && cd $SRC
84 [ -f "$BINUTILS_TARBALL" ] || wget $BINUTILS_WGET
85 [ -f "$LINUX_TARBALL" ] || wget $LINUX_WGET
86 [ -f "$GLIBC_TARBALL" ] || wget $GLIBC_WGET
87 [ -f "$GCC_TARBALL" ] || wget $GCC_WGET
88 }
90 # 1. Binutils
91 binutils() {
92 init_compile
93 rm -rf binutils-$BINUTILS_VERSION
94 echo "Extracting: $BINUTILS_TARBALL"
95 tar xjf $SRC/$BINUTILS_TARBALL
96 echo "Configure: $BINUTILS_ARGS"
97 cd binutils-$BINUTILS_VERSION
98 ./configure \
99 --prefix=$tools \
100 --target=$TARGET \
101 --enable-plugins \
102 --enable-threads \
103 --enable-targets=$BUILD_SYSTEM \
104 --with-sysroot=$sysroot \
105 $BINUTILS_ARGS &&
106 make || exit 1
107 make install
108 echo "cross: binutils compiled on: $(date)"
109 }
111 # 2. Kernel headers could use CROSS_COMPILE but gcc is not yet build.
112 linux_headers() {
113 init_compile
114 if [ ! -d "linux-$LINUX_VERSION" ]; then
115 echo "Extracting: $LINUX_TARBALL"
116 tar xjf $SRC/$LINUX_TARBALL
117 fi
118 rm -rf linux-headers
119 cd linux-$LINUX_VERSION
120 make mrproper
121 make ARCH=$ARCH headers_check
122 make ARCH=$ARCH headers_install \
123 INSTALL_HDR_PATH=$source/linux-headers
124 rm $source/linux-headers/include/.*install*
125 echo "Copying headers to: $sysroot/usr"
126 cp -a $source/linux-headers/* $sysroot/usr
127 }
129 # 2.1 Glibc headers needed to compile x86_64 gcc-static.
130 glibc_headers() {
131 init_compile
132 echo "Extracting: $GLIBC_TARBALL"
133 tar xjf $SRC/$GLIBC_TARBALL
134 rm -rf glibc-headers
135 mkdir glibc-headers && cd glibc-headers
136 libc_cv_forced_unwind=yes \
137 libc_cv_c_cleanup=yes \
138 ../glibc-$GLIBC_VERSION/configure \
139 --prefix=/usr \
140 --host=$TARGET \
141 --with-headers=$sysroot/usr/include \
142 --without-cvs \
143 --disable-sanity-checks \
144 --enable-kernel=2.6.32 &&
145 make -k install-headers install_root=$sysroot
146 # Fixes
147 mkdir -p $sysroot/usr/include/gnu
148 touch $sysroot/usr/include/gnu/stubs.h
149 cp bits/stdio_lim.h $sysroot/usr/include/bits
150 }
152 # 3. GCC static (first pass)
153 gcc_static() {
154 init_compile
155 echo "Extracting: $GCC_TARBALL"
156 tar xjf $SRC/$GCC_TARBALL
157 echo "Configure: $GCC_STATIC_ARGS"
158 # Arch fixes and work around
159 case "$ARCH" in
160 x86_64)
161 # GCC wants Glib headers in cross environment (not tested
162 # with sysroot) Should we install glibc-headers before ?
163 echo "Try with eglibc or install glibc-headers first"
164 #rm -f $tools/$TARGET/include
165 #ln -s /usr/include $tools/$TARGET/include
166 ;;
167 esac
168 rm -rf gcc-static
169 mkdir gcc-static && cd gcc-static
170 ../gcc-$GCC_VERSION/configure \
171 --prefix=$tools \
172 --libexec=$tools/lib \
173 --target=$TARGET \
174 --disable-shared \
175 --disable-threads \
176 --disable-libgomp \
177 --disable-libmudflap \
178 --disable-libssp \
179 --without-headers \
180 --with-newlib \
181 --with-sysroot=$sysroot \
182 $GCC_STATIC_ARGS &&
183 make all-gcc all-target-libgcc || exit 1
184 make install-gcc install-target-libgcc
185 echo "cross: gcc-static compiled on: $(date)"
186 }
188 # 4. GNU Glibc
189 glibc() {
190 init_compile
191 echo "Extracting: $GLIBC_TARBALL"
192 tar xjf $SRC/$GLIBC_TARBALL
193 echo "Configure: $GLIBC_ARGS"
194 # Some arch may need glibc-ports and custom CFLAGS
195 case "$ARCH" in
196 arm)
197 export CFLAGS="-march=armv6 -O2"
198 [ -f "$SRC/glibc-ports-$GLIBC_VERSION.tar.bz2" ] || wget \
199 http://ftp.gnu.org/gnu/libc/glibc-ports-$GLIBC_VERSION.tar.bz2 \
200 -O $SRC/glibc-ports-$GLIBC_VERSION.tar.bz2 || exit 1
201 echo "Extracting: glibc-ports-$GLIBC_VERSION.tar.bz2"
202 rm -rf glibc-$GLIBC_VERSION/ports
203 tar xjf $SRC/glibc-ports-$GLIBC_VERSION.tar.bz2
204 mv glibc-ports-$GLIBC_VERSION glibc-$GLIBC_VERSION/ports
205 libexec=/usr/lib/glibc ;;
206 x86_64)
207 #export CFLAGS="-march=nocona -O2 -pipe"
208 ccflags="-m64"
209 libexec=/usr/lib64/glibc ;;
210 esac
211 # Disable linking to libgcc_eh
212 cd glibc-$GLIBC_VERSION
213 cp Makeconfig Makeconfig.orig
214 sed -e 's/-lgcc_eh//g' Makeconfig.orig > Makeconfig
215 cd ..
216 echo "CFLAGS: $CFLAGS"
217 rm -rf glibc-build
218 mkdir -p glibc-build && cd glibc-build
219 BUILD_CC="gcc" \
220 CC="${TARGET}-gcc $ccflags" \
221 AR="${TARGET}-ar" \
222 RANLIB="${TARGET}-ranlib" \
223 libc_cv_forced_unwind=yes \
224 libc_cv_c_cleanup=yes \
225 ../glibc-$GLIBC_VERSION/configure \
226 --prefix=/usr \
227 --libexec=$libexec \
228 --host=$TARGET \
229 --with-headers=$sysroot/usr/include \
230 --with-binutils=$tools/bin \
231 --enable-kernel=2.6.32 \
232 $GLIBC_ARGS &&
233 make || exit 1
234 make install_root=$sysroot install
235 # Work around to let GCC find Glibc headers.
236 #cd $sysroot
237 #ln -s usr/include sys-include
238 echo "cross: glibc compiled on: $(date)"
239 }
241 # 4. Eglibc: always use --prefix=/usr
242 eglibc() {
243 init_compile
244 rm -rf eglibc-build eglibc-$EGLIBC_VERSION
245 echo "Extracting: $EGLIBC_TARBALL"
246 tar xjf $SRC/$EGLIBC_TARBALL
247 # Some arch may need glibc-ports and custom CFLAGS
248 case "$ARCH" in
249 arm)
250 export CFLAGS="-march=armv6 -O2"
251 if [ ! -d "$source/eglibc-ports-$EGLIBC_VERSION" ]; then
252 echo "Cloning $EGLIBC_WGET/ports"
253 svn co $EGLIBC_WGET/ports eglibc-ports-$EGLIBC_VERSION >/dev/null
254 fi
255 cp -a eglibc-ports-$EGLIBC_VERSION eglibc-$EGLIBC_VERSION/ports
256 libexec=/usr/lib/eglibc ;;
257 x86_64)
258 #export CFLAGS="-march=nocona -O2 -pipe"
259 ccflags="-m64"
260 libexec=/usr/lib64/eglibc ;;
261 esac
262 # Disable linking to libgcc_eh
263 cd eglibc-$EGLIBC_VERSION
264 cp Makeconfig Makeconfig.orig
265 sed -e 's/-lgcc_eh//g' Makeconfig.orig > Makeconfig
266 cd ..
267 mkdir -p eglibc-build && cd eglibc-build
268 # config.cache
269 cat > config.cache << EOT
270 libc_cv_forced_unwind=yes
271 libc_cv_c_cleanup=yes
272 libc_cv_gnu89_inline=yes
273 EOT
274 BUILD_CC="gcc" \
275 CC="${TARGET}-gcc $ccflags" \
276 AR="${TARGET}-ar" \
277 RANLIB="${TARGET}-ranlib" \
278 ../eglibc-$EGLIBC_VERSION/configure \
279 --prefix=/usr \
280 --libexec=$libexec \
281 --host=$TARGET \
282 --with-headers=$sysroot/usr/include \
283 --with-binutils=$tools/bin \
284 --enable-kernel=2.6.32 \
285 --with-__thread \
286 --without-gd \
287 --without-cvs \
288 --cache-file=config.cache \
289 $EGLIBC_ARGS &&
290 make || exit 1
291 make install_root=$sysroot install
292 # The rpc headers (RPC is no longer in eglibc <2.13)
293 #
294 #if [ "$EGLIBC_VERSION" -gt "2.13" ]; then
295 #rpcsvc = "bootparam_prot.x nlm_prot.x rstat.x \
296 #yppasswd.x klm_prot.x rex.x sm_inter.x mount.x \
297 #rusers.x spray.x nfs_prot.x rquota.x key_prot.x"
298 #cd sunrpc/rpcsvc
299 #for r in ${rpcsvc}; do
300 #h=$(echo $r|sed -e's,\.x$,.h,')
301 #rpcgen -h $r -o $h || echo "unable to generate header for $r"
302 #done
303 #fi
304 }
306 # 5. GCC final
307 gcc_final() {
308 init_compile
309 if [ ! -d "gcc-$GCC_VERSION" ]; then
310 echo "Extracting: $GCC_TARBALL"
311 tar xjf $SRC/$GCC_TARBALL
312 fi
313 echo "Configure: $GCC_FINAL_ARGS"
314 rm -rf gcc-build
315 mkdir -p gcc-build && cd gcc-build
316 AR=ar \
317 ../gcc-$GCC_VERSION/configure \
318 --prefix=$tools \
319 --libexec=$tools/lib \
320 --target=$TARGET \
321 --enable-shared \
322 --enable-c99 \
323 --enable-long-long \
324 --enable-__cxa_atexit \
325 --with-system-zlib \
326 --enable-plugin \
327 --disable-multilib \
328 --disable-libssp \
329 --disable-checking \
330 --disable-werror \
331 --with-pkgversion="SliTaz" \
332 --with-bugurl="https://bugs.slitaz.org/" \
333 --with-sysroot=$sysroot \
334 $GCC_FINAL_ARGS &&
335 make AS_FOR_TARGET="${TARGET}-as" \
336 LD_FOR_TARGET="${TARGET}-ld" || exit 1
337 make install
338 echo "cross: GCC final compiled on: $(date)"
339 }
341 #
342 # Commands
343 #
345 case "$1" in
346 howto|man)
347 doc=/usr/share/doc/cookutils/cross.txt
348 [ -f "$doc" ] && less -E $doc ;;
349 info)
350 init_compile
351 CC=${TARGET}-gcc
352 echo -e "\nCross Toolchain information" && separator
353 [ "$config" ] && echo "Config file : $config"
354 cat << EOT
355 Target arch : $ARCH
356 C Compiler : $CC
357 Build directory : $WORK
358 Tools prefix : $tools/bin
359 Arch sysroot : $sysroot
360 EOT
361 separator && echo ""
362 echo "GCC version" && separator
363 if [ -x "$tools/bin/$CC" ]; then
364 $CC -v
365 else
366 echo "No C compiler. To build a toolchain run: cross compile"
367 echo "Missing: $tools/bin/$CC"
368 fi
369 separator && echo "" ;;
370 testsuite)
371 init_compile
372 echo "[COMPILING] $TARGET-gcc -v -Wall -o test.out test.c" \
373 | tee $logdir/testsuite.log
374 echo 'int main() { return 0; }' > test.c
375 $TARGET-gcc -v -Wall -o test.out test.c 2>&1 | tee -a $logdir/testsuite.log
376 if [ -x /usr/bin/file ]; then
377 echo -e "\n[CHECKING] file test.out" | tee -a $logdir/testsuite.log
378 file test.out | tee -a $logdir/testsuite.log
379 fi
380 echo -e "\n[CHECKING] readelf -h test.out" | tee -a $logdir/testsuite.log
381 readelf -h test.out | tee -a $logdir/testsuite.log ;;
382 check)
383 echo "Checking: build system packages"
384 for pkg in slitaz-toolchain mpfr mpfr-dev gmp gmp-dev mpc-library \
385 gawk autoconf; do
386 if [ ! -d "/var/lib/tazpkg/installed/$pkg" ]; then
387 echo "Missing packages: $pkg"
388 if [ -x /usr/sbin/spk-add ]; then
389 spk-add $pkg
390 else
391 tazpkg -gi $pkg
392 fi
393 fi
394 done
395 echo "Using: --with-sysroot=$sysroot" ;;
396 download)
397 download_src ;;
398 show-log)
399 pkg=$2
400 log=$logdir/$pkg.log
401 if [ ! -f "$log" ]; then
402 echo "No log file found for: $pkg" && exit 1
403 fi
404 less -E $log ;;
405 binutils)
406 rm -f $logdir/binutils.log
407 binutils 2>&1 | tee $logdir/binutils.log ;;
408 linux-headers)
409 linux_headers 2>&1 | tee $logdir/linux-headers.log ;;
410 glibc-headers)
411 glibc_headers 2>&1 | tee $logdir/glibc-headers.log ;;
412 gcc-static)
413 gcc_static 2>&1 | tee $logdir/gcc-static.log ;;
414 glibc)
415 glibc 2>&1 | tee $logdir/glibc.log ;;
416 eglibc)
417 eglibc 2>&1 | tee $logdir/eglibc.log ;;
418 gcc-final)
419 gcc_final 2>&1 | tee $logdir/gcc-final.log ;;
420 compile)
421 # Compile the full toolchain.
422 time=$(date +%s)
423 init_compile
424 echo "Compile start: $(date)" | tee $logdir/compile.log
425 download_src
426 binutils 2>&1 | tee $logdir/binutils.log
427 case "$ARCH" in
428 x86_64) glibc_headers 2>&1 | tee $logdir/glibc-headers.log ;;
429 esac
430 gcc_static 2>&1 | tee $logdir/gcc-static.log
431 linux_headers 2>&1 | tee $logdir/linux-headers.log
432 case "$ARCH" in
433 arm) eglibc 2>&1 | tee $logdir/eglibc.log ;;
434 x86_64) glibc 2>&1 | tee $logdir/glibc.log ;;
435 esac
436 gcc_final 2>&1 | tee $logdir/gcc-final.log
437 echo ""
438 echo "Compile end : $(date)" | tee -a $logdir/compile.log
439 time=$(($(date +%s) - $time))
440 sec=$time
441 div=$(( ($time + 30) / 60))
442 [ "$div" != 0 ] && min="~ ${div}m"
443 echo "Build time : ${sec}s $min" | tee -a $logdir/compile.log
444 echo "" ;;
445 clean)
446 echo -n "Removing all source files..."
447 rm -rf $WORK/source && status
448 [ "$log" ] && rm -f $WORK/log/*.log ;;
449 clean-tools)
450 # Remove crap :-)
451 init_compile
452 echo "Cleaning : $tools ($(du -sh $tools | awk '{print $1}'))"
453 for file in share/info share/man share/local
454 do
455 echo -n "Removing : $file"
456 rm -rf $tools/$file && status
457 done
458 echo -n "Stripping : shared libs and binaries"
459 find $tools/bin -type f -exec strip -s '{}' 2>/dev/null \;
460 find $tools/lib -name cc1* -exec strip -s '{}' 2>/dev/null \;
461 find $tools/lib -name lto* -exec strip -s '{}' 2>/dev/null \;
462 find $sysroot -name "*.so*" -exec ${TARGET}-strip -s '{}' 2>/dev/null \;
463 sleep 1 && status
464 echo -n "Tools size : " && du -sh $tools | awk '{print $1}' ;;
465 gen-prebuilt)
466 # Create a prebuilt cross toolchain tarball.
467 init_compile
468 date=$(date "+%Y%m%d")
469 package="slitaz-$ARCH-toolchain-$date"
470 tarball="$package.tar.bz2"
471 cd /cross
472 mkdir -p $package/$ARCH || exit 1
473 echo ""
474 echo -n "Copying $ARCH to: $package"
475 cp -a $ARCH/tools $package/$ARCH
476 cp -a $ARCH/sysroot $package/$ARCH
477 status
478 prebuilt_readme
479 echo -n "Creating prebuilt $ARCH toolchain tarball..."
480 tar cjf $tarball $package
481 status
482 rm -rf $package
483 size=$(du -sh $tarball | awk '{print $1}')
484 echo "Tarball path: $(pwd)/$tarball"
485 echo "Tarball size: $size"
486 echo "" ;;
487 *)
488 usage ;;
489 esac