chiark / gitweb /
f29893ee25f6f095cfbdd8bfad74f3f71125cc31
[distorted-chroot] / mess / maint / update-cross-tools
1 #! /bin/sh -e
2
3 badp=nil
4 myarch=$(dpkg-architecture -qDEB_HOST_ARCH)
5 while getopts "a:" opt; do
6   case $opt in
7     a) myarch=$OPTARG ;;
8     *) badp=t ;;
9   esac
10 done
11 shift $(( $OPTIND - 1 ))
12 case $# in 0) badp=t ;; esac
13 case $badp in
14   t)
15     cat >&2 <<EOF
16 usage: $0 [-a MYARCH] DIST ...
17 EOF
18     exit 1
19     ;;
20 esac
21 for arg in "$@"; do
22   case $arg in *-*) echo >&2 "$0: bad arch name \`$arg'"; exit 1 ;; esac
23 done
24 mymulti=$(dpkg-architecture -a$myarch -qDEB_HOST_MULTIARCH)
25
26 cross_archs="arm-linux-gnueabi arm-linux-gnueabihf aarch64-linux-gnu"
27 cross_pkgs="
28         apt bash ccache coreutils dash eatmydata fakeroot findutils
29         gnupg gpgv gzip m4 make mawk qemu-user-static sed tar xz-utils"
30 for a in $cross_archs; do
31   for i in gcc g++ binutils; do
32     cross_pkgs="$cross_pkgs $i-$a"
33   done
34 done
35 cross_pkgs=$(echo $cross_pkgs)
36
37 wanted="
38         /usr/bin/ apt apt-cache apt-config apt-get apt-key apt-mark
39         /usr/lib/apt/ methods/ solvers/
40
41         /bin/ cat chgrp chown cp date dd df dir echo false ln ls mkdir
42                 mknod mktemp mv pwd readlink rm rmdir sleep stty sync touch
43                 true uname vdir
44         /usr/bin/ [ arch b2sum base32 base64 basename chcon cksum comm
45                 csplit cut dircolors dirname du env expand expr factor fmt
46                 fold groups head hostid id install join link logname md5sum
47                 mkfifo nice nl nohup nproc numfmt od paste pathchk pinky pr
48                 printenv printf ptx realpath runcon seq sha1sum sha224sum
49                 sha256sum sha384sum sha512sum shred shuf sort split stat
50                 stdbuf sum tac tail tee test timeout tr truncate tsort tty
51                 unexpand uniq unlink users wc who whoami yes
52         /usr/lib/$mymulti/ coreutils/
53
54         /lib/$mymulti/ libnss_*.so.*
55
56         /usr/bin/ gpg gpgv gpgconf kbxutil watchgnupg
57
58         /usr/bin/ qemu-*-static
59
60         /bin/ bash dash gzip sed tar
61         /usr/bin/ ccache find m4 make mawk xargs xz
62         /usr/lib/$mymulti/ libeatmydata.so* libfakeroot/
63
64         /etc/ld.so.conf.d/ $mymulti.conf fakeroot*.conf"
65
66 for a in $cross_archs; do
67   wanted="$wanted
68
69         /usr/bin/$a- addr2line ar as c++filt dwp elfedit gprof ld ld.*
70                 nm objcopy objdump ranlib readelf size strings strip
71
72         /usr/bin/$a- cpp gcc g++ gcov gcov-dump gcov-tool gprof
73                 gcc-ar gcc-nm gcc-ranlib
74         /usr/lib/gcc-cross/$a/ ..."
75 done
76 wanted=$(echo $wanted)
77
78 case $myarch in
79   i386) elfsig=7f454c46010101??0000000000000000????0300 ;;
80   amd64) elfsig=7f454c46020101??0000000000000000????3e00 ;;
81   *) echo >&2 "$0: unsupported local arch \`$myarch'"; exit 1 ;;
82 esac
83
84 chase_link () {
85   p=$1 d=
86   while :; do
87     case $p in
88       "") break ;;
89       "/"*) p=${p#/} ;;
90       "./"*) p=${p#./} ;;
91       "../"*)
92         p=${p#../}
93         case $d in */*) d=${d%/*} ;; *) d= ;; esac
94         ;;
95       *)
96         case $p in */*) f=${p%%/*} p=${p#*/} ;; *) f=$p p="" ;; esac
97         d=${d:+$d/}$f
98         ;;
99     esac
100     if ! [ -e "$crossnew$d" ] && ! [ -L "$crossnew$d" ]; then
101       if [ -d "$root/$d" ] &&  ! [ -L "$root/$d" ]; then
102         mkdir "$crossnew$d"
103       else
104         echo >&2 "$0: copy /$d to satisfy symlinks"
105         rsync -aHR $root/./$d $crossnew
106       fi
107     fi
108     if [ -L "$crossnew$d" ]; then
109       t=$(readlink "$crossnew$d")
110       case $t in /*) t=${t#/} d= ;; esac
111       case $d in */*) d=${d%/*} ;; *) d= ;; esac
112       p=$t${p:+/$p}
113     fi
114   done
115 }
116
117 exec 3>&1
118 for d in "$@"; do
119   echo >&2 "$0: create $d snapshot"
120   sess=$(schroot -bc$d-$myarch 3>&-)
121   schroot -uroot -rc$sess -- eatmydata sh -ec "
122         apt-get update
123         apt-get -y upgrade
124         apt-get -y install $cross_pkgs"
125   crossdir=/usr/local.schroot/cross/$d-$myarch/
126   crossold=${crossdir%/}.old/ crossnew=${crossdir%/}.new/
127   rm -rf $crossnew; mkdir -p $crossnew
128
129   root=/schroot/$sess/fs; dir=/
130   for i in $wanted; do
131     case $i in
132       /*)
133         dir=$i
134         ;;
135       *)
136         case $i in ...) f=$dir ;; *) f=$dir$i ;; esac
137         echo >&2 "$0: copy $f"
138         rsync -aHR $root/.$f $crossnew
139         ;;
140     esac
141   done
142
143   find $crossnew -xtype l -print | while read i; do
144     chase_link ${i#$crossnew}
145   done
146
147   find $crossnew -type f -print | while read i; do
148     sig=$(head -c20 "$i" | bincode -e -m0 -flowerc hex)
149     case $sig in $elfsig) echo "$i" ;; esac
150   done >$root/private/QUEUE.in
151
152   counter=0
153   cp $root/private/QUEUE.in /tmp/mdw/queue.in.$counter
154
155   while [ -s $root/private/QUEUE.in ]; do
156     schroot -uroot -rc$sess -- eatmydata sh -ec '
157         prog=$1
158         while read i; do
159         echo >&2 "$prog: scanning binary $i"
160           ldd "$i" | while read a b c d; do
161             case $a:$b:$c:$d in
162               not:a:dynamic:executable) ;;
163               statically:linked::) ;;
164               /*) echo "$a" ;;
165               *:=\>:/*) echo "$c" ;;
166               linux-*) ;;
167               *) echo >&2 "$i: unable to find $a"; exit 2 ;;
168             esac
169           done
170         done </private/QUEUE.in >/private/QUEUE.out' - "$0"
171
172     cp $root/private/QUEUE.out /tmp/mdw/queue.out.$counter
173     counter=$(( $counter + 1 ))
174
175     while read i; do
176       if [ -e "$crossnew$i" ] || [ -L "$crossnew$i" ]
177       then continue; fi
178       if [ -d "$root$i" ]; then continue; fi
179       echo >&2 "$0: copy $i"
180       rsync -aHR $root/.$i $crossnew >&3
181       chase_link $i >&3
182       sig=$(head -c20 $crossnew$i | bincode -e -m0 -flowerc hex)
183       case $sig in $elfsig) echo "$i" ;; esac
184     done <$root/private/QUEUE.out >$root/private/QUEUE.in
185
186     cp $root/private/QUEUE.in /tmp/mdw/queue.in.$counter
187
188   done
189
190   echo >&2 "$0: establish TOOLCHAIN"
191   for a in $cross_archs; do
192     tooldir=$crossnew/TOOLCHAIN/$a
193     mkdir -p $tooldir
194     for i in $crossnew/usr/bin/$a-*; do
195       t=${i#$crossnew/usr/bin/}
196       mv $i $tooldir/$t
197       ln -s $t $tooldir/${t#$a-}
198     done
199   done
200   mkdir $crossnew/TOOLCHAIN/lib
201   ln -s ../../usr/lib/gcc-cross $crossnew/TOOLCHAIN/lib/
202
203   echo >&2 "$0: establish QEMU"
204   mkdir $crossnew/QEMU
205   mv $crossnew/usr/bin/qemu-*-static $crossnew/QEMU/
206
207   echo >&2 "$0: remove snapshot"
208   schroot -ec$sess 3>&-
209   if [ -d $crossdir ]; then mv $crossdir $crossold; fi
210   mv $crossnew $crossdir; rm -rf $crossold
211   echo >&2 "$0: committed $crossdir"
212 done