#!/bin/bash # # This script is the first stage in bootstrapping a Slackware build to # a new platform or architecture. Running with no arguments builds a # cross-development environment, then cross-builds a minimal rootfs. # Once you have this minimal rootfs booted, run stage2 in that rootfs # to build the rest of the bootstrap packages. # # This script assumes that all the needed sources and SlackBuild # scripts are available in $SLACKROOT/source (below). # The resulting rootfs will be build in $ROOTFS (below). # # Note that SLACKSOURCE_LOCAL is for local SlackBuilds that override # the official ones, for example, board-specific kernel packages. # # You may pass a single module name on the command line to rebuild # just that one module. Module names match the big case statement # below. # # For reference, when a package is built multiple times... # # foo-host is the "runs on host" part of a standard cross-compiler # foo-target is the target libraries etc # target-foo is a cross-built target-native # # Note that the "dev" step requires sudo, as it installs special files # in $ROOTFS/dev/ # # The routine is: # - Find the Slackware package source (either in $SLACKSOURCES_LOCAL/ # or in $SLACKROOT/source) # - Run the SlackBuild script with "--prep" parameter which unpacks # source tarballs, does any patching but does not actually compile # (the package source tarball is unpacked into $SLACKSOURCE) # - Cross-compilation happens in $BUILDDIR # # ------------------------------------------------------------ # What are we cross-compiling for? DISTRO=slackware ARCH=armv7hl HWSPEC=tegra KVER=3.2.29 KARCH=arm CHOST="$ARCH-$DISTRO-linux-gnueabi" SLKCFLAGS="-O2 -march=armv7-a -mfpu=vfpv3-d16" SLKLDFLAGS="" LIBDIRSUFFIX="" # Where will we create the cross-compiler binaries? TOP=$PWD # Where do we look for sources? SRCDIR=$(cd $(dirname $0); pwd) # Script to run in the rootfs, on the target: STAGE2=$SRCDIR/stage2.sh # Where to find the package sources; # The symlink '$DISTRO' points to your distro development tree # (with 'source' as a subdirectory): SLACKROOT=$TOP/$DISTRO # Local sources: SLACKSOURCE_LOCAL=$SRCDIR/source.local NUMJOBS=${NUMJOBS:--j7} # Where we configure and build our cross-tools: BUILDDIR=$TOP/builds # Where we extract our original Slackware sources: SLACKSOURCE=$TOP/sources # Where we store our Slackware packages: SLACKBUILD=$TOP/pkgs # Cross-tools have their own specific prefix: PREFIX=$TOP/install # Kernel specifics: KCONFIGDIR=$SLACKSOURCE_LOCAL/k/configs-$ARCH KCONFIG=config-$HWSPEC-$KVER # The cross-compiler target TARGET=$CHOST # This is where the new rootfs will be built ROOTFS=$TOP/rootfs # Needed during build: export CFLAGS="$SLKCFLAGS" export LDFLAGS="$SLKLDFLAGS" if [ -f $SRCDIR/local.conf ]; then . $SRCDIR/local.conf fi # ------------------------------------------------------------ # Sanity checks error() { echo Error: "$@" 1>&2 ERROR=1 } if [ $UID -eq 0 ] then error You must *NOT* run the $(basename $0) script as root! fi if [ ! -d $SLACKROOT/. ] then error SLACKROOT set to $SLACKROOT, but I see no directory there. echo '$'SLACKROOT usually refers to a symlink to a directory with the 'source' directory in it. echo SLACKSOURCE_LOCAL may likewise refer to a directory with local source overrides in it. fi test x"$ERROR" = x"1" && exit 1 unset CC unset CXX unset CFLAGS unset CXXFLAGS unset AR unset LD unset AS # ------------------------------------------------------------ echo echo Running: $0 $* echo Date: $(date) echo Cwd: $(pwd) echo mkdirp() { test -d $1 || mkdir -p $1 } mkdirp $SLACKSOURCE mkdirp $SLACKBUILD mkdirp $ROOTFS mkdirp $PREFIX mkdirp $BUILDDIR mkdirp $TOP/done export PATH=$PREFIX/bin:$PATH mcd() { test -d $1 || mkdir -p $1 cd $1 } getsb() { SOUT=${2:-$SLACKSOURCE} PKGDIR=$(dirname $(find $SLACKSOURCE_LOCAL/ -maxdepth 3 -type f -name $1.SlackBuild)) if [ -n "$PKGDIR" -a -d $PKGDIR ]; then true else PKGDIR=$(dirname $(find $SLACKROOT/source -maxdepth 3 -type f -name $1.SlackBuild)) fi if [ -n "$PKGDIR" -a -d $PKGDIR ]; then echo "Using sources at '$PKGDIR'" rm -rf ${SOUT}/$1 mkdir -p ${SOUT}/$1 cd $PKGDIR ARCH=$ARCH TMP=${SOUT}/$1 sh ${1}.SlackBuild --prep rm -rf ${SOUT}/$1/package-* else echo "Could not find sources for '$1'" exit 1 fi } rgetsb() { getsb $1 $ROOTFS/stage2/sources } set -e BUILD=$(gcc -v 2>&1 | grep Target: | sed 's/.*: //') # These are for cross-tools like gcc, binutils CONFIGARGS="--prefix=$PREFIX --target=$TARGET --with-cpu=cortex-a8 --with-tune=cortex-a8 --with-arch=armv7-a --with-float=hard --with-fpu=vfpv3-d16 --with-abi=aapcs-linux --enable-languages=c,c++ --with-sysroot=$ROOTFS --enable-threads=posix --disable-libssp " TCONFIGARGS="--prefix=/usr --build=$BUILD --host=$TARGET --target=$TARGET --enable-werror=no --enable-cxx --with-cpu=cortex-a8 --with-tune=cortex-a8 --with-arch=armv7-a --with-float=hard --with-fpu=vfpv3-d16 --with-abi=aapcs-linux --enable-languages=c,c++ --enable-threads=posix --disable-libssp " KERNELARGS="ARCH=${KARCH} CROSS_COMPILE=${TARGET}-" # Must use install_root=$ROOTFS on all makes setup_glibc() { GV=$(cd $SLACKSOURCE/glibc ; echo glibc-2*) GLIBCARGS0="--prefix=/usr --with-headers=$ROOTFS/usr/include --enable-kernel=2.6.31 --enable-bind-now --build $BUILD --host $TARGET --disable-profile --cache-file=config.cache --without-cvs --without-selinux --with-elf --without-gd" GLIBCARGS1="$GLIBCARGS0 --enable-add-ons=nptl,ports --disable-sanity-checks --with-tls --with-__thread " GLIBCARGS2="$GLIBCARGS0 --enable-add-ons=nptl,ports --disable-sanity-checks --with-tls --with-__thread " } prefill_glibc_cache() { echo libc_cv_forced_unwind=yes > config.cache echo libc_cv_c_cleanup=yes >> config.cache echo libc_cv_ctors_header=yes >> config.cache } notparallel() { echo .NOTPARALLEL: >> Makefile } fix_la() { for la in $ROOTFS/usr/lib/*$1*.la do if test -f $la then rm $la fi done } #-------------------------------------------------- go() { test -f $TOP/done/$1 && return 0 if "$0" "$@" then date > $TOP/done/$1 else echo echo Module "$@" failed return 1 fi } case "$1" in "" ) go kernel-headers go binutils go gcc-host go glibc-headers go gcc-libgcc go glibc go gcc go dev go u-boot go kernel go x-loader go gmp go mpfr go libmpc #go ppl #go cloog go zlib go t-binutils go t-gcc go bash go make go sed go coreutils go util-linux go tar go gzip go bzip2 go diffutils go findutils go gawk go patch go infozip go which go xz go grep go stage2 ;; "clean" ) set -vx mkdir .quickrm.$$ mv -f $SLACKBUILD $SLACKSOURCE $ROOTFS $PREFIX $BUILDDIR $TOP/done .quickrm.$$ rm -rf .quickrm.$$ & ;; "sync" ) echo Copying built rootfs to tegra-1... rsync -a $ROOTFS/ root@tegra-1:/hardfp/ ;; "test1" ) echo test running go test echo test passed ;; "test" ) echo Testing exit 1 ;; #-------------------------------------------------- # host cross-tools "kernel-headers" ) getsb k mcd $BUILDDIR/kernel cd $SLACKSOURCE/k/linux-$KVER cp $KCONFIGDIR/$KCONFIG .config make $KERNELARGS INSTALL_HDR_PATH=$ROOTFS/usr oldconfig make $KERNELARGS INSTALL_HDR_PATH=$ROOTFS/usr headers_install ;; "binutils" ) getsb binutils mcd $BUILDDIR/binutils $SLACKSOURCE/binutils/binutils-*/configure $CONFIGARGS notparallel make $NUMJOBS make $NUMJOBS install ;; "gcc-host" ) getsb gcc mcd $BUILDDIR/gcc $SLACKSOURCE/gcc/gcc-*/configure $CONFIGARGS --with-headers=$ROOTFS/usr/include notparallel make $NUMJOBS all-host make $NUMJOBS install-host ;; "glibc-headers" ) set -vx getsb glibc setup_glibc #mcd $BUILDDIR/glibc # This directory needs to be inside the source, _and_ called $ARCH : mcd $SLACKSOURCE/glibc/$GV/$ARCH prefill_glibc_cache $SLACKSOURCE/glibc/$GV/configure $GLIBCARGS1 notparallel mkdir -p $ROOTFS/usr/include/{bits,gnu} while ( ! make ARCH=$ARCH cross-compiling=yes install_root=$ROOTFS install-bootstrap-headers=yes install-headers ) ; do continue ; done touch $ROOTFS/usr/include/gnu/stubs.h touch $ROOTFS/usr/include/bits/stdio_lim.h cp $SLACKSOURCE/glibc/$GV/nptl/sysdeps/pthread/pthread.h $ROOTFS/usr/include ( cd $ROOTFS/usr/include/bits sed '/ifndef.*NO_LONG_DOUBLE/,/#endif/d' < mathdef.h > mathdef.h.new mv mathdef.h.new mathdef.h ) # We also build just enough files to link libgcc.so. The fake # libc.so will never actually get used. mkdirp $ROOTFS/usr/lib make $NUMJOBS ARCH=$ARCH cross-compiling=yes csu/subdir_lib cp csu/crt*.o $ROOTFS/usr/lib $TARGET-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o $ROOTFS/usr/lib/libc.so ;; "gcc-libgcc" ) getsb gcc mcd $BUILDDIR/gcc $SLACKSOURCE/gcc/gcc-*/configure $CONFIGARGS --with-headers=$ROOTFS/usr/include notparallel make $NUMJOBS all-target-libgcc make $NUMJOBS install-target-libgcc ;; "glibc" ) getsb glibc setup_glibc #mcd $BUILDDIR/glibc # This directory needs to be inside the source, _and_ called $ARCH : mcd $SLACKSOURCE/glibc/$GV/$ARCH prefill_glibc_cache $SLACKSOURCE/glibc/$GV/configure $GLIBCARGS2 notparallel make $NUMJOBS ARCH=$ARCH cross-compiling=yes make $NUMJOBS ARCH=$ARCH cross-compiling=yes install_root=$ROOTFS install ( cd $ROOTFS/usr/include/bits sed '/ifndef.*NO_LONG_DOUBLE/,/#endif/d' < mathdef.h > mathdef.h.new mv mathdef.h.new mathdef.h ) ;; "gcc" ) getsb gcc mcd $BUILDDIR/gcc $SLACKSOURCE/gcc/gcc-*/configure $CONFIGARGS --with-headers=$ROOTFS/usr/include notparallel make $NUMJOBS make $NUMJOBS install mcd $ROOTFS/lib/gcc rsync -av $PREFIX/lib/gcc/ $ROOTFS/lib/gcc/ rsync -av $PREFIX/$TARGET/lib/ $ROOTFS/lib/ ;; #-------------------------------------------------- # target boot support "dev" ) #rsync -av $TOP/dev-template/ $ROOTFS/ mkdirp $ROOTFS/proc mkdirp $ROOTFS/sys mcd $ROOTFS/tmp chmod 1777 . mcd $ROOTFS/dev sudo mknod null c 1 3 sudo mknod zero c 1 5 sudo mknod tty c 5 0 sudo mknod console c 5 1 sudo mknod sda b 8 0 sudo mknod sda1 b 8 1 sudo mknod sda2 b 8 2 sudo mknod sda3 b 8 3 sudo mknod sda4 b 8 4 sudo mknod mmcblk0 b 179 0 sudo mknod mmcblk0p1 b 179 1 sudo mknod mmcblk0p2 b 179 2 sudo mknod mmcblk0p3 b 179 3 sudo mknod mmcblk0p4 b 179 4 sudo mknod mmcblk1 b 179 48 sudo mknod mmcblk1p1 b 179 49 sudo mknod mmcblk1p2 b 179 50 sudo mknod mmcblk1p3 b 179 51 sudo mknod mmcblk1p4 b 179 52 sudo mknod ttyO0 c 253 0 sudo mknod ttyO1 c 253 1 sudo mknod ttyO2 c 253 2 sudo mknod ttyO3 c 253 3 sudo chmod a+rw null zero ;; "kernel" ) getsb k mcd $BUILDDIR/kernel echo copying kernel sources to build area... rsync -a --delete $SLACKSOURCE/k/linux-$KVER . cd linux-$KVER cp $KCONFIGDIR/$KCONFIG .config make $NUMJOBS ARCH=$KARCH CROSS_COMPILE=${TARGET}- silentoldconfig make $NUMJOBS ARCH=$KARCH CROSS_COMPILE=${TARGET}- uImage make $NUMJOBS ARCH=$KARCH CROSS_COMPILE=${TARGET}- modules make $NUMJOBS ARCH=$KARCH CROSS_COMPILE=${TARGET}- INSTALL_MOD_PATH=$ROOTFS modules_install mkdirp $ROOTFS/boot mkdirp $ROOTFS/lib/firmware cp arch/$KARCH/boot/uImage $ROOTFS/boot ;; "x-loader" ) if [ ! -f $BUILDDIR/x-loader/README ] then cd $BUILDDIR git clone git://gitorious.org/x-loader/x-loader.git fi cd $BUILDDIR/x-loader sed s/-Werror// cpu/omap4/config.mk > cpu/omap4/config.mk.new mv cpu/omap4/config.mk.new cpu/omap4/config.mk make $NUMJOBS distclean make $NUMJOBS CROSS_COMPILE=${TARGET}- omap4430panda_config make $NUMJOBS CROSS_COMPILE=${TARGET}- mkdirp $ROOTFS/boot cp MLO $ROOTFS/boot ;; "u-boot" ) # git git://git.denx.de/u-boot.git if [ ! -f $BUILDDIR/u-boot/README ] then cd $BUILDDIR git clone git://git.denx.de/u-boot.git fi cd $BUILDDIR/u-boot make $NUMJOBS distclean make $NUMJOBS CROSS_COMPILE=${TARGET}- omap4_panda_config make $NUMJOBS CROSS_COMPILE=${TARGET}- u-boot.img mkdirp $ROOTFS/boot cp u-boot.img $ROOTFS/boot/u-boot.img ;; "djtest" ) cd $TOP/djtest make $NUMJOBS make $NUMJOBS install ROOTFS=${ROOTFS} ;; #-------------------------------------------------- # target-side libraries gmp | mpfr | ppl ) L=$1 getsb $L mcd $BUILDDIR/t-$L $SLACKSOURCE/$L/${L}-*/configure $TCONFIGARGS make $NUMJOBS make $NUMJOBS install DESTDIR=${ROOTFS} fix_la $L ;; libmpc ) getsb libmpc mcd $BUILDDIR/t-libmpc $SLACKSOURCE/libmpc/mpc-*/configure $TCONFIGARGS make make $NUMJOBS install DESTDIR=${ROOTFS} fix_la mpc ;; zlib ) getsb zlib mcd $BUILDDIR/t-zlib rsync -av $SLACKSOURCE/zlib/zlib-*/ ./ CHOST=${TARGET} \ prefix=/usr \ ./configure make make $NUMJOBS install DESTDIR=${ROOTFS} fix_la zlib ;; "cloog" ) getsb cloog mcd $BUILDDIR/t-cloog $SLACKSOURCE/cloog/cloog-*/configure $TCONFIGARGS --with-ppl make $NUMJOBS make $NUMJOBS install DESTDIR=${ROOTFS} fix_la cloog ;; #-------------------------------------------------- # target-side applications "bash" ) getsb bash mcd $BUILDDIR/bash cat < config.cache bash_cv_func_ctype_nonascii=yes bash_cv_opendir_not_robust=no bash_cv_ulimit_maxfds=yes bash_cv_func_sigsetjmp=present bash_cv_printf_a_format=yes bash_cv_job_control_missing=present bash_cv_sys_named_pipes=present bash_cv_unusable_rtsigs=no EOF $SLACKSOURCE/bash/bash-*/configure --prefix=/ --cache-file=config.cache --build=$BUILD --host=$TARGET make $NUMJOBS make $NUMJOBS install DESTDIR=${ROOTFS} (cd $ROOTFS/bin; ln -s bash sh) ;; "t-binutils" ) getsb binutils mcd $BUILDDIR/t-binutils $SLACKSOURCE/binutils/binutils-*/configure $TCONFIGARGS notparallel make $NUMJOBS make $NUMJOBS install DESTDIR=${ROOTFS} ;; "t-gcc" ) getsb gcc mcd $BUILDDIR/t-gcc sed -i -e '/^PCHFLAGS/s/ $(CXXFLAGS)/ -nostdinc++ $(CXXFLAGS)/' $SLACKSOURCE/gcc/gcc-*/libstdc++-v3/include/Makefile.in $SLACKSOURCE/gcc/gcc-*/configure $TCONFIGARGS notparallel make make install DESTDIR=${ROOTFS} ;; make | tar | gzip | diffutils | findutils | gawk | which | grep ) getsb $1 mcd $BUILDDIR/$1 $SLACKSOURCE/${1}/${1}-*/configure $TCONFIGARGS notparallel test -d tools/gnulib/lib && make $NUMJOBS V=1 -C tools/gnulib/lib make $NUMJOBS V=1 make $NUMJOBS install DESTDIR=${ROOTFS} ;; sed ) getsb sed mcd $BUILDDIR/sed $SLACKSOURCE/sed/sed-*/configure $TCONFIGARGS notparallel # Touch sed.1 so that it will not be built. # The makefile in the sed/doc directory attempts to run the # built sed binary in order to extract the --help output, but # this fails because the sed binary is a cross-tool. touch doc/sed.1 make $NUMJOBS V=1 make $NUMJOBS install DESTDIR=${ROOTFS} ;; patch ) getsb patch mcd $BUILDDIR/patch cat < config.cache ac_cv_func_strnlen_working=yes EOF $SLACKSOURCE/patch/patch-*/configure $TCONFIGARGS --cache-file=config.cache notparallel make $NUMJOBS V=1 make $NUMJOBS install DESTDIR=${ROOTFS} ;; xz ) getsb xz mcd $BUILDDIR/xz $SLACKSOURCE/xz/xz-*/configure \ --prefix=/usr \ --build=$BUILD \ --host=$TARGET \ notparallel make $NUMJOBS V=1 make $NUMJOBS install DESTDIR=${ROOTFS} ;; infozip ) getsb infozip mcd $BUILDDIR/infozip rsync -av $SLACKSOURCE/infozip/unzip*/ ./ make $NUMJOBS -f unix/Makefile \ CC=${TARGET}-gcc \ AS=${TARGET}-as \ AR=${TARGET}-ar \ STRIP=${TARGET}-strip \ RANLIB=${TARGET}-ranlib \ prefix=/usr \ generic make $NUMJOBS -f unix/Makefile \ CC=${TARGET}-gcc \ AS=${TARGET}-as \ AR=${TARGET}-ar \ STRIP=${TARGET}-strip \ RANLIB=${TARGET}-ranlib \ prefix=${ROOTFS}/usr \ install ;; coreutils ) getsb coreutils mcd $BUILDDIR/coreutils cat < config.cache fu_cv_sys_stat_statfs2_bsize=yes gl_cv_func_working_mkstemp=yes EOF $SLACKSOURCE/coreutils/coreutils-*/configure $TCONFIGARGS --cache-file=config.cache PERL=NO notparallel mkdir -p man for i in $(cd $SLACKSOURCE/coreutils/coreutils-*/man; echo *.x) do base=`echo $i | sed 's/\.x//'` touch man/$base.1 done make $NUMJOBS V=1 make $NUMJOBS install DESTDIR=${ROOTFS} ;; util-linux ) getsb util-linux mcd $BUILDDIR/util-linux $SLACKSOURCE/util-linux/util-linux-*/configure $TCONFIGARGS --without-ncurses --disable-wall notparallel make $NUMJOBS V=1 make $NUMJOBS install DESTDIR=${ROOTFS} ;; bzip2 ) getsb bzip2 mcd $BUILDDIR/bzip2 rsync -av $SLACKSOURCE/bzip2/bzip2-*/ ./ make $NUMJOBS \ CC=${TARGET}-gcc \ AR=${TARGET}-ar \ RANLIB=${TARGET}-ranlib \ PREFIX=/usr \ CFLAGS="$CFLAGS -fpic -fPIC" \ libbz2.a bzip2 bzip2recover make $NUMJOBS \ CC=${TARGET}-gcc \ AR=${TARGET}-ar \ RANLIB=${TARGET}-ranlib \ PREFIX=${ROOTFS}/usr \ install # the installation makes symbols links with our host's paths # in them, we need to redo those. cd $ROOTFS/usr/bin rm bzless; ln -s bzmore bzless rm bzfgrep; ln -s bzgrep bzfgrep rm bzcmp; ln -s bzdiff bzcmp rm bzegrep; ln -s bzgrep bzegrep ;; stage2 ) # install source trees in rootfs, so stage2 will have them for # its builds. mkdirp $ROOTFS/stage2 rsync -a $SRCDIR/recipe.d $ROOTFS/stage2/ for PKG in $ROOTFS/stage2/recipe.d/[0-9][0-9][0-9][0-9]-* do PKG=$(echo $PKG | sed "s/.*\\/[0-9][0-9][0-9][0-9]-//") echo "Installing sources for $PKG" rgetsb $PKG done ( cd $ROOTFS/stage2/sources/sqlite/sqlite-* test -f sqlite3.h.stage1 \ || tclsh tool/mksqlite3h.tcl . > sqlite3.h.stage1 ) cp $STAGE2 $ROOTFS/stage2/stage2.sh ( echo TARGET=$TARGET echo TCONFIGARGS=\"$TCONFIGARGS\" \ | sed 's/--build=[^ ]*//' \ | sed 's/--host=[^ ]*//' \ | sed 's/--target=[^ ]*//' ) > $ROOTFS/stage2/local.conf ;; esac exit 0