cookutils view cross @ rev 449

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