script/lib/ansi: add additional ANSI style codes
[CDN/Mosi.git] / script / makeworld
1 #!/bin/sh
2
3 # Root directory of makeworld
4 ROOT="$(realpath "$(dirname "${0}")/../worlds")"
5
6 # Makeworld dir structure should contain, at minimum:
7 # script
8 #  makeworld (this file)
9 # seed
10 #  base
11 #   <ARCH> (arch of build host: i386, amd64, etc)
12 #    base.* (virgin base tree of same arch as host, used to seed chroot for clean build)
13 # <TARGET> (i386, amd64, etc)
14 #  <CONFIG> (GENERIC, SABA, SS4200, etc)
15 #   config
16 #    make.conf
17 #    src.conf
18 #    CONFIG (Matches config name: GENERIC, SABA, SS4200, etc)
19
20 # Going to build this config:
21 TARGET="${TARGET:-i386}"
22 CONFIG="${CONFIG:-GENERIC}"
23 MAKEOPTS="${MAKEOPTS:-"-j4"}"
24
25 # Check if it exists
26 [ -d "${ROOT}/${TARGET}/${CONFIG}" ] || wtf "${TARGET}/${CONFIG} doesn't exist"
27
28 # Target world directory
29 world="${ROOT}/${TARGET}/${CONFIG}"
30 # Source chroot seed directory
31 seed="${ROOT}/seed/base/$(uname -m)"
32 # Root directory for chroot
33 build="${ROOT}/seed/chroot-${TARGET}-${CONFIG}"
34
35 # Default build phases
36 phases="${phases:-buildworld buildkernel distrib-dirs installworld installkernel distribution}"
37
38 date="$(date +%Y%m%d)"
39
40 # Functions
41 meh() { printf " \033[1;32m*\033[0m %s\n" "${*}"; }
42 omg() { printf " \033[1;33m*\033[0m %s\n" "${*}"; }
43 wtf() { printf " \033[1;31m* FAIL\033[0m %s\n" "${*}"; exit 1; }
44
45 # Prepare chroot for build
46 prepare() {
47   mount | grep -q "${build}" && wtf "Stuff is mounted under ${build}; cannot continue"
48
49   # Cleanup trap here, so that an abort during prepare can clean up properly
50   trap "cleanup" exit hup int term kill
51
52   meh "Preparing build chroot"
53   [ -d "${build}" ] && wtf "${build}: directory exists"
54   mkdir -p "${build}" || wtf
55   cat "${seed}"/base.?? | tar xCf "${build}" - || wtf
56   mkdir -p "${build}/usr/obj" || wtf
57
58   meh "Mounting chroot filesystems"
59   mkdir -p "${world}/obj"
60   mkdir -p "${world}/root"
61   mount -t devfs devfs "${build}/dev" || wtf
62   # Mount /usr/src as a union, so that changes to it will not affect the underlying tree
63   # unionfs suffers from deadlocks; don't use it
64   mount -t nullfs -r /usr/src "${build}/usr/src" || wtf
65   mount -t nullfs "${world}/obj" "${build}/usr/obj" || wtf
66   mount -t nullfs "${world}/root" "${build}/mnt" || wtf
67
68   if [ -d "${world}/config" ]
69   then
70     meh "Installing build-time configuration"
71     [ -f "${world}/config/${CONFIG}" ] && cp "${world}/config/${CONFIG}" "/usr/src/sys/${TARGET}/conf/"
72     [ -f "${world}/config/make.conf" ] && cp "${world}/config/make.conf" "${build}/etc/"
73     [ -f "${world}/config/src.conf" ] && cp "${world}/config/src.conf" "${build}/etc/"
74   fi
75 }
76
77 # Cleanup chroot
78 cleanup() {
79   meh "Cleaning up"
80   umount -f "${build}/mnt"
81   umount -f "${build}/usr/obj"
82   umount -f "${build}/usr/src"
83   umount -f "${build}/dev"
84   mount | grep -q "${build}" && wtf "Stuff is still mounted under ${build}; not removing"
85   chflags -R noschg "${build}"
86   rm -Rf "${build}"
87   trap "" exit hup int term kill
88 }
89
90 if [ -d "${build}" ]
91 then
92   omg "${build}: directory exists; purging"
93   cleanup
94 fi
95
96 prepare
97
98 meh "Seed: ${seed}"
99 meh "Config: ${TARGET}/${CONFIG}"
100 meh "Builddir: ${build}"
101 meh "make ${MAKEOPTS}"
102 meh "DESTDIR=${world}/root"
103
104 # Construct environment for chroot build
105 env="
106 USER=root
107 HOME=/root
108 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
109 SHELL=/bin/sh
110 "
111
112 for phase in ${phases}
113 do
114   meh "==> Phase: ${phase}"
115   script "${world}/${date}-${phase}.log" env -i ${env} chroot "${build}" sh -c \
116     "cd /usr/src; time make ${MAKEOPTS} ${phase} TARGET=${TARGET} KERNCONF=${CONFIG} DESTDIR=/mnt" || wtf "chroot-cmd ${phase}"
117 done
118
119 # Copy the config files into the target, to keep a record of the build options
120 [ -f "${world}/config/${CONFIG}" ] && cp "${world}/config/${CONFIG}" "${build}/boot/kernel/"
121 [ -f "${world}/config/make.conf" ] && cp "${world}/config/make.conf" "${build}/etc/"
122 [ -f "${world}/config/src.conf" ] && cp "${world}/config/src.conf" "${build}/etc/"