cookutils view cross @ rev 446

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