Commit | Line | Data |
---|---|---|
fd0f20e1 MW |
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 |