+#! /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