1#         $NetBSD: Makefile.image,v 1.44 2024/05/17 21:31:10 christos Exp $
2#
3# Makefile snippet to build a tree from the provided lists,
4# and make an ffs file system image from that tree
5#
6# Required variables:
7#         NETBSDSRCDIR        top level of src tree (set by <bsd.own.mk>)
8#         LISTS               list file(s) to use
9#         IMAGEDEPENDS        depends for ${IMAGE}
10#         IMAGEENDIAN         endianness of ${IMAGE}
11#         IMAGESIZE size of ${IMAGE}
12#         MTREECONF mtree specfiles to use to build a master specfile
13#
14# Optional variables:
15#         IMAGE               name of target image
16#         IMAGEPREBUILD       additional operations to run pre image creation
17#         IMAGEPOSTBUILD      operation to run on ${IMAGE} ${.TARGET} after its built
18#                             (if this returns non zero, ${.TARGET} is removed)
19#         IMAGERUNTIME        files/directories to copy from $DESTDIR onto the image
20#         IMAGESPECEXTRA      files/directories to add to the spec
21#         CRUNCHBIN name of crunchgen(1)ed binary
22#         DESTDIR             destination directory
23#         MAKEFS_FLAGS        extra options to ${TOOL_MAKEFS}
24#         PARSELISTENV        environment variables to set for parselist.awk
25#         WORKDIR             directory to build image in to
26#         IMAGETAR  tar.gz file to create containing ${IMAGE}'s contents
27#
28#         IMAGE_RELEASEDIR    where to install ${IMAGE}.gz
29#         IMAGETAR_RELEASEDIR where to install ${IMAGETAR}
30#
31
32.if !defined(_MAKEFILE_IMAGE_)
33_MAKEFILE_IMAGE_=1
34
35
36WORKDIR?= work
37WORKSPEC?=          work.spec
38WORKBUILT?=         work.built
39CUROBJDIR!=     cd ${.CURDIR} && ${PRINTOBJDIR}
40
41.include "${DISTRIBDIR}/common/Makefile.parselist"
42
43PARSELISTENV+=      TARGETDIR=${.OBJDIR}/${WORKDIR:Q}
44
45.if ${MKREPRO_TIMESTAMP:Uno} != "no"
46MAKEFS_TIMESTAMP=-T "${MKREPRO_TIMESTAMP}"
47PAX_TIMESTAMP=--timestamp "${MKREPRO_TIMESTAMP}"
48GZIP_N_FLAG=-n
49.endif
50MAKESPEC= ${HOST_SH} ${NETBSDSRCDIR}/etc/makespec
51
52.if ${MAKEVERBOSE} >= 2
53PAX_v?= -v
54.else
55PAX_v?=
56.endif
57
58
59GZIP_FLAGS= -9 ${GZIP_N_FLAG}
60
61.if !target(${WORKBUILT})                                             # {
62${WORKBUILT}: ${IMAGEDEPENDS} ${WORKSPEC} ${PARSELISTDEP} ${LISTS}
63#         There is a .PHONY ${CRUNCHBIN}, so check if out of date by hand
64#         Default to `.' if ${CRUNCHBIN} isn't set, to always force a rebuild.
65          [ "${.OODATE}" = ${CRUNCHBIN:U.} -a -f ${WORKBUILT} -a ${WORKBUILT} -nt ${CRUNCHBIN:U.} ]  || { \
66          ${_MKSHMSG} "  build " ${.CURDIR:T}/${WORKDIR}; \
67          rm -rf ${WORKDIR} ${WORKBUILT}; \
68          mkdir -m 755 ${WORKDIR} &&  \
69          ${TOOL_MTREE} -def ${WORKSPEC} -p ${WORKDIR}/ -UW && \
70          ${PARSELIST} -v mode=populate ${LISTS} | \
71          ${HOST_SH} -e ${POPULATE_DEBUG} \
72          && touch ${WORKBUILT} ; \
73          }
74
75CLEANFILES+=        ${WORKBUILT}
76
77clean cleandir distclean: cleanfsimage
78
79.PHONY: cleanfsimage
80
81cleanfsimage:
82          -rm -rf ${WORKDIR} ${WORKBUILT}
83
84.endif    # ! target (${WORKBUILT})                                   # }
85
86.if !target(${WORKSPEC})                                              # {
87${WORKSPEC}: ${MTREECONF} ${LISTS} ${PARSELISTDEP}
88          ${_MKTARGET_CREATE}
89          -rm -f ${.TARGET} ${.TARGET}.tmp
90          ( for i in ${MTREECONF}; do   \
91                    echo "# --" ; \
92                    echo "# entries from: $$i" ; \
93                    echo "#" ; \
94                    cat $$i ;           \
95                    echo "/unset all" ; \
96          done ) >> ${.TARGET}.tmp
97          ${PARSELIST} -v mode=mtree ${LISTS} >> ${.TARGET}.tmp \
98          && mv ${.TARGET}.tmp ${.TARGET}
99
100CLEANFILES+=        ${WORKSPEC} ${WORKSPEC}.tmp
101.endif    # ! target (${WORKSPEC})                                    # }
102
103.if defined(IMAGE)                                                    # {
104IMGMAKEFSOPTIONS?= -o bsize=4096,fsize=512
105${IMAGE}: ${WORKBUILT}
106.if defined(IMAGEPREBUILD)
107          ${IMAGEPREBUILD}
108.endif
109          if [ "X${IMAGERUNTIME}" != "X" ]; then                                \
110                    release_destdir=${CUROBJDIR}/${WORKDIR};                    \
111                    cd ${DESTDIR};                                                        \
112                    for imge in ${IMAGERUNTIME};                                \
113                    do                                                                    \
114                              ${TOOL_PAX} ${PAX_TIMESTAMP} -rw -pp ${PAX_v}     \
115                                        $${imge} $$release_destdir;             \
116                    done;                                                                 \
117                    cd "${CUROBJDIR}";                                          \
118          fi
119          for i in ${IMAGESPECEXTRA}; do                                                  \
120                    if [ -n "$$i" ] && [ -e ${WORKDIR}/$$i ]; then              \
121                        ${MAKESPEC} -d ${WORKDIR} $$i >> ${WORKSPEC};           \
122                    fi;                                                                   \
123          done
124          [ "${.OODATE}" = ${WORKBUILT} -a -f ${IMAGE} -a ! ${IMAGE} -ot ${WORKBUILT} ]  || { \
125          ${_MKSHMSG_CREATE} ${.CURDIR:T}/${.TARGET}; \
126          rm -f ${.TARGET} ${.TARGET}.tmp; \
127          ${TOOL_MAKEFS} -t ffs -B ${IMAGEENDIAN} -s ${IMAGESIZE} -F ${WORKSPEC} \
128              -xx ${MAKEFS_TIMESTAMP} -N ${NETBSDSRCDIR}/etc ${IMGMAKEFSOPTIONS} \
129              -o optimization=space,minfree=0 \
130              ${MAKEFS_FLAGS} ${.TARGET}.tmp ${WORKDIR} \
131          && mv -f ${.TARGET}.tmp ${.TARGET}; \
132          }
133.if defined(IMAGEPOSTBUILD)
134          ${IMAGEPOSTBUILD} || { rm -f ${.TARGET} ; false; }
135.endif
136
137.PHONY: fsimage
138fsimage: ${IMAGE}
139
140${IMAGE}.gz: ${IMAGE}
141          ${_MKTARGET_CREATE}
142          -rm -f ${.TARGET}
143          ${TOOL_GZIP} ${GZIP_FLAGS} -c ${.ALLSRC} > ${.TARGET}
144
145realall: ${IMAGE}
146
147.if defined(IMAGE_RELEASEDIR)
148release:: check_RELEASEDIR .WAIT ${IMAGE}.gz
149          ${RELEASE_INSTALL} ${IMAGE}.gz \
150              ${RELEASEDIR}/${RELEASEMACHINEDIR}/${IMAGE_RELEASEDIR}
151.endif
152
153CLEANFILES+=        ${IMAGE} ${IMAGE}.gz ${IMAGE}.tmp
154.endif    # ! defined(IMAGE)                                          # }
155
156
157.if defined(IMAGETAR)                                                           # {
158${IMAGETAR}: ${WORKBUILT} ${WORKSPEC} ${IMAGEDEPENDS}
159          ${_MKTARGET_CREATE}
160          ( cd ${WORKDIR}; \
161            GZIP=${GZIP_FLAGS:Q} \
162            ${TOOL_PAX} ${PAX_TIMESTAMP} --use-compress-program=${TOOL_GZIP:Q} \
163                -ON ${NETBSDSRCDIR}/etc -wdM <${.OBJDIR}/${WORKSPEC} \
164          ) > ${.TARGET}.tmp \
165          && mv ${.TARGET}.tmp ${.TARGET}
166
167realall: ${IMAGETAR}
168
169CLEANFILES+=        ${IMAGETAR} ${IMAGETAR}.tmp
170
171.if defined(IMAGETAR_RELEASEDIR)
172release:: check_RELEASEDIR .WAIT ${IMAGETAR}
173          ${RELEASE_INSTALL} ${IMAGETAR} \
174              ${RELEASEDIR}/${RELEASEMACHINEDIR}/${IMAGETAR_RELEASEDIR}
175.endif
176
177.endif    # ! defined(IMAGETAR)                                                 # }
178
179
180.endif    # _MAKEFILE_IMAGE_
181