]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - tools/tools/sysbuild/sysbuild.sh
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.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 else
47         TARGET_PART=unknown
48         FREEBSD_PART=unknown
49 fi
50
51 # Relative to /freebsd
52 PORTS_PATH=ports
53 SRC_PATH=src
54 # OBJ_PATH=obj
55
56 # Name of kernel
57 KERNCONF=GENERIC
58
59 # srcconf
60 #SRCCONF="SRCCONF=/usr/src/src.conf"
61
62 # -j arg to make(1)
63
64 ncpu=`sysctl -n kern.smp.cpus`
65 if [ $ncpu -gt 1 ] ; then
66         JARG="-j $ncpu"
67 fi
68
69 # serial console ?
70 SERCONS=false
71
72 # Remotely mounted distfiles
73 # REMOTEDISTFILES=fs:/rdonly/distfiles
74
75 # Proxy
76 #FTP_PROXY=http://127.0.0.1:3128/
77 #HTTP_PROXY=http://127.0.0.1:3128/
78 #export FTP_PROXY HTTP_PROXY
79
80 PORTS_WE_WANT='
81 '
82
83 PORTS_OPTS="BATCH=YES MAKE_IDEA=YES A4=yes"
84
85 CONFIGFILES='
86 '
87
88 cleanup() (
89 )
90
91 before_ports() (
92 )
93
94 before_ports_chroot() (
95 )
96
97 final_root() (
98 )
99
100 final_chroot() (
101 )
102
103 #######################################################################
104 #######################################################################
105
106 usage () {
107         (
108         echo "Usage: $0 [-b/-k/-w] [-c config_file]"
109         echo "  -b      suppress builds (both kernel and world)"
110         echo "  -k      suppress buildkernel"
111         echo "  -w      suppress buildworld"
112         echo "  -p      used cached packages"
113         echo "  -c      specify config file"
114         ) 1>&2
115         exit 2
116 }
117
118 #######################################################################
119 #######################################################################
120
121 if [ ! -f $0 ] ; then
122         echo "Must be able to access self ($0)" 1>&2
123         exit 1
124 fi
125
126 if grep -q 'Magic String: 0`0nQT40W%l,CX&' $0 ; then
127         true
128 else
129         echo "self ($0) does not contain magic string" 1>&2
130         exit 1
131 fi
132
133 #######################################################################
134
135 set -e
136
137 log_it() (
138         set +x
139         a="$*"
140         set `cat /tmp/_sb_log`
141         TX=`date +%s`
142         echo "$1 $TX" > /tmp/_sb_log
143         DT=`expr $TX - $1 || true`
144         DL=`expr $TX - $2 || true`
145         echo -n "### `date +%H:%M:%S`"
146         printf " ### %5d ### %5d ### %s\n" $DT $DL "$a"
147 )
148
149 #######################################################################
150
151
152 ports_recurse() (
153         set +x
154         for d
155         do
156                 if [ ! -d $d ] ; then
157                         echo "Missing port $d" 1>&2
158                         exit 2
159                 fi
160                 if grep -q "^$d\$" /tmp/_.plist ; then
161                         true
162                 else
163                         (
164                         cd $d
165                         ports_recurse `make -V _DEPEND_DIRS`
166                         )
167                         echo $d >> /tmp/_.plist
168                 fi
169         done
170 )
171
172 ports_build() (
173         set +x
174
175         true > /tmp/_.plist
176         ports_recurse $PORTS_WE_WANT 
177
178         # Now build & install them
179         for p in `cat /tmp/_.plist`
180         do
181                 t=`echo $p | sed 's,/usr/ports/,,'`
182                 pn=`cd $p && make package-name`
183                 if [ "x${PKG_DIR}" != "x" -a -f ${PKG_DIR}/$pn.tbz ] ; then
184                         if [ "x$use_pkg" = "x-p" ] ; then
185                                 log_it "install $p from ${PKG_DIR}/$pn.tbz"
186                                 pkg_add ${PKG_DIR}/$pn.tbz
187                         fi
188                 fi
189                 i=`pkg_info -qO $t`
190                 if [ -z "$i" ] ; then
191                         log_it "build $p"
192                         b=`echo $p | tr / _`
193                         (
194                                 set -x
195                                 cd /usr/ports
196                                 cd $p
197                                 set +e
198                                 make clean
199                                 if make install ${PORTS_OPTS} ; then
200                                         if [ "x${PKG_DIR}" != "x" ] ; then
201                                                 make package ${PORTS_OPTS}
202                                                 mv *.tbz ${PKG_DIR}
203                                         fi
204                                 else
205                                         log_it FAIL build $p
206                                 fi
207                                 make clean
208                         ) > _.$b 2>&1 < /dev/null
209                         date
210                 fi
211         done
212 )
213
214 ports_prefetch() (
215         (
216         set +x
217         true > /tmp/_.plist
218         ports_recurse $PORTS_WE_WANT
219
220         # Now checksump/fetch them
221         for p in `cat /tmp/_.plist`
222         do
223                 b=`echo $p | tr / _`
224                 (
225                         cd $p
226                         if make checksum $PORTS_OPTS ; then
227                                 true
228                         else
229                                 make distclean
230                                 make checksum $PORTS_OPTS || true
231                         fi
232                 ) > /mnt/_.prefetch.$b 2>&1
233         done
234         ) 
235 )
236
237 #######################################################################
238
239 do_world=true
240 do_kernel=true
241 use_pkg=""
242 c_arg=""
243
244 set +e
245 args=`getopt bc:hkpw $*`
246 if [ $? -ne 0 ] ; then
247         usage
248 fi
249 set -e
250
251 set -- $args
252 for i
253 do
254         case "$i"
255         in
256         -b)
257                 shift;
258                 do_world=false
259                 do_kernel=false
260                 ;;
261         -c)
262                 c_arg=$2
263                 if [ ! -f "$c_arg" ] ; then
264                         echo "Cannot read $c_arg" 1>&2
265                         usage
266                 fi
267                 . "$2"
268                 shift
269                 shift
270                 ;;
271         -h)
272                 usage
273                 ;;
274         -k)
275                 shift;
276                 do_kernel=false
277                 ;;
278         -p)
279                 shift;
280                 use_pkg="-p"
281                 ;;
282         -w)
283                 shift;
284                 do_world=false
285                 ;;
286         --)
287                 shift
288                 break;
289                 ;;
290         esac
291 done
292
293 #######################################################################
294
295 if [ "x$1" = "xchroot_script" ] ; then
296         set +x
297         set -e
298
299         shift
300
301         before_ports_chroot
302
303         ports_build
304
305         exit 0
306 fi
307
308 if [ "x$1" = "xfinal_chroot" ] ; then
309         final_chroot
310         exit 0
311 fi
312
313 if [ $# -gt 0 ] ; then
314         echo "$0: Extraneous arguments supplied"
315         usage
316 fi
317
318 #######################################################################
319
320 T0=`date +%s`
321 echo $T0 $T0 > /tmp/_sb_log
322
323 log_it Unmount everything
324 (
325         ( cleanup )
326         umount /freebsd/distfiles || true
327         umount /mnt/freebsd/distfiles || true
328         umount /dev/${FREEBSD_PART} || true
329         umount /mnt/freebsd || true
330         umount /mnt/dev || true
331         umount /mnt || true
332         umount /dev/${TARGET_PART} || true
333 ) # > /dev/null 2>&1
334
335 log_it Prepare running image
336 mkdir -p /freebsd
337 mount /dev/${FREEBSD_PART} /freebsd
338
339 #######################################################################
340
341 if [ ! -d /freebsd/${PORTS_PATH} ] ;  then
342         echo PORTS_PATH does not exist 1>&2
343         exit 1
344 fi
345
346 if [ ! -d /freebsd/${SRC_PATH} ] ;  then
347         echo SRC_PATH does not exist 1>&2
348         exit 1
349 fi
350
351 log_it TARGET_PART $TARGET_PART
352 sleep 5
353
354 rm -rf /usr/ports
355 ln -s /freebsd/${PORTS_PATH} /usr/ports
356
357 rm -rf /usr/src
358 ln -s /freebsd/${SRC_PATH} /usr/src
359
360 if $do_world ; then
361         if [ "x${OBJ_PATH}" != "x" ] ; then
362                 rm -rf /usr/obj
363                 mkdir -p /freebsd/${OBJ_PATH}
364                 ln -s /freebsd/${OBJ_PATH} /usr/obj
365         else
366                 rm -rf /usr/obj
367                 mkdir -p /usr/obj
368         fi
369 fi
370
371 #######################################################################
372
373 for i in ${PORTS_WE_WANT}
374 do
375         if [ ! -d $i ]  ; then
376                 echo "Port $i not found" 1>&2
377                 exit 2
378         fi
379 done
380
381 export PORTS_WE_WANT
382 export PORTS_OPTS
383
384 #######################################################################
385
386 log_it Prepare destination partition
387 newfs -O2 -U /dev/${TARGET_PART} > /dev/null
388 mount /dev/${TARGET_PART} /mnt
389 mkdir -p /mnt/dev
390 mount -t devfs devfs /mnt/dev
391
392 if [ "x${REMOTEDISTFILES}" != "x" ] ; then
393         rm -rf /freebsd/${PORTS_PATH}/distfiles
394         ln -s /freebsd/distfiles /freebsd/${PORTS_PATH}/distfiles
395         mkdir -p /freebsd/distfiles
396         mount  ${REMOTEDISTFILES} /freebsd/distfiles
397 fi
398
399 log_it "Start prefetch of ports distfiles"
400 ports_prefetch &
401
402 if $do_world ; then
403         (
404         cd /usr/src
405         log_it "Buildworld"
406         make ${JARG} -s buildworld ${SRCCONF} > /mnt/_.bw 2>&1
407         )
408 fi
409
410 if $do_kernel ; then
411         (
412         cd /usr/src
413         log_it "Buildkernel"
414         make ${JARG} -s buildkernel KERNCONF=$KERNCONF > /mnt/_.bk 2>&1
415         )
416 fi
417
418
419 log_it Installworld
420 (cd /usr/src && make ${JARG} installworld DESTDIR=/mnt ${SRCCONF} ) \
421         > /mnt/_.iw 2>&1
422
423 log_it distribution
424 (cd /usr/src/etc && make -m /usr/src/share/mk distribution DESTDIR=/mnt ${SRCCONF} ) \
425         > /mnt/_.dist 2>&1
426
427 log_it Installkernel
428 (cd /usr/src && make ${JARG} installkernel DESTDIR=/mnt KERNCONF=$KERNCONF ) \
429         > /mnt/_.ik 2>&1
430
431 if [ "x${OBJ_PATH}" != "x" ] ; then
432         rmdir /mnt/usr/obj
433         ln -s /freebsd/${OBJ_PATH} /mnt/usr/obj
434 fi
435
436 log_it Wait for ports prefetch
437 wait
438
439 log_it Move filesystems
440
441 if [ "x${REMOTEDISTFILES}" != "x" ] ; then
442         umount /freebsd/distfiles
443 fi
444 umount /dev/${FREEBSD_PART} || true
445 mkdir -p /mnt/freebsd
446 mount /dev/${FREEBSD_PART} /mnt/freebsd
447 if [ "x${REMOTEDISTFILES}" != "x" ] ; then
448         mount  ${REMOTEDISTFILES} /mnt/freebsd/distfiles
449 fi
450
451 rm -rf /mnt/usr/ports || true
452 ln -s /freebsd/${PORTS_PATH} /mnt/usr/ports
453
454 rm -rf /mnt/usr/src || true
455 ln -s /freebsd/${SRC_PATH} /mnt/usr/src
456
457 log_it Build and install ports
458
459 # Make sure fetching will work in the chroot
460 if [ -f /etc/resolv.conf ] ; then
461         log_it copy resolv.conf
462         cp /etc/resolv.conf /mnt/etc
463         chflags schg /mnt/etc/resolv.conf
464 fi
465
466 if [ -f /etc/localtime ] ; then
467         log_it copy localtime
468         cp /etc/localtime /mnt/etc
469 fi
470
471 log_it copy ports config files
472 (cd / ; find var/db/ports -print | cpio -dumpv /mnt )
473
474 log_it ldconfig in chroot
475 chroot /mnt sh /etc/rc.d/ldconfig start
476
477 log_it before_ports
478
479         before_ports 
480 )
481
482 log_it build ports
483 pwd
484 cp $0 /mnt/root
485 cp /tmp/_sb_log /mnt/tmp
486 b=`basename $0`
487 if [ "x$c_arg" != "x" ] ; then
488         cp $c_arg /mnt/root
489         chroot /mnt sh /root/$0 -c /root/`basename $c_arg` $use_pkg chroot_script 
490 else
491         chroot /mnt sh /root/$0 $use_pkg chroot_script
492 fi
493 cp /mnt/tmp/_sb_log /tmp
494
495 log_it fixing fstab
496 sed "/[         ]\/[    ]/s;^[^         ]*[     ];/dev/${TARGET_PART}   ;" \
497         /etc/fstab > /mnt/etc/fstab
498
499 log_it create all mountpoints
500 grep -v '^[     ]*#' /mnt/etc/fstab | 
501 while read a b c
502 do
503         mkdir -p /mnt/$b
504 done
505
506 if [ "x$SERCONS" != "xfalse" ] ; then
507         log_it serial console
508         echo " -h" > /mnt/boot.config
509         sed -i "" -e /ttyd0/s/off/on/ /mnt/etc/ttys
510         sed -i "" -e /ttyu0/s/off/on/ /mnt/etc/ttys
511         sed -i "" -e '/^ttyv[0-8]/s/    on/     off/' /mnt/etc/ttys
512 fi
513
514 log_it move config files
515 (
516         cd /mnt
517         mkdir root/configfiles_dist
518         find ${CONFIGFILES} -print | cpio -dumpv root/configfiles_dist
519 )
520
521 (cd / && find ${CONFIGFILES} -print | cpio -dumpv /mnt)
522
523 log_it final_root
524 ( final_root )
525 log_it final_chroot
526 cp /tmp/_sb_log /mnt/tmp
527 if [ "x$c_arg" != "x" ] ; then
528         chroot /mnt sh /root/$0 -c /root/`basename $c_arg` final_chroot
529 else
530         chroot /mnt sh /root/$0 final_chroot
531 fi
532 cp /mnt/tmp/_sb_log /tmp
533 log_it "Check these messages (if any):"
534 grep '^Stop' /mnt/_* || true
535 log_it DONE