#       $NetBSD: Makefile.bootcd,v 1.56 2025/04/27 21:35:36 pgoyette Exp $
#
# Makefile snipped to create a CD/DVD ISO
#

# XXX TODO:
# 1) merge with src/distrib/cdrom
# 2) teach makefs to add data from more than 1 directory (see below)

#
# Required variables:
#       CDBASE          Basename of the iso
#
# Optional variables:
#       CDRELEASE       Set to 'true' to include $RELEASEDIR/$RELEASEMACHINEDIR on the CD
#       CDRELEASE_NOISOS Excludes installation/cdrom directory if set
#       CDRELEASE_NODEBUG       Excludes debug sets if set
#       CDSOURCE        Set to 'true' to include $RELEASEDIR/source on the CD
#       CDEXTRA         Set to a list of files or directories containing extra
#                       stuff to put on CD (set by build.sh -C flag)
#       CDBUILDEXTRA    Set to a list of files or directories containing extra
#                       stuff to put on CD (use in Makefiles)
#       CDEXTRA_SKIP    A list of file exclusion paths to exclude when copying
#                       directories of extra stuff in CDEXTRA AND CDBUILDEXTRA
#       CDDEV_POPULATE  Set to 'true' to fully populate /dev on the CD (and
#                       safe a tmpfs union mount)
#       BOOT            Defaults to $DESTDIR/usr/mdec/boot
#       BOOTXX_CD9660   Defaults to $DESTDIR/usr/mdec/bootxx_cd9660
#       CDBOOTOPTIONS   Options for installboot, eg -o console=com0,speed=9600
#       CDMAKEFSOPTIONS Options for makefs, eg bootimage=i386;bootxx,no-emul-boot
#       CDMAKEFSEXTRAOPTS additional options for makefs, e.g. -F specfile
#       CDROMS_RELEASEDIR Where to install ${CDBASE}.iso
#       CDINSTKERNEL    instkernel directory (relative to ${.CURDIR})
#       CDKERNELS       couples of the form:
#                               source  name_on_cd
#       CDRUNTIME       files/directories to copy from $DESTDIR onto the CD
#       CD_SETS         sets to be extracted onto the CD
#       SETS_DIR        where the CD_SETS are found (default provided)
# source kernels are copied from ${CDINSTKERNEL} (or its obj dir)
# note that as of yet, bootxx_cd9660 can't load kernel names of more than
# 8 chars (though they can be in a sub-directory meaning the pathname is
# longer than 8 chars)
#

BOOT?=          ${DESTDIR}/usr/mdec/boot
BOOTXX_CD9660?= ${DESTDIR}/usr/mdec/bootxx_cd9660
CDRELEASE?=     false
CDSOURCE?=      false
CDDEV_POPULATE?=false
if ${CDRELEASE} == false
CDROMS_RELEASEDIR?=     ${MACHINE}/installation/cdrom
else
CDROMS_RELEASEDIR?=     images
endif
if defined(CDRELEASE_NOISOS)
CDRELEASE_EXCLUDE+=     -s ',./installation/cdrom.*,,gp'
endif
if defined(CDRELEASE_NOCOMPAT)
 for sufx in tgz tar.xz
CDRELEASE_EXCLUDE+=     -s ',./binary/sets/base32.${sufx},,gp'
CDRELEASE_EXCLUDE+=     -s ',./binary/sets/base64.${sufx},,gp'
 endfor
endif
if defined(CDRELEASE_NODEBUG)
 for sufx in tgz tar.xz
CDRELEASE_EXCLUDE+=     -s ',./binary/sets/debug.${sufx},,gp'
CDRELEASE_EXCLUDE+=     -s ',./binary/sets/debug32.${sufx},,gp'
CDRELEASE_EXCLUDE+=     -s ',./binary/sets/debug64.${sufx},,gp'
CDRELEASE_EXCLUDE+=     -s ',./binary/sets/xdebug.${sufx},,gp'
 endfor
endif
if defined(CDRELEASE_NOHTML)
 for sufx in tgz tar.xz
CDRELEASE_EXCLUDE+=     -s ',./binary/sets/manhtml.${sufx},,gp'
 endfor
endif
if defined(CDRELEASE_NOTESTS)
 for sufx in tgz tar.xz
CDRELEASE_EXCLUDE+=     -s ',./binary/sets/tests.${sufx},,gp'
 endfor
endif
if !defined(CDRELEASE_LIVEIMAGE)
CDRELEASE_EXCLUDE+=     -s ',./installation/liveimage.*,,gp'
endif
if !defined(CDRELEASE_INSTALLIMAGE)
CDRELEASE_EXCLUDE+=     -s ',./installation/installimage.*,,gp'
endif

