-#! /bin/sh -e
-
-badp=nil
-myarch=$(dpkg-architecture -qDEB_HOST_ARCH)
-while getopts "a:" opt; do
- case $opt in
- a) myarch=$OPTARG ;;
- *) badp=t ;;
- esac
-done
-shift $(( $OPTIND - 1 ))
-case $# in 0) badp=t ;; esac
-case $badp in
- t)
- cat >&2 <<EOF
-usage: $0 [-a MYARCH] DIST ...
-EOF
- exit 1
- ;;
-esac
-for arg in "$@"; do
- case $arg in *-*) echo >&2 "$0: bad arch name \`$arg'"; exit 1 ;; esac
-done
-mymulti=$(dpkg-architecture -a$myarch -qDEB_HOST_MULTIARCH)
-
-cross_archs="arm-linux-gnueabi arm-linux-gnueabihf aarch64-linux-gnu"
-cross_pkgs="
- apt bash ccache coreutils dash eatmydata fakeroot findutils
- gnupg gpgv gzip m4 make mawk qemu-user-static sed tar xz-utils"
-for a in $cross_archs; do
- for i in gcc g++ binutils; do
- cross_pkgs="$cross_pkgs $i-$a"
- done
-done
-cross_pkgs=$(echo $cross_pkgs)
-
-wanted="
- /usr/bin/ apt apt-cache apt-config apt-get apt-key apt-mark
- /usr/lib/apt/ methods/ solvers/
-
- /bin/ cat chgrp chown cp date dd df dir echo false ln ls mkdir
- mknod mktemp mv pwd readlink rm rmdir sleep stty sync touch
- true uname vdir
- /usr/bin/ [ arch b2sum base32 base64 basename chcon cksum comm
- csplit cut dircolors dirname du env expand expr factor fmt
- fold groups head hostid id install join link logname md5sum
- mkfifo nice nl nohup nproc numfmt od paste pathchk pinky pr
- printenv printf ptx realpath runcon seq sha1sum sha224sum
- sha256sum sha384sum sha512sum shred shuf sort split stat
- stdbuf sum tac tail tee test timeout tr truncate tsort tty
- unexpand uniq unlink users wc who whoami yes
- /usr/lib/$mymulti/ coreutils/
-
- /lib/$mymulti/ libnss_*.so.*
-
- /usr/bin/ gpg gpgv gpgconf kbxutil watchgnupg
-
- /usr/bin/ qemu-*-static
-
- /bin/ bash dash gzip sed tar
- /usr/bin/ ccache find m4 make mawk xargs xz
- /usr/lib/$mymulti/ libeatmydata.so* libfakeroot/
-
- /etc/ld.so.conf.d/ $mymulti.conf fakeroot*.conf"
-
-for a in $cross_archs; do
- wanted="$wanted
-
- /usr/bin/$a- addr2line ar as c++filt dwp elfedit gprof ld ld.*
- nm objcopy objdump ranlib readelf size strings strip
-
- /usr/bin/$a- cpp gcc g++ gcov gcov-dump gcov-tool gprof
- gcc-ar gcc-nm gcc-ranlib
- /usr/lib/gcc-cross/$a/ ..."
-done
-wanted=$(echo $wanted)
-
-case $myarch in
- i386) elfsig=7f454c46010101??0000000000000000????0300 ;;
- amd64) elfsig=7f454c46020101??0000000000000000????3e00 ;;
- *) echo >&2 "$0: unsupported local arch \`$myarch'"; exit 1 ;;
-esac
-
-chase_link () {
- p=$1 d=
- while :; do
- case $p in
- "") break ;;
- "/"*) p=${p#/} ;;
- "./"*) p=${p#./} ;;
- "../"*)
- p=${p#../}
- case $d in */*) d=${d%/*} ;; *) d= ;; esac
- ;;
- *)
- case $p in */*) f=${p%%/*} p=${p#*/} ;; *) f=$p p="" ;; esac
- d=${d:+$d/}$f
- ;;
- esac
- if ! [ -e "$crossnew$d" ] && ! [ -L "$crossnew$d" ]; then
- if [ -d "$root/$d" ] && ! [ -L "$root/$d" ]; then
- mkdir "$crossnew$d"
- else
- echo >&2 "$0: copy /$d to satisfy symlinks"
- rsync -aHR $root/./$d $crossnew
- fi
- fi
- if [ -L "$crossnew$d" ]; then
- t=$(readlink "$crossnew$d")
- case $t in /*) t=${t#/} d= ;; esac
- case $d in */*) d=${d%/*} ;; *) d= ;; esac
- p=$t${p:+/$p}
- fi
- done
-}
-
-exec 3>&1
-for d in "$@"; do
- echo >&2 "$0: create $d snapshot"
- sess=$(schroot -bc$d-$myarch 3>&-)
- schroot -uroot -rc$sess -- eatmydata sh -ec "
- apt-get update
- apt-get -y upgrade
- apt-get -y install $cross_pkgs"
- crossdir=/usr/local.schroot/cross/$d-$myarch/
- crossold=${crossdir%/}.old/ crossnew=${crossdir%/}.new/
- rm -rf $crossnew; mkdir -p $crossnew
-
- root=/schroot/$sess/fs; dir=/
- for i in $wanted; do
- case $i in
- /*)
- dir=$i
- ;;
- *)
- case $i in ...) f=$dir ;; *) f=$dir$i ;; esac
- echo >&2 "$0: copy $f"
- rsync -aHR $root/.$f $crossnew
- ;;
- esac
- done
-
- find $crossnew -xtype l -print | while read i; do
- chase_link ${i#$crossnew}
- done
-
- find $crossnew -type f -print | while read i; do
- sig=$(head -c20 "$i" | bincode -e -m0 -flowerc hex)
- case $sig in $elfsig) echo "$i" ;; esac
- done >$root/private/QUEUE.in
-
- counter=0
- cp $root/private/QUEUE.in /tmp/mdw/queue.in.$counter
-
- while [ -s $root/private/QUEUE.in ]; do
- schroot -uroot -rc$sess -- eatmydata sh -ec '
- prog=$1
- while read i; do
- echo >&2 "$prog: scanning binary $i"
- ldd "$i" | while read a b c d; do
- case $a:$b:$c:$d in
- not:a:dynamic:executable) ;;
- statically:linked::) ;;
- /*) echo "$a" ;;
- *:=\>:/*) echo "$c" ;;
- linux-*) ;;
- *) echo >&2 "$i: unable to find $a"; exit 2 ;;
- esac
- done
- done </private/QUEUE.in >/private/QUEUE.out' - "$0"
-
- cp $root/private/QUEUE.out /tmp/mdw/queue.out.$counter
- counter=$(( $counter + 1 ))
-
- while read i; do
- if [ -e "$crossnew$i" ] || [ -L "$crossnew$i" ]
- then continue; fi
- if [ -d "$root$i" ]; then continue; fi
- echo >&2 "$0: copy $i"
- rsync -aHR $root/.$i $crossnew >&3
- chase_link $i >&3
- sig=$(head -c20 $crossnew$i | bincode -e -m0 -flowerc hex)
- case $sig in $elfsig) echo "$i" ;; esac
- done <$root/private/QUEUE.out >$root/private/QUEUE.in
-
- cp $root/private/QUEUE.in /tmp/mdw/queue.in.$counter
-
- done
-
- echo >&2 "$0: establish TOOLCHAIN"
- for a in $cross_archs; do
- tooldir=$crossnew/TOOLCHAIN/$a
- mkdir -p $tooldir
- for i in $crossnew/usr/bin/$a-*; do
- t=${i#$crossnew/usr/bin/}
- mv $i $tooldir/$t
- ln -s $t $tooldir/${t#$a-}
- done
- done
- mkdir $crossnew/TOOLCHAIN/lib
- ln -s ../../usr/lib/gcc-cross $crossnew/TOOLCHAIN/lib/
-
- echo >&2 "$0: establish QEMU"
- mkdir $crossnew/QEMU
- mv $crossnew/usr/bin/qemu-*-static $crossnew/QEMU/
-
- echo >&2 "$0: remove snapshot"
- schroot -ec$sess 3>&-
- if [ -d $crossdir ]; then mv $crossdir $crossold; fi
- mv $crossnew $crossdir; rm -rf $crossold
- echo >&2 "$0: committed $crossdir"
-done