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