So I pushed that pax-utils.
- Improved Makefile handling. (vapier)
- QA_TEXTREL/QA_EXECSTACK/QA_WX_LOAD exempt filtering flags. (kevquinn)
- Handle versioned symbols correctly on unstripped ELF files when using the -s flag.
- Do not assume it is ok to read from stdin if the -l -p flags were given. (solar)
Now it’s time to get back to some cross compiling goodness. Well one thing I know about myself is anything I do I tend todo in excess. So I figure why build 1 cross compiler when you can build them all. Why merge into 1 place when you can reasonable test cross compiling for all arches.. Well that’s just what I did and am doing.
Little script I’m using for just this task..
#!/bin/sh # Copyright 2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: <solar@gentoo.org> CFLAGS="-Os -pipe" CBUILD=$(portageq envvar CHOST) CXXFLAGS="${CFLAGS}" export PYTHON_DONTCOMPILE=1 USE_SAVE="${USE}" if [ ! -x /usr/bin/qlist ]; then echo "please emerge portage-utils" exit 1 fi gcc_executables=$(qlist -oeCI gcc| sort -u | grep ^cross- | sed s/cross-//g | tr / -) opts="$@" for x in "$@"; do if [[ $x == "--libc" ]]; then opts="${opts/${x}/}" DO_LIBC=1 do_libc=1 fi if [[ "${lastopt}" == "--target" ]]; then ctarget_only="${x}" opts="${opts/${x}/}" opts="${opts/${lastopt}/}" fi lastopt=${x} done function cross_env_update() { mkdir -p ${ROOT}/etc for lpath in /usr/local/lib /usr/${CTARGET}/lib /usr/lib/gcc/${CTARGET}/$(${CTARGET}-gcc -dumpversion) /usr/lib/libstdc++-v3/; do echo "${lpath}" >> ${ROOT}/etc/ld.so.conf done } function cmerge() { CHOST=${1} shift export CTARGET=${CHOST} ARCH=$(echo ${CTARGET} | cut -d '-' -f 1) CC=${CTARGET}-gcc CXX=${CTARGET}-g++ PKGDIR=${HOME}/packages/${CHOST} ROOT="${HOME}/ROOT/${CHOST}" LDFLAGS="-L${ROOT}/lib -L${ROOT}/usr/lib" do_libc=${DO_LIBC} unset ELIBC case ${CTARGET} in *-linux-gnu) ELIBC=glibc;; *-linux-uclibc) ELIBC=uclibc;; avr) ELIBC=avr-libc;; esac export ELIBC [[ $ELIBC == "" ]] && do_libc=0 USE="${ARCH} ${USE_SAVE}" case ${ARCH} in armeb) ARCH=arm;; s390x) ARCH=s390;; mips*) ARCH=mips;; powerpc64) ARCH=ppc64;; sparc*) ARCH=sparc;; powerpc) ARCH=ppc;; hppa*) ARCH=hppa;; sh4*|sheb) ARCH=sh;; x86_64) ARCH=amd64;; avr|ee|iop|cris) ARCH="x86";; i?86) ARCH=x86;; esac ACCEPT_KEYWORDS="${ARCH}" [[ "${unstable}" != "" ]] && ACCEPT_KEYWORDS="${ACCEPT_KEYWORDS} ~${ARCH}" USE="-* ${ARCH} ${USE} elibc_${ELIBC} multicall make-symlinks" export ARCH ACCEPT_KEYWORDS CFLAGS CXXFLAGS LDFLAGS ROOT CBUILD CHOST CTARGET CC CXX PKGDIR USE mkdir -p ${ROOT}/etc if [[ $ELIBC != "" ]]; then if [ -e ${ROOT}/etc/ld.so.conf ]; then if [ "$(md5sum ${ROOT}/etc/ld.so.conf|awk '{print $1}')" == "b18efa8c9f95b6aecc0974c0f54d8bb9" ]; then touch ${ROOT}/etc/ld.so.conf cross_env_update fi else cross_env_update fi fi if [[ "$do_libc" == 1 ]]; then emerge -b cross-${CHOST}/${ELIBC} ${opts} else emerge -b ${opts} fi unset ARCH ACCEPT_KEYWORDS LDFLAGS ROOT CHOST CTARGET CC CXX PKGDIR USE ELIBC } if [[ "$1" == "" ]]; then echo "$0: <opts> <emerge opts>" echo " --libc" echo " --target <chost>" echo " --libc --target i386-gentoo-linux-uclibc busybox -pv" exit 1 fi for gnugcc in ${gcc_executables}; do [ -e /usr/bin/${gnugcc} ] || { echo bummer $gnugcc ; continue; } # include=$($gnugcc -print-file-name=) [[ $ctarget_only != "" ]] && [[ ${gnugcc/-gcc/} != $ctarget_only ]] && continue cmerge "${gnugcc/-gcc/}" "$@" done
A blind run at building busybox and libc for just about every chost combo yields the following results. Anything marked N is something that failed. R means it installed of course.
tinderbox ~ # ./cmerge -qpv busybox [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/alpha-gentoo-linux-uclibc/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/alpha-unknown-linux-gnu/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/arm-gentoo-linux-uclibc/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/arm-softfloat-linux-gnu/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/arm-softfloat-linux-uclibc/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/arm-unknown-linux-gnu/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/armeb-gentoo-linux-uclibc/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/armeb-softfloat-linux-gnu/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/armeb-softfloat-linux-uclibc/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/armeb-unknown-linux-gnu/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/avr/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/cris-gentoo-linux-uclibc/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/ee/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/hppa-unknown-linux-gnu/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/hppa1.1-unknown-linux-gnu/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/hppa2.0-unknown-linux-gnu/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/hppa64-unknown-linux-gnu/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/i386-gentoo-linux-uclibc/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/i386-pc-linux-gnu/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/i686-gentoo-linux-uclibc/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/ia64-unknown-linux-gnu/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/iop/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/m68k-gentoo-linux-uclibc/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/m68k-unknown-linux-gnu/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/mips-gentoo-linux-uclibc/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/mips-unknown-linux-gnu/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/mips64-unknown-linux-gnu/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/mips64el-unknown-linux-gnu/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/mipsel-gentoo-linux-uclibc/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/mipsel-unknown-linux-gnu/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/powerpc-gentoo-linux-uclibc/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/powerpc-softfloat-linux-gnu/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/powerpc-softfloat-linux-uclibc/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/powerpc-unknown-linux-gnu/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/powerpc64-unknown-linux-gnu/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/s390-ibm-linux-gnu/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/s390x-ibm-linux-gnu/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/sh-gentoo-linux-uclibc/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/sh-unknown-linux-gnu/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/sh4-gentoo-linux-uclibc/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/sh4-unknown-linux-gnu/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/sh4eb-gentoo-linux-uclibc/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/sh4eb-unknown-linux-gnu/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/sheb-gentoo-linux-uclibc/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/sheb-unknown-linux-gnu/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/sparc-gentoo-linux-uclibc/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/sparc-unknown-linux-gnu/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/sparc64-unknown-linux-gnu/ [ebuild N ] sys-apps/busybox-1.1.0 to /root/ROOT/x86_64-gentoo-linux-uclibc/ [ebuild R ] sys-apps/busybox-1.1.0 to /root/ROOT/x86_64-pc-linux-gnu/
Well that’s cool and all. But how to test stuff? Thats where qemu comes to the rescue.. Few mins of hacking and poof we come up with a little something something like so.
#!/bin/sh pkg_genext2fs() { if ! type -p genext2fs > /dev/null; then echo "no genext2fs" return 1 fi cd $1 || return 1 rom=/rom mkdir -p {usr/,}{s,}bin etc/init.d proc/self dev/shm root tmp ./${rom} chmod 700 root chmod 1777 tmp ################ cat <<EOF > etc/init.d/rcS #!/bin/sh rom=$rom mount -a mount tmpfs \$rom -t tmpfs mkdir -p \$rom/proc \$rom/dev \$rom/ro \$rom/tmp mount -o bind /dev \$rom/dev mount -o bind /proc \$rom/proc busybox cp -a bin etc lib root sbin usr \$rom/ chmod 1777 \$rom/tmp pivot_root \$rom/ \$rom/ro EOF ################ chmod +x etc/init.d/rcS if [ ! -L proc/self/exe ]; then cd proc/self ln -s /bin/busybox exe if [ -e /proc/self/fd ] ; then ln -fs /proc/self/fd fd 2> /dev/null ln -fs fd/0 stdin ln -fs fd/1 stdout ln -fs fd/2 stderr fi cd ../../ fi cd etc ln -sf ../proc/mounts mtab grep -v ^# /etc/protocols > protocols cd .. cd dev ln -sf /proc/kcore core # ttys for i in `seq 0 9`; do [ ! -e tty$i ] && mknod tty$i c 4 $i done [ ! -e tty ] && (mknod -m 666 tty c 5 0 2> /dev/null || echo cant mknod for tty) [ ! -e null ] && (mknod -m 666 null c 1 3 2> /dev/null || echo cant mknod for null) [ ! -e zero ] && (mknod -m 666 zero c 1 5 2> /dev/null || echo cant mknod for zero) [ ! -e urandom ] && (mknod -m 644 urandom c 1 9 2> /dev/null || echo cant mknod for urandom) [ ! -e random ] && mknod random c 1 8 [ ! -e console ] && mknod console c 5 1 [ ! -e full ] && mknod full c 1 7 [ ! -e kmem ] && mknod kmem c 1 2 [ ! -e mem ] && mknod mem c 1 1 [ ! -e port ] && mknod port c 1 4 # IDE devs [ ! -e hda ] && mknod hda b 3 0 [ ! -e hdb ] && mknod hdb b 3 64 [ ! -e hdc ] && mknod hdc b 22 0 [ ! -e hdd ] && mknod hdd b 22 64 # loop devs for i in `seq 0 7`; do [ ! -e loop$i ] && mknod loop$i b 7 $i; done # ram devs for i in `seq 0 9`; do [ ! -e ram$i ] && mknod ram$i b 1 $i ; done [ ! -L ram ] && ln -s ram1 ram # virtual console screen devs for i in `seq 0 9`; do [ ! -e vcs$i ] && mknod vcs$i b 7 $i; done chown root:tty tty 2> /dev/null chown root:sys null zero 2> /dev/null cd - ################ ## /etc/fstab ## ################ cat <<EOF > etc/fstab #/dev/root / ro,defaults defaults 0 0 proc /proc proc defaults 0 0 #none /dev devfs defaults 0 0 devpts /dev/pts devpts defaults,gid=5,mode=620 0 0 tmpfs /tmp tmpfs defaults 0 0 tmpfs $rom tmpfs defaults 0 0 tmpfs /dev/shm tmpfs defaults 0 0 EOF ################ cd ${TOPDIR} || return 1 cd $1 || return 1 scanelf -qnBR . | grep libgcc REALSIZE=$(LANG=C du ./ -s -c -k | grep total | awk '{print $1}') ADDTOROOTSIZE=$([ $REALSIZE -ge 20000 ] && echo 16384 || echo 16) SIZE=$(( $REALSIZE + $ADDTOROOTSIZE )) INODES=$(($(find ${DESTDIR} | wc -l) + 400)) genext2fs -i ${INODES} -b ${SIZE} -q -d . $2 cd $TOPDIR } TOPDIR=$PWD tarballs="$@" [[ $1 == "" ]] && tarballs="$(ls *.tar.bz2)" for x in ${tarballs} ; do d=$(basename $x .tar.bz2) cd $TOPDIR pkg_genext2fs ${d} $TOPDIR/${d}.ext2 [ $? != 0 ] && echo WTF $? done
End result..
arm-gentoo-linux-uclibc.ext2 armeb-softfloat-linux-uclibc.ext2 mips-gentoo-linux-uclibc.ext2 powerpc-softfloat-linux-uclibc.ext2
arm-softfloat-linux-uclibc.ext2 i386-gentoo-linux-uclibc.ext2 mipsel-gentoo-linux-uclibc.ext2 sh4-gentoo-linux-uclibc.ext2
armeb-gentoo-linux-uclibc.ext2 i686-gentoo-linux-uclibc.ext2 powerpc-gentoo-linux-uclibc.ext2
As we can see uClibc is clearly better at everything. In this case being cross compiled and producing all the parts needed in order to be booted..
wget http://tinderbox.x86.dev.gentoo.org/portage/local/misc/i386-gentoo-linux-uclibc.ext2
qemu -kernel /boot/bzImage -append “root=/dev/hda init=/sbin/init rootfstype=ext2 ro” i386-gentoo-linux-uclibc.ext2
Sweet worked like a charm..
Next task is to mass x-compile some kernels for other arches and see what qemu can do for us..