]> git.pld-linux.org Git - projects/cleanbuild.git/blob - cleanbuild
- reverted .la file preprocessing: turns out my first method is the best working one
[projects/cleanbuild.git] / cleanbuild
1 #!/usr/bin/sudo /bin/sh
2
3 RPMS_FROM="$HOME/rpm/cleanRPMS.repo"
4 DEST="th"
5 SRC="-n th-x86_64-test"
6 SUFFIX=""
7 CACHEDIR="$PWD/poldekcache"
8 RPMMACROS=""
9 BUILDERRC=""
10 IGNORE=""
11 ignore() { IGNORE="$IGNORE $*"; }
12 NODEBUG=true
13 CLEANAFTER=false
14 FORCE_UMOUNT=false
15 NOREBUILDDB=true
16 # Whatever you set here as value, consider that it may not be shorter than
17 # /usr/lib/debug (or /usr/src/debug) for debuginfo to work.
18 # You get "Only dest dir longer than base dir not supported" error otherwise.
19 BUILDDIR=/usr/src/BUILD
20
21 [ -r .cleanbuildrc ] && . ./.cleanbuildrc
22
23 [ -z "$USER" ] && echo "USER not defined" && exit 1
24 [ "$USER" == "root" ] && echo "USER must not be root" && exit 1
25
26 export LC_ALL=C
27 unset LANGUAGE
28 unset LANG
29
30 usage() {
31         [ $# -gt 0 ] && echo "$*"
32         echo "Usage:"
33         echo "  ./cleanbuild [cleanbuild options] specname [builder options]"
34         echo "  ./build [cleanbuild options] specname [builder options]"
35         echo "  ./clean [cleanbuild options]"
36         echo "  ./create [cleanbuild options]"
37         echo "  ./install [cleanbuild options] packages"
38         echo ""
39         echo "cleanbuild options:"
40         echo " -32, -64, -th-i486  - select architecture"
41         echo " --cleanafter | -ca  - clean after build"
42         echo " --forceumount | -fu - force umount tmpfs"
43         echo " --debug             - enable debug"
44         echo " -a, -b, -c, -d, -e  - select alternative chroot directory"
45         exit 1
46 }
47
48 FETCH=false
49 CLEAN=false
50 CREATE=false
51 BUILD=false
52 INSTALL=false
53
54 case "$0" in
55         *clean)
56                 CLEAN=exit_after
57                 ;;
58         *cleanbuild)
59                 FETCH=true
60                 CLEAN=true
61                 CREATE=true
62                 BUILD=true
63                 ;;
64         *build)
65                 CREATE=true
66                 BUILD=true
67                 ;;
68         *create)
69                 CLEAN=true
70                 CREATE=exit_after
71                 ;;
72         *install)
73                 CREATE=true
74                 INSTALL=exit_after
75                 ;;
76         *)
77                 usage
78                 ;;
79 esac
80
81 while [ $# -gt 0 ]; do
82         OPT="${1}"
83         case "$OPT" in
84                 -32)    OPT="-th-i686" ;;
85                 -64)    OPT="-th-x86_64" ;;
86                 -th-32) OPT="-th-i686" ;;
87                 -th-64) OPT="-th-x86_64" ;;
88                 -ti-32) OPT="-ti-i686" ;;
89                 -ti-64) OPT="-ti-x86_64" ;;
90                 -ac)    OPT="-ac-amd64" ;;
91                 -ac-32) OPT="-ac-i586" ;;
92                 -ac-64) OPT="-ac-amd64" ;;
93         esac
94
95         V="${OPT#-}"
96         case "$OPT" in
97                 -th-i[46]86 | -th-x86_64)
98                         DEST="$V"
99                         SRC="-n $V-ready"
100                         ;;
101                 -th-i[46]86-test | -th-x86_64-test)
102                         DEST="$V"
103                         SRC="-n $V"
104                         ;;
105                 -ti-i[56]86 | -ti-x86_64)
106                         DEST="$V"
107                         SRC="-n $V-ready"
108                         ;;
109                 -ti-i[56]86-test | -ti-x86_64-test)
110                         DEST="$V"
111                         SRC="-n $V"
112                         ;;
113                 -ac-amd64 | -ac-i[356]86 | -ac-athlon)
114                         DEST="$V"
115                         SRC="-n $V-ready"
116                         ;;
117                 --cleanafter | -ca)
118                         CLEANAFTER=true
119                         ;;
120                 --debug)
121                         NODEBUG=false
122                         ;;
123                 --forceumount | -fu)
124                         FORCE_UMOUNT=true
125                         ;;
126                 -[a-e])
127                         SUFFIX="$OPT"
128                         ;;
129                 -~*)
130                         SUFFIX="$V"
131                         ;;
132                 *)
133                         break
134                         ;;
135         esac
136         shift
137 done
138
139 if $BUILD; then
140         [ $# -ne 0 ] || usage
141         build_pkg="${1}"
142         build_pkg="${build_pkg%/}"
143         build_pkg="${build_pkg%.spec}"
144         build_pkg="${build_pkg#*/}"
145         shift
146
147         builder_options="$*"
148 fi
149
150 $NODEBUG || set -x
151
152 CHNAME="chroot-$DEST$SUFFIX"
153 CHDIR="$PWD/$CHNAME"
154 CHHOME="/home/users/$USER"
155
156 warn()
157 {
158         echo -n -e "\033[31;1m" >&2
159         echo -n "$*" >&2
160         echo -e "\033[0m" >&2
161 }
162
163 die()
164 {
165         code=$1
166         shift
167         warn "$*"
168         exit $code
169 }
170
171 info()
172 {
173         echo -n -e "\033[32m"
174         echo -n "$*"
175         echo -e "\033[0m"
176 }
177
178 title()
179 {
180         [ -t 1 ] || return 0
181         local msg="$CHNAME: $build_pkg: $*"
182         case "$TERM" in
183                 cygwin|xterm*)
184                         echo -ne "\033]1;$msg\007\033]2;$msg\007" >&2
185                         ;;
186                 screen*)
187                         echo -ne "\033]0;$msg\007" >&2
188                         ;;
189         esac
190         return 0
191 }
192
193 exit_after()
194 {
195         return 0;
196 }
197
198 check_running()
199 {
200         [ -r "$CHDIR/.pid" ] || return
201         PID=$(< "$CHDIR/.pid")
202         if [ -d /proc/$PID ]; then
203                 die 10 "Another process ($PID) already running in $CHNAME"
204         fi
205 }
206
207 for D in installed buildlogs $CACHEDIR; do
208         if [ ! -d "$D" ]; then
209                 info "mkdir $D"
210                 su $USER -c "mkdir -p $D" || die 13 "Cannot create work directories"
211         fi
212 done
213
214 ignore \
215         vserver-packages \
216         upstart\* \
217         xorg-driver-video-fglrx\* xorg-driver-video-nvidia\* xorg-xserver-xgl-libGL \
218         xorg-data-xbitmaps \
219         compat-gcc\* \
220         libpng1\* \
221         freetype1-devel-* \
222         anacron fcron hc-cron \
223         masqmail msmtp-sendmail omta postfix sendmail ssmtp nail-mail nullmailer \
224         ghostscript-esp \
225         \*-multilib-\* \
226         gnome-speech-driver-festival gnome-speech-driver-speech-dispatcher
227
228
229 rebuilddb()
230 {
231         $NOREBUILDDB || rpm --root=$CHDIR --rebuilddb
232 }
233
234 poldek()
235 {
236         $NODEBUG || set -x
237         rebuilddb
238         /usr/bin/poldek $SRC -s "$RPMS_FROM" -r "$CHDIR" "--cachedir=$CACHEDIR" --conf=$PWD/poldekconf/poldek.conf "$@"
239 }
240
241
242 build_umount()
243 {
244         for DIR in $CHHOME/rpm $CHHOME dev proc sys; do
245                 [ -d $CHDIR/$DIR ] && umount $CHDIR/$DIR
246         done
247 }
248
249 build_remove_root()
250 {
251         $NODEBUG || set -x
252         if $FORCE_UMOUNT; then
253                 # safety checks.
254                 [ "$CHDIR" ] || exit 1
255                 [ -d "$CHDIR" ] || exit 1
256                 rm -rf $CHDIR/*
257                 umount -l $CHDIR
258         else
259                 umount $CHDIR
260         fi
261         rmdir $CHDIR
262 }
263
264 clean()
265 {
266         info "Cleaning $CHNAME"
267         title "cleaning chroot"
268         build_umount
269         build_remove_root
270 }
271
272 build_prepare_root()
273 {
274         title "preparing chroot"
275         set -e
276         $NODEBUG || set -x
277         mkdir $CHDIR
278         mount -t tmpfs -o size=8G,relatime /dev/null $CHDIR
279         echo $$ > $CHDIR/.pid
280
281         rpm --root=$CHDIR --initdb 
282         poldek --up || :
283         poldek -O "ignore=$IGNORE" -u rpm-build pwdutils coreutils
284
285         for DIR in dev proc sys; do
286                 # We need to create these directories manually, because they are marked
287                 # as netsharedpath in cleanbuild poldek.conf
288                 mkdir $CHDIR/$DIR
289                 mount -o bind /$DIR $CHDIR/$DIR
290         done
291
292         chroot $CHDIR useradd -m $USER -u$(id $USER -u)
293
294         # replicate files which already belong to $USER
295         # so they will have correct owner and permissions
296         cp -a $CHDIR/$CHHOME/{tmp,rpm}
297         cp -a $CHDIR/$CHHOME/tmp $CHDIR$BUILDDIR
298
299         cp -a $CHDIR/$CHHOME/{.bashrc,.rpmmacros}
300         cat <<-EOM > $CHDIR/$CHHOME/.rpmmacros
301         %_builddir              $BUILDDIR
302         %buildroot              %{_builddir}/%{name}-%{version}-root-%(id -u -n)
303         %_rpmdirname    cleanRPMS
304         %_rpmdir                %{expand:%%global _rpmdir %([ -d %{_topdir}/../%{_rpmdirname} ] && (cd %{_topdir}/../%{_rpmdirname}; pwd) || echo %{_topdir}/%{_rpmdirname})}%_rpmdir
305         %distribution   CleanPLD
306         %_binary_payload        w1.gzdio
307 EOM
308         [ -z "$RPMMACROS" ] || echo "$RPMMACROS" >> $CHDIR/$CHHOME/.rpmmacros
309
310         cp -a $CHDIR/$CHHOME/{.bashrc,.builderrc}
311         cat <<-'EORC' > $CHDIR/$CHHOME/.builderrc
312         TITLECHANGE=no
313 EORC
314         [ -z "$BUILDERRC" ] || echo "$BUILDERRC" >> $CHDIR/$CHHOME/.builderrc
315
316         set +e
317 }
318
319 build_mount_home()
320 {
321         $NODEBUG || set -x
322         mount -o bind $HOME/rpm $CHDIR/$CHHOME/rpm
323 }
324
325
326 print_installed()
327 {
328         echo=$1
329         if [ -r installed/$build_pkg ]; then
330                 $echo "$(cat installed/$build_pkg | awk '{print $1}' | sort -u \
331                         | awk '{br=br ", " $1} END{gsub(/^, /, "- BR: ", br ); print br}')"
332                 cat installed/$build_pkg
333         fi
334 }
335
336 addlist()
337 {
338         LIST="$1"
339
340         print_installed info
341
342         return
343         echo "*** $build_pkg $(date --rfc-3339=seconds) ***" >> $LIST
344         print_installed echo >> $LIST
345 }
346
347 builddie()
348 {
349         LIST="$1"; shift
350         CODE="$1"; shift
351         MSG="$*"
352
353         rm -f $CHDIR/.pid
354
355         $CLEANAFTER && clean
356         title "failed !"
357
358         addlist "ERROR_$LIST"
359         die $CODE "$MSG"
360 }
361
362 LAST_INSTALL=""
363 poldek_install()
364 {
365         I="$1";
366         # Nothing to install
367         [ -n "$I" ] || return 1
368         # Installing same packets second time
369         [ "$LAST_INSTALL" != "$I" ] || return 1
370         LAST_INSTALL="$I"
371
372         info "Installing" $I
373         poldek -O "ignore=$IGNORE" -u $I | tee $$.poldek_install
374         ret=
375         if grep -q "Preparing...                ##################################################" $$.poldek_install \
376                         && ! grep -q "file .* from install of .* conflicts with file from package" $$.poldek_install
377                 then
378                 info "Poldek:" $I "installed"
379                 ret=0
380         elif grep -q "Nothing to do" $$.poldek_install; then
381                 warn "Poldek:" $I "installed already"
382                 ret=1
383         fi
384         rm $$.poldek_install
385         [ -n "$ret" ] && return $ret
386
387         # try harder
388         poldek -u $I && return 0
389         poldek -u $I && return 0
390         warn "Poldek:" "Could not install" $I
391         return 1
392 }
393
394 maybe_call()
395 {
396         local cond="$1"; shift
397         local func="$1"; shift
398
399         [ $cond == "false" ] && return
400         $func "$@"
401         [ $cond == "exit_after" ] && exit
402 }
403
404 fetch()
405 {
406         info "Fetching $build_pkg"
407         title "fetch"
408         $NODEBUG || set -x
409         su $USER -c "$HOME/rpm/packages/builder -g $build_pkg $builder_options" \
410                 || die 11 "Fetch failed"
411 }
412
413 create()
414 {
415         $NODEBUG || set -x
416         su $USER -c "poldek -s $RPMS_FROM --mkidx"
417
418         if [ ! -d $CHDIR ]; then
419                 info "Preparing $CHNAME"
420                 build_prepare_root
421                 build_mount_home
422         fi
423 }
424
425
426 maybe_call $FETCH fetch
427
428 check_running
429
430 maybe_call $CLEAN clean
431
432 maybe_call $CREATE create
433
434 echo $$ > $CHDIR/.pid
435
436 maybe_call $INSTALL poldek_install "$*"
437
438 $BUILD || exit
439
440 if [ -p /tmp/fixfreq ]; then
441         echo $$ > /tmp/fixfreq
442 fi
443
444 while true; do
445         info "Building $build_pkg in $CHNAME"
446         rebuilddb
447         find $CHDIR/usr/lib{,64} -name "*.la" -print0 | \
448                 xargs -0 -r sed -i -e "s@dependency_libs=.*@dependency_libs=' '@"
449         buildlog="buildlogs/$build_pkg"
450         if [ -r $buildlog ]; then
451                 i=1
452                 while [ -r $buildlog.$i ]; do
453                         i=$((i+1))
454                 done
455                 info "moving $buildlog to $buildlog.$i"
456                 mv $buildlog $buildlog.$i
457         fi
458         ./findunusedbr -c $CHDIR $HOME/rpm/packages/$build_pkg/$build_pkg.spec
459         title "building"
460         { chroot $CHDIR su $USER -c "$CHHOME/rpm/packages/builder -nn -bb $build_pkg $builder_options" < /dev/null 2>&1; echo $? > ecode; } | tee $buildlog
461
462         ECODE=$(< ecode)
463         rm -f ecode
464
465         if grep -q "error: Failed build dependencies:" $buildlog; then
466                 SEARCH=$(cat $buildlog | awk '/^Error:/ { p = 0 }; { if ( p ) { f="p"; if ( $1 ~ /^\// ) f="f"; printf "search -%c %s; ", f, $1; } }; /error: Failed build dependencies:/ { p = 1 }')
467                 INSTALL=$(poldek -O "ignore=$IGNORE" --shcmd="$SEARCH" | awk '{ if ( p ) { print; p = 0; } } / package\(s\) found:$/ { p = 1 }' | sed 's/^\(.*\)-.*-.*$/\1/' | sort -u)
468
469                 if poldek_install "$INSTALL"; then
470                         info "Deps installed"
471                         continue
472                 else
473                         addlist ERROR_BRINSTALL
474                         die 4 "Cannot install BRs"
475                 fi
476         fi
477
478         ./findbr $CHDIR/$BUILDDIR $buildlog > $$.installed
479         installed_something=false
480         while read pkg msg; do
481                 if poldek_install $pkg; then
482                         info "findbr:" $pkg "installed"
483                         echo "$pkg $msg" >> installed/$build_pkg
484                         ./addbr $build_pkg "$pkg" "$msg"
485                         installed_something=true
486                 else
487                         warn "findbr:" $pkg "not installed"
488                 fi
489         done < $$.installed
490         rm -f $$.installed
491         $installed_something && continue
492
493         if [ $ECODE -eq 0 ]; then
494                 $CLEANAFTER && clean
495                 addlist BUILT_OK
496                 ./findunusedbr $CHDIR $HOME/rpm/packages/$build_pkg/$build_pkg.spec
497                 info "$build_pkg built OK !"
498                 title "OK !"
499                 exit 0
500         else
501                 builddie UNKNOWN 1 "Got error but dunno what to do !"
502         fi
503 done
504
505
506 # vim: ts=4 sw=4 filetype=sh
This page took 0.07056 seconds and 4 git commands to generate.