SETS_DIR?=      ${RELEASEDIR}/${RELEASEMACHINEDIR}/binary/sets

include <bsd.own.mk>            # For PRINTOBJDIR
include <bsd.kernobj.mk>        # For KERNSRCDIR

DISTRIBVER!=    ${HOST_SH} ${KERNSRCDIR}/conf/osrelease.sh
DISTRIBREV!=    ${HOST_SH} ${KERNSRCDIR}/conf/osrelease.sh -s
CUROBJDIR!=     cd ${.CURDIR} && ${PRINTOBJDIR}
ISO_VOLID!=     echo NETBSD_${DISTRIBREV} | tr a-z A-Z
PUBLISHER?= The_NetBSD_Project
if defined(CDMAKEFSOPTIONS)
_CDMAKEFSOPTIONS=       rockridge,label=${ISO_VOLID},publisher=${PUBLISHER},${CDMAKEFSOPTIONS}
else
_CDMAKEFSOPTIONS=       rockridge,label=${ISO_VOLID},publisher=${PUBLISHER}
endif

if ${MKREPRO_TIMESTAMP:Uno} != "no"
MAKEFS_TIMESTAMP=-T "${MKREPRO_TIMESTAMP}"
PAX_TIMESTAMP=--timestamp "${MKREPRO_TIMESTAMP}"
endif
MAKESPEC=       ${HOST_SH} ${NETBSDSRCDIR}/etc/makespec

if ${MKUNPRIVED} == "no"
CD_METALOG.unpriv=
mtunpriv=
else
CD_METALOG.unpriv=-M ${METALOG}.sanitised
mtunpriv="-U"
endif

# Stuff that should come from elsewhere - XXX where? - HF
RM?=            rm
MKDIR?=         mkdir -p
CHMOD?=         chmod
ECHO?=          echo

if ${CDRELEASE} == false
CDIMAGE=        ${CDBASE}.iso
elif ${CDBASE:M*dvd}
CDIMAGE=        NetBSD-${DISTRIBVER}-${CDBASE:S/dvd$//}-dvd.iso
else
CDIMAGE=        NetBSD-${DISTRIBVER}-${CDBASE:S/cd$//}.iso
endif
WORKSPEC=       fs.spec

CLEANFILES+=    ${CDIMAGE}
CLEANFILES+=    bootxx.${MACHINE}
CLEANFILES+=    ${WORKSPEC}

CDSETSENV=      DESTDIR=${DESTDIR:Q} \
               MACHINE=${MACHINE:Q} \
               MACHINE_ARCH=${MACHINE_ARCH:Q} \
               AWK=${TOOL_AWK:Q} \
               CKSUM=${TOOL_CKSUM:Q} \
               DB=${TOOL_DB:Q} \
               HOST_SH=${HOST_SH:Q} \
               MAKE=${MAKE:Q} \
               MKTEMP=${TOOL_MKTEMP:Q} \
               MTREE=${TOOL_MTREE:Q} \
               PAX=${TOOL_PAX:Q} \
               COMPRESS_PROGRAM=${COMPRESS_PROGRAM:Q} \
               GZIP=${GZIP_FLAGS:Q} \
               PKG_CREATE=${TOOL_PKG_CREATE:Q} \
               SED=${TOOL_SED:Q} \
               TSORT=${TSORT:Q} \
               MKRUMP=no \
               MKCOMPAT=no \
               MKDEBUG=no \
               MKDEBUGLIB=no

CDSETSCMD=      cd ${NETBSDSRCDIR}/distrib/sets && \
               ${CDSETSENV} \
               ${HOST_SH}

include "${NETBSDSRCDIR}/distrib/common/Makefile.distrib"

if defined(CDINSTKERNEL)
_INSTKERNELNOBJDIR!=    cd ${.CURDIR}/${CDINSTKERNEL} && ${PRINTOBJDIR}
endif
if exists(${DESTDIR}/usr/mdec/bootxx_cd9660)
if exists(${DESTDIR}/usr/mdec/boot.${MACHINE})
BOOT2=boot.${MACHINE}
else
BOOT2=boot
endif
endif

prepare:
       ${MKDIR} ${MKDIRPERM} "${CUROBJDIR}/cdrom"
if ${KERNEL_DIR:Uno} == "yes"
       ${MKDIR} ${MKDIRPERM} "${CUROBJDIR}/cdrom/netbsd"
endif
if defined(CDKERNELS)
for kernel target in ${CDKERNELS}
       ${INSTALL} ${COPY} -m 0644 ${_INSTKERNELNOBJDIR}/${kernel} cdrom/${target}
endfor
if exists(${DESTDIR}/usr/mdec/bootxx_cd9660)
       ${RM} -f cdrom/${BOOT2}
       ${INSTALL} ${COPY} -m 0644 ${DESTDIR}/usr/mdec/${BOOT2} cdrom/${BOOT2}
       ${RM} -f bootxx.${MACHINE}
       ${INSTALL} ${COPY} -m 0644 ${DESTDIR}/usr/mdec/bootxx_cd9660 bootxx.${MACHINE}
       ${CHMOD} +w bootxx.${MACHINE}
if defined(CDBOOTOPTIONS)
       ${TOOL_INSTALLBOOT} -m${MACHINE} -e ${CDBOOTOPTIONS} bootxx.${MACHINE}
endif
endif
endif

if ${MAKEVERBOSE} >= 2
PAX_v?= -v
else
PAX_v?=
endif

# Copy $RELEASEDIR/${MACHINE} in the CDROM dir
#
# XXX This could be done a lot easier if makefs(8) could
# XXX include more than one directory on the image - HF
#
copy-releasedir:
       ${RM} -f ${RELEASEDIR}/${CDROMS_RELEASEDIR}/${CDIMAGE}
       if ${CDRELEASE}; then                                           \
               if [ ! -d ${RELEASEDIR}/${RELEASEMACHINEDIR} ]; then    \
                       echo "Missing ${RELEASEDIR}/${RELEASEMACHINEDIR}, aborting"; \
                       exit 1;                                         \
               fi;                                                     \
               ${MKDIR} ${MKDIRPERM} "${CUROBJDIR}/cdrom/${RELEASEMACHINEDIR}";        \
               release_destdir="${CUROBJDIR}/cdrom/${RELEASEMACHINEDIR}";      \
               cd ${RELEASEDIR}/${RELEASEMACHINEDIR};                  \
               echo Copying $$(pwd) to $$release_destdir ...;          \
               ${TOOL_PAX} ${PAX_TIMESTAMP}                            \
                       -rw -pe ${PAX_v}                                \
                       ${CDRELEASE_EXCLUDE}                            \
                       . $$release_destdir;                            \
               cd "${CUROBJDIR}";                                      \
       fi
       if ${CDSOURCE}; then                                            \
               if [ ! -d ${RELEASEDIR}/source ]; then                  \
                       echo "Missing ${RELEASEDIR}/source, aborting";  \
                       exit 1;                                         \
               fi;                                                     \
               ${MKDIR} ${MKDIRPERM} "${CUROBJDIR}/cdrom/source";      \
               release_destdir="${CUROBJDIR}/cdrom/source";            \
               cd ${RELEASEDIR}/source;                                \
               echo Copying $$(pwd) to $$release_destdir ...;          \
               ${TOOL_PAX} ${PAX_TIMESTAMP}                            \
                       -rw -pe ${PAX_v}                                \
                       . $$release_destdir;                            \
               cd "${CUROBJDIR}";                                      \
       fi
       if [ "X${CDRUNTIME}" != "X" ]; then                             \
               release_destdir=$${curdir}/cdrom;                       \
               cd $$release_destdir;                                   \
               cd ${DESTDIR};                                          \
               for cde in ${CDRUNTIME};                                \
               do                                                      \
                       ${TOOL_PAX} ${PAX_TIMESTAMP} -rw -pp ${PAX_v}   \
                               $${cde} $$release_destdir;              \
               done;                                                   \
               cd "${CUROBJDIR}";                                      \
       fi
       if [ "X${CDEXTRA}${CDBUILDEXTRA}" != "X" ]; then                \
               skipflag="";                                            \
               cdextra_skip="${CDEXTRA_SKIP}";                         \
               if [ "X$${cdextra_skip}" != "X" ]; then                 \
                       rm -f cdskip;                                   \
                       for skip in $${cdextra_skip};                   \
                       do                                              \
                               echo $${skip} >> cdskip;                \
                       done;                                           \
                       skipflag="-X ${CUROBJDIR:Q}/cdskip";            \
               fi;                                                     \
               cdextra="${CDEXTRA}";                                   \
               cdbuildextra="${CDBUILDEXTRA}";                         \
               for cde in $${cdextra} $${cdbuildextra};                \
               do                                                      \
                       release_destdir="${CUROBJDIR}/cdrom";           \
                       if [ -f $${cde} ]; then                         \
                               echo Copying $${cde} to $$release_destdir ...;  \
                               ${INSTALL} ${COPY} -m 0644 $${cde} $${release_destdir}; \
                       elif [ -d $${cde} ]; then                       \
                               cd $${cde};                             \
                               echo Copying $$(pwd) to $$release_destdir ...;  \
                               ${TOOL_MTREE} -c $${skipflag} |         \
                                       ${TOOL_PAX} ${PAX_TIMESTAMP}    \
                                       -rw -pe ${PAX_v}                \
                                       -M $$release_destdir;           \
                       else                                            \
                               echo "Missing $${cde}, aborting";       \
                               exit 1;                                 \
                       fi;                                             \
                       cd "${CUROBJDIR}";                              \
               done;                                                   \
       fi
if !empty(CD_SETS)
       ${MKDIR} ${MKDIRPERM} "${CUROBJDIR}/cdrom/etc/mtree"
for set in ${CD_SETS}
       if [ -f ${CUROBJDIR:Q}/cdrom/etc/mtree/set.${set} ]; then       \
               ${CHMOD} +w ${CUROBJDIR:Q}/cdrom/etc/mtree/set.${set};  \
       fi;                                                             \
       ${CDSETSCMD} ./maketars -i "${CUROBJDIR}/cdrom"                 \
           ${CD_METALOG.unpriv} ${mtunpriv} -N ${NETBSDSRCDIR}/etc     \
           -xx -F "${CUROBJDIR}/cdrom/etc/mtree"                       \
           -d "${DESTDIR:S,^$,/,}" ${set}
endfor
       if [ -d "${CUROBJDIR}/cdrom/var/spool/ftp/hidden" ]; then       \
               ${CHMOD} +r "${CUROBJDIR}/cdrom/var/spool/ftp/hidden";  \
       fi
endif

if ${CDDEV_POPULATE} != true
DELDEV=-e '/^\.\/dev\/.*type=char/d'
endif

image:
       @echo Preparing spec files for makefs...
       ${RM} -f ${WORKSPEC}
       if [ -d cdrom/etc/mtree ]; then                         \
               cat cdrom/etc/mtree/* |                         \
                   ${TOOL_SED} -e 's/ size=[0-9]*//'           \
                    ${DELDEV}                                  \
                    -e '/^\.\/etc\/gettytab/d' > ${WORKSPEC};  \
       fi
       if [ -r cdrom/dev/MAKEDEV ] &&                          \
                ${CDDEV_POPULATE} == true; then                \
               ${HOST_SH} cdrom/dev/MAKEDEV -s init |          \
                   ${TOOL_SED} -e '/^\. type=dir/d'            \
                       -e 's,^\.,./dev,' >> ${WORKSPEC};       \
       fi
if defined(SPEC_IN)
       cat ${SPEC_IN} >> ${WORKSPEC}
endif
if defined(SECONDARY_BOOT)
       echo "./${SECONDARY_BOOT} type=file uname=root gname=wheel mode=0444" \
           >> ${WORKSPEC}
endif
if defined(SPEC_EXTRA)
       cat ${SPEC_EXTRA} >> ${WORKSPEC}
endif
       if [ ! -s ${WORKSPEC} ]; then \
           ${MAKESPEC} -d cdrom . > ${WORKSPEC}; \
       else \
           for i in ${RELEASEMACHINEDIR} source ${CDEXTRA} ${CDBUILDEXTRA}; do\
               if [ -n "$$i" ] && [ -e cdrom/$$i ]; then \
                   ${MAKESPEC} -d cdrom $$i >> ${WORKSPEC}; \
               fi; \
           done; \
       fi
       ${TOOL_MAKEFS} -N ${NETBSDSRCDIR}/etc -t cd9660 -F ${WORKSPEC} -xx \
           ${MAKEFS_TIMESTAMP} ${CDMAKEFSEXTRAOPTS} -o ${_CDMAKEFSOPTIONS:Q} \
           ${CDIMAGE} cdrom

if ${CDRELEASE} == false
release: prepare .WAIT prepare_md_post .WAIT copy-releasedir .WAIT image_md_pre .WAIT image .WAIT image_md_post
       ${MKDIR} ${MKDIRPERM} ${RELEASEDIR}/${CDROMS_RELEASEDIR}
       ${RELEASE_INSTALL} ${CDIMAGE} ${RELEASEDIR}/${CDROMS_RELEASEDIR}

iso_image:
else
release:

iso_image: prepare .WAIT prepare_md_post .WAIT copy-releasedir .WAIT image_md_pre .WAIT image .WAIT image_md_post
       ${MKDIR} ${MKDIRPERM} ${RELEASEDIR}/${CDROMS_RELEASEDIR}
       ${RELEASE_INSTALL} ${CDIMAGE} ${RELEASEDIR}/${CDROMS_RELEASEDIR}
endif

clean:
       @if [ -d cdrom/var/spool/ftp/hidden ]; then             \
               ${CHMOD} +r cdrom/var/spool/ftp/hidden;         \
       fi      # XXX
       ${RM} -fr cdrom

prepare_md_post: .PHONY
image_md_post: .PHONY
image_md_pre: .PHONY

include <bsd.prog.mk>