3 # Makeworld dir structure should contain, at minimum:
5 # makeworld (this file)
9 # <ARCH> (arch of build host: i386, amd64, etc)
10 # base.* (virgin base tree of same arch as host, used to seed chroot for clean build)
11 # <TARGET> (i386, amd64, etc)
12 # <CONFIG> (GENERIC, SABA, SS4200, etc)
16 # CONFIG (Matches config name: GENERIC, SABA, SS4200, etc)
18 # Load shlib and modules
19 _root="$(dirname "${0}")"; . "${_root}/lib/env.sh"
23 [ "${*}" ] && printf "%s\n\n" "${*}"
24 echo "Usage: $(basename "${0}") -m <makeopts> -t <target> -c <config> <target, ...>"
25 echo " -m <makeopts> Provide additional flags to make"
26 echo " -t <target> Target architecture (i386, amd64)"
27 echo " -c <config> Target configuration (in worlds/<target>/<config>)"
30 echo "Available make targets:"
31 for target in ${make_tgts}
38 # Prepare chroot for build
40 # Verify environment sanity
41 [ -d "${build}" ] && omg "${build}: directory exists; purging" && cleanup
42 mount | grep -q "${build}" && wtf "Stuff is mounted under ${build}; cannot continue"
43 ls -1 "${seed}"/base.?? >/dev/null 2>&1 || wtf "Populate seed directory ${seed} first"
44 [ -f /usr/src/sys/conf/newvers.sh ] || wtf "Need sources in /usr/src to build"
46 # Cleanup trap here, so that an abort during prepare can clean up properly
47 trap "cleanup" exit hup int term kill
49 meh "Preparing build chroot"
50 [ -d "${build}" ] && wtf "${build}: directory exists"
51 mkdir -p "${build}" || wtf
52 cat "${seed}"/base.?? | tar xCf "${build}" - || wtf
53 mkdir -p "${build}/usr/obj" || wtf
55 meh "Mounting chroot filesystems"
56 mkdir -p "${world}/obj"
57 mkdir -p "${world}/root"
58 mount -t devfs devfs "${build}/dev" || wtf
59 # Mount /usr/src as a union, so that changes to it will not affect the underlying tree
60 # unionfs suffers from deadlocks; don't use it
61 mount -t nullfs -r /usr/src "${build}/usr/src" || wtf
62 mount -t nullfs "${world}/obj" "${build}/usr/obj" || wtf
63 mount -t nullfs "${world}/root" "${build}/mnt" || wtf
65 if [ -d "${world}/config" ]
67 meh "Installing build-time configuration"
68 [ -f "${world}/config/${CONFIG}" ] && cp "${world}/config/${CONFIG}" "/usr/src/sys/${TARGET}/conf/"
69 [ -f "${world}/config/make.conf" ] && cp "${world}/config/make.conf" "${build}/etc/"
70 [ -f "${world}/config/src.conf" ] && cp "${world}/config/src.conf" "${build}/etc/"
77 umount -f "${build}/mnt"
78 umount -f "${build}/usr/obj"
79 umount -f "${build}/usr/src"
80 umount -f "${build}/dev"
81 mount | grep -q "${build}" && wtf "Stuff is still mounted under ${build}; not removing"
82 chflags -R noschg "${build}"
84 trap "" exit hup int term kill
87 # Root directory of makeworld
88 ROOT="$(realpath "$(dirname "${0}")/../worlds")"
90 # Compute make -j<cpus*2>
91 make_cpus="$(sysctl -n hw.ncpu)"
92 make_jobs="$(( ${make_cpus} * 2 ))"
93 make_tgts="buildworld buildkernel distrib-dirs installworld installkernel distribution"
98 MAKEOPTS="-j${make_jobs}"
100 while getopts "m:t:c:h" opt
103 m) MAKEOPTS="${MAKEOPTS} ${OPTARG}" ;;
104 t) TARGET="${OPTARG}" ;;
105 c) CONFIG="${OPTARG}" ;;
107 [?]) pebkac "Unrecognized option ${opt}" ;;
110 shift $(( $OPTIND - 1 ))
112 # Build make target sequence
113 sequence="${*:-${make_tgts}}"
115 # Target world directory
116 world="${ROOT}/${TARGET}/${CONFIG}"
117 # Source chroot seed directory
118 seed="${ROOT}/seed/base/$(uname -m)"
119 # Root directory for chroot
120 build="${ROOT}/seed/chroot-${TARGET}-${CONFIG}"
122 # Environment for chroot build
126 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
130 date="$(date +%Y%m%d)"
132 # Check if target config exists
133 [ -d "${world}" ] || wtf "${TARGET}/${CONFIG} doesn't exist"
135 # Purge any build directory that might be left over
138 omg "${build}: directory exists; purging"
142 meh "Making world for ${TARGET}/${CONFIG}"
147 meh "Config: ${TARGET}/${CONFIG}"
148 meh "Builddir: ${build}"
149 meh "make ${MAKEOPTS}"
150 meh "DESTDIR=${world}/root"
152 for step in ${sequence}
154 meh "==> Phase: ${step}"
155 script "${world}/${date}-${step}.log" env -i ${env} chroot "${build}" sh -c \
156 "cd /usr/src; time make ${MAKEOPTS} ${step} TARGET=${TARGET} KERNCONF=${CONFIG} DESTDIR=/mnt" || wtf "chroot-cmd ${phase}"
159 # Copy the config files into the target, to keep a record of the build options
160 [ -f "${world}/config/${CONFIG}" ] && cp "${world}/config/${CONFIG}" "${build}/boot/kernel/"
161 [ -f "${world}/config/make.conf" ] && cp "${world}/config/make.conf" "${build}/etc/"
162 [ -f "${world}/config/src.conf" ] && cp "${world}/config/src.conf" "${build}/etc/"