]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - tools/tools/sysbuild/sysbuild.sh
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / tools / tools / sysbuild / sysbuild.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 1994-2009 Poul-Henning Kamp.
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 # 1. Redistributions of source code must retain the above copyright
10 #    notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 #    notice, this list of conditions and the following disclaimer in the
13 #    documentation and/or other materials provided with the distribution.
14 #
15 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 # SUCH DAMAGE.
26 #
27 # $FreeBSD$
28 #
29
30 set -e
31
32 exec < /dev/null
33
34 if [ `uname -m` = "i386" ] ; then
35         TARGET_PART=`df / | sed '
36         1d
37         s/[    ].*//
38         s,/dev/,,
39         s,s1a,s3a,
40         s,s2a,s1a,
41         s,s3a,s2a,
42         '`
43
44         # Where our build-bits are to be found
45         FREEBSD_PART=`echo $TARGET_PART | sed 's/s[12]a/s3/'`
46 elif [ `uname -m` = "amd64" ] ; then
47         TARGET_PART=`df / | sed '
48         1d
49         s/[    ].*//
50         s,/dev/,,
51         s,s1a,s3a,
52         s,s2a,s1a,
53         s,s3a,s2a,
54         '`
55
56         # Where our build-bits are to be found
57         FREEBSD_PART=`echo $TARGET_PART | sed 's/s[12]a/s3/'`
58 else
59         TARGET_PART=unknown
60         FREEBSD_PART=unknown
61 fi
62
63 # Relative to /freebsd
64 PORTS_PATH=ports
65 SRC_PATH=src
66 # OBJ_PATH=obj
67
68 # Name of kernel
69 KERNCONF=GENERIC
70
71 # srcconf
72 #SRCCONF="SRCCONF=/usr/src/src.conf"
73
74 # -j arg to make(1)
75
76 ncpu=`sysctl -n kern.smp.cpus`
77 if [ $ncpu -gt 1 ] ; then
78         JARG="-j $ncpu"
79 fi
80
81 # serial console ?
82 SERCONS=false
83
84 # Remotely mounted distfiles
85 # REMOTEDISTFILES=fs:/rdonly/distfiles
86
87 # Proxy
88 #FTP_PROXY=http://127.0.0.1:3128/
89 #HTTP_PROXY=http://127.0.0.1:3128/
90 #export FTP_PROXY HTTP_PROXY
91
92 PORTS_WE_WANT='
93 '
94
95 PORTS_OPTS="BATCH=YES MAKE_IDEA=YES A4=yes"
96
97 CONFIGFILES='
98 '
99
100 cleanup() (
101 )
102
103 before_ports() (
104 )
105
106 before_ports_chroot() (
107 )
108
109 final_root() (
110 )
111
112 final_chroot() (
113 )
114
115 #######################################################################
116 #######################################################################
117
118 usage () {
119         (
120         echo "Usage: $0 [-b/-k/-w] [-c config_file]"
121         echo "  -b      suppress builds (both kernel and world)"
122         echo "  -k      suppress buildkernel"
123         echo "  -w      suppress buildworld"
124         echo "  -p      used cached packages"
125         echo "  -c      specify config file"
126         ) 1>&2
127         exit 2
128 }
129
130 #######################################################################
131 #######################################################################
132
133 if [ ! -f $0 ] ; then
134         echo "Must be able to access self ($0)" 1>&2
135         exit 1
136 fi
137
138 if grep -q 'Magic String: 0`0nQT40W%l,CX&' $0 ; then
139         true
140 else
141         echo "self ($0) does not contain magic string" 1>&2
142         exit 1
143 fi
144
145 #######################################################################
146
147 set -e
148
149 log_it() (
150         set +x
151         a="$*"
152         set `cat /tmp/_sb_log`
153         TX=`date +%s`
154         echo "$1 $TX" > /tmp/_sb_log
155         DT=`expr $TX - $1 || true`
156         DL=`expr $TX - $2 || true`
157         echo -n "### `date +%H:%M:%S`"
158         printf " ### %5d ### %5d ### %s\n" $DT $DL "$a"
159 )
160
161 #######################################################################
162
163
164 ports_recurse() (
165         set +x
166         t=$1
167         shift
168         if [ "x$t" = "x." ] ; then
169                 true > /tmp/_.plist
170                 true > /tmp/_.plist.tdone
171                 echo 'digraph {' > /tmp/_.plist.dot
172         fi
173         if grep -q "^$t\$" /tmp/_.plist.tdone ; then
174                 return
175         fi
176         echo "$t" >> /tmp/_.plist.tdone
177         for d
178         do
179                 if [ ! -d $d ] ; then
180                         echo "Missing port $d" 1>&2
181                         continue
182                 fi
183                 if [ ! -f $d/Makefile ] ; then
184                         echo "Missing port $d" 1>&2
185                         continue
186                 fi
187                 if [ "x$t" != "x." ] ; then
188                         echo "\"$t\" -> \"$d\"" >> /tmp/_.plist.dot
189                 fi
190                 if grep -q "^$d\$" /tmp/_.plist ; then
191                         true
192                 elif grep -q "^$d\$" /tmp/_.plist.tdone ; then
193                         true
194                 else
195                         (
196                         cd $d
197                         ports_recurse $d `make -V _DEPEND_DIRS ${PORTS_OPTS}`
198                         )
199                         echo "$d" >> /tmp/_.plist
200                 fi
201         done
202         if [ "x$t" = "x." ] ; then
203                 echo '}' >> /tmp/_.plist.dot
204         fi
205 )
206
207 ports_build() (
208         set +x
209
210         ports_recurse . $PORTS_WE_WANT 
211
212         # Now build & install them
213         for p in `cat /tmp/_.plist`
214         do
215                 t=`echo $p | sed 's,/usr/ports/,,'`
216                 pn=`cd $p && make package-name`
217                 if [ "x${PKG_DIR}" != "x" -a -f ${PKG_DIR}/$pn.tbz ] ; then
218                         if [ "x$use_pkg" = "x-p" ] ; then
219                                 log_it "install $p from ${PKG_DIR}/$pn.tbz"
220                                 pkg_add ${PKG_DIR}/$pn.tbz
221                         fi
222                 fi
223                 i=`pkg_info -qO $t`
224                 if [ -z "$i" ] ; then
225                         log_it "build $p"
226                         b=`echo $p | tr / _`
227                         (
228                                 set -x
229                                 cd /usr/ports
230                                 cd $p
231                                 set +e
232                                 make clean ${PORTS_OPTS}
233                                 if make install ${PORTS_OPTS} ; then
234                                         if [ "x${PKG_DIR}" != "x" ] ; then
235                                                 make package ${PORTS_OPTS}
236                                                 mkdir -p ${PKG_DIR}
237                                                 mv *.tbz ${PKG_DIR}
238                                         fi
239                                 else
240                                         log_it FAIL build $p
241                                 fi
242                                 make clean
243                         ) > _.$b 2>&1 < /dev/null
244                         date
245                 fi
246         done
247 )
248
249 ports_prefetch() (
250         (
251         set +x
252         true > /mnt/_.prefetch
253         echo "Building /tmp/_.plist" >> /mnt/_.prefetch
254
255         ports_recurse . $PORTS_WE_WANT
256
257         echo "Completed /tmp/_.plist" >> /mnt/_.prefetch
258         # Now checksump/fetch them
259         for p in `cat /tmp/_.plist`
260         do
261                 b=`echo $p | tr / _`
262                 (
263                         cd $p
264                         if make checksum $PORTS_OPTS ; then
265                                 rm -f /mnt/_.prefetch.$b
266                                 echo "OK $p" >> /mnt/_.prefetch
267                                 exit 0
268                         fi
269                         make distclean
270                         make checksum $PORTS_OPTS || true
271
272                         if make checksum $PORTS_OPTS > /dev/null 2>&1 ; then
273                                 rm -f /mnt/_.prefetch.$b
274                                 echo "OK $p" >> /mnt/_.prefetch
275                         else
276                                 echo "BAD $p" >> /mnt/_.prefetch
277                         fi
278                 ) > /mnt/_.prefetch.$b 2>&1
279         done
280         ) 
281 )
282
283 #######################################################################
284
285 do_world=true
286 do_kernel=true
287 use_pkg=""
288 c_arg=""
289
290 set +e
291 args=`getopt bc:hkpw $*`
292 if [ $? -ne 0 ] ; then
293         usage
294 fi
295 set -e
296
297 set -- $args
298 for i
299 do
300         case "$i"
301         in
302         -b)
303                 shift;
304                 do_world=false
305                 do_kernel=false
306                 ;;
307         -c)
308                 c_arg=$2
309                 if [ ! -f "$c_arg" ] ; then
310                         echo "Cannot read $c_arg" 1>&2
311                         usage
312                 fi
313                 . "$2"
314                 shift
315                 shift
316                 ;;
317         -h)
318                 usage
319                 ;;
320         -k)
321                 shift;
322                 do_kernel=false
323                 ;;
324         -p)
325                 shift;
326                 use_pkg="-p"
327                 ;;
328         -w)
329                 shift;
330                 do_world=false
331                 ;;
332         --)
333                 shift
334                 break;
335                 ;;
336         esac
337 done
338
339 #######################################################################
340
341 if [ "x$1" = "xchroot_script" ] ; then
342         set +x
343         set -e
344
345         shift
346
347         before_ports_chroot
348
349         ports_build
350
351         exit 0
352 fi
353
354 if [ "x$1" = "xfinal_chroot" ] ; then
355         final_chroot
356         exit 0
357 fi
358
359 if [ $# -gt 0 ] ; then
360         echo "$0: Extraneous arguments supplied"
361         usage
362 fi
363
364 #######################################################################
365
366 T0=`date +%s`
367 echo $T0 $T0 > /tmp/_sb_log
368
369 log_it Unmount everything
370 (
371         ( cleanup )
372         umount /freebsd/distfiles || true
373         umount /mnt/freebsd/distfiles || true
374         umount /dev/${FREEBSD_PART} || true
375         umount /mnt/freebsd || true
376         umount /mnt/dev || true
377         umount /mnt || true
378         umount /dev/${TARGET_PART} || true
379 ) # > /dev/null 2>&1
380
381 log_it Prepare running image
382 mkdir -p /freebsd
383 mount /dev/${FREEBSD_PART} /freebsd
384
385 #######################################################################
386
387 if [ ! -d /freebsd/${PORTS_PATH} ] ;  then
388         echo PORTS_PATH does not exist 1>&2
389         exit 1
390 fi
391
392 if [ ! -d /freebsd/${SRC_PATH} ] ;  then
393         echo SRC_PATH does not exist 1>&2
394         exit 1
395 fi
396
397 log_it TARGET_PART $TARGET_PART
398 sleep 5
399
400 rm -rf /usr/ports
401 ln -s /freebsd/${PORTS_PATH} /usr/ports
402
403 rm -rf /usr/src
404 ln -s /freebsd/${SRC_PATH} /usr/src
405
406 if $do_world ; then
407         if [ "x${OBJ_PATH}" != "x" ] ; then
408                 rm -rf /usr/obj
409                 mkdir -p /freebsd/${OBJ_PATH}
410                 ln -s /freebsd/${OBJ_PATH} /usr/obj
411         else
412                 rm -rf /usr/obj
413                 mkdir -p /usr/obj
414         fi
415 fi
416
417 #######################################################################
418
419 for i in ${PORTS_WE_WANT}
420 do
421         if [ ! -d $i ]  ; then
422                 echo "Port $i not found" 1>&2
423                 exit 2
424         fi
425 done
426
427 export PORTS_WE_WANT
428 export PORTS_OPTS
429
430 #######################################################################
431
432 log_it Prepare destination partition
433 newfs -O2 -U /dev/${TARGET_PART} > /dev/null
434 mount /dev/${TARGET_PART} /mnt
435 mkdir -p /mnt/dev
436 mount -t devfs devfs /mnt/dev
437
438 if [ "x${REMOTEDISTFILES}" != "x" ] ; then
439         rm -rf /freebsd/${PORTS_PATH}/distfiles
440         ln -s /freebsd/distfiles /freebsd/${PORTS_PATH}/distfiles
441         mkdir -p /freebsd/distfiles
442         mount  ${REMOTEDISTFILES} /freebsd/distfiles
443 fi
444
445 log_it copy ports config files
446 (cd / ; find var/db/ports -print | cpio -dumpv /mnt > /dev/null 2>&1)
447
448 log_it "Start prefetch of ports distfiles"
449 ports_prefetch &
450
451 if $do_world ; then
452         (
453         cd /usr/src
454         log_it "Buildworld"
455         make ${JARG} -s buildworld ${SRCCONF} > /mnt/_.bw 2>&1
456         )
457 fi
458
459 if $do_kernel ; then
460         (
461         cd /usr/src
462         log_it "Buildkernel"
463         make ${JARG} -s buildkernel KERNCONF=$KERNCONF > /mnt/_.bk 2>&1
464         )
465 fi
466
467
468 log_it Installworld
469 (cd /usr/src && make ${JARG} installworld DESTDIR=/mnt ${SRCCONF} ) \
470         > /mnt/_.iw 2>&1
471
472 log_it distribution
473 (cd /usr/src/etc && make -m /usr/src/share/mk distribution DESTDIR=/mnt ${SRCCONF} ) \
474         > /mnt/_.dist 2>&1
475
476 log_it Installkernel
477 (cd /usr/src && make ${JARG} installkernel DESTDIR=/mnt KERNCONF=$KERNCONF ) \
478         > /mnt/_.ik 2>&1
479
480 if [ "x${OBJ_PATH}" != "x" ] ; then
481         rmdir /mnt/usr/obj
482         ln -s /freebsd/${OBJ_PATH} /mnt/usr/obj
483 fi
484
485 log_it Wait for ports prefetch
486 log_it "(Tail /mnt/_.prefetch for progress)"
487 wait
488
489 log_it Move filesystems
490
491 if [ "x${REMOTEDISTFILES}" != "x" ] ; then
492         umount /freebsd/distfiles
493 fi
494 umount /dev/${FREEBSD_PART} || true
495 mkdir -p /mnt/freebsd
496 mount /dev/${FREEBSD_PART} /mnt/freebsd
497 if [ "x${REMOTEDISTFILES}" != "x" ] ; then
498         mount  ${REMOTEDISTFILES} /mnt/freebsd/distfiles
499 fi
500
501 rm -rf /mnt/usr/ports || true
502 ln -s /freebsd/${PORTS_PATH} /mnt/usr/ports
503
504 rm -rf /mnt/usr/src || true
505 ln -s /freebsd/${SRC_PATH} /mnt/usr/src
506
507 log_it Build and install ports
508
509 # Make sure fetching will work in the chroot
510 if [ -f /etc/resolv.conf ] ; then
511         log_it copy resolv.conf
512         cp /etc/resolv.conf /mnt/etc
513         chflags schg /mnt/etc/resolv.conf
514 fi
515
516 if [ -f /etc/localtime ] ; then
517         log_it copy localtime
518         cp /etc/localtime /mnt/etc
519 fi
520
521 log_it ldconfig in chroot
522 chroot /mnt sh /etc/rc.d/ldconfig start
523
524 log_it before_ports
525
526         before_ports 
527 )
528
529 log_it build ports
530 pwd
531 cp $0 /mnt/root
532 cp /tmp/_sb_log /mnt/tmp
533 b=`basename $0`
534 if [ "x$c_arg" != "x" ] ; then
535         cp $c_arg /mnt/root
536         chroot /mnt sh /root/$0 -c /root/`basename $c_arg` $use_pkg chroot_script 
537 else
538         chroot /mnt sh /root/$0 $use_pkg chroot_script
539 fi
540 cp /mnt/tmp/_sb_log /tmp
541
542 log_it fixing fstab
543 sed "/[         ]\/[    ]/s;^[^         ]*[     ];/dev/${TARGET_PART}   ;" \
544         /etc/fstab > /mnt/etc/fstab
545
546 log_it create all mountpoints
547 grep -v '^[     ]*#' /mnt/etc/fstab | 
548 while read a b c
549 do
550         mkdir -p /mnt/$b
551 done
552
553 if [ "x$SERCONS" != "xfalse" ] ; then
554         log_it serial console
555         echo " -h" > /mnt/boot.config
556         sed -i "" -e /ttyd0/s/off/on/ /mnt/etc/ttys
557         sed -i "" -e /ttyu0/s/off/on/ /mnt/etc/ttys
558         sed -i "" -e '/^ttyv[0-8]/s/    on/     off/' /mnt/etc/ttys
559 fi
560
561 log_it move config files
562 (
563         cd /mnt
564         mkdir root/configfiles_dist
565         find ${CONFIGFILES} -print | cpio -dumpv root/configfiles_dist
566 )
567
568 (cd / && find ${CONFIGFILES} -print | cpio -dumpv /mnt)
569
570 log_it final_root
571 ( final_root )
572 log_it final_chroot
573 cp /tmp/_sb_log /mnt/tmp
574 if [ "x$c_arg" != "x" ] ; then
575         chroot /mnt sh /root/$0 -c /root/`basename $c_arg` final_chroot
576 else
577         chroot /mnt sh /root/$0 final_chroot
578 fi
579 cp /mnt/tmp/_sb_log /tmp
580 log_it "Check these messages (if any):"
581 grep '^Stop' /mnt/_* || true
582 log_it DONE