cookutils view cross @ rev 403

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