cookutils view cross @ rev 408

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