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