xref: /freebsd/share/mk/bsd.man.mk (revision 51e8e8b0f36933814b1be08913857727876aece5)
1#
2# The include file <bsd.man.mk> handles installing manual pages and
3# their links.
4#
5#
6# +++ variables +++
7#
8# DESTDIR	Change the tree where the man pages gets installed. [not set]
9#
10# MANDIR	Base path for manual installation. [${SHAREDIR}/man/man]
11#
12# MANOWN	Manual owner. [${SHAREOWN}]
13#
14# MANGRP	Manual group. [${SHAREGRP}]
15#
16# MANMODE	Manual mode. [${NOBINMODE}]
17#
18# MANSUBDIR	Subdirectory under the manual page section, i.e. "/i386"
19#		or "/tahoe" for machine specific manual pages.
20#
21# MAN		The manual pages to be installed. For sections see
22#		variable ${SECTIONS}
23#
24# MANSRC.${MAN:T} Name of source file for an individual manual page.
25#		Defaults to the manual page name.
26#
27# MCOMPRESS_CMD	Program to compress man pages. Output is to
28#		stdout. [${COMPRESS_CMD}]
29#
30# MLINKS	List of manual page links (using a suffix). The
31#		linked-to file must come first, the linked file
32#		second, and there may be multiple pairs. The files
33#		are hard-linked.
34#
35# NO_MLINKS	If you do not want install manual page links. [not set]
36#
37# MANFILTER	command to pipe the raw man page through before compressing
38#		or installing.  Can be used to do sed substitution.
39#
40# MANBUILDCAT	create preformatted manual pages in addition to normal
41#		pages. [not set]
42#
43# MANDOC_CMD	command and flags to create preformatted pages
44#
45# MANGROUPS	A list of groups, each of which should be a variable containing
46# 		a list of manual pages in that group.  By default one group is
47# 		defined called "MAN".
48#
49# 		For each group, group-specific options may be set:
50# 		<group>OWN, <group>GRP, <group>MODE and <group>PACKAGE.
51#
52# +++ targets +++
53#
54#	maninstall:
55#		Install the manual pages and their links.
56#
57
58.if !target(__<bsd.init.mk>__)
59.error bsd.man.mk cannot be included directly.
60.endif
61
62MANGROUPS?=	MAN
63
64# MAN_SUBPACKAGE is the subpackage manpages will be installed in.  When
65# MANSPLITPKG is enabled, this is ignored and the subpackage is forced
66# to be "-man", otherwise it defaults to empty so manpages go in the
67# base package.  This can be set to "-dev" for manpages that should go
68# in the -dev package.
69MAN_SUBPACKAGE?=
70
71# The default man package, if not otherwise specified.
72MAN_PACKAGE=	${PACKAGE:Uutilities}
73
74# Backwards compatibility.
75MINSTALL?=	${MANINSTALL}
76
77CATDIR=		${MANDIR:H:S/$/\/cat/}
78CATEXT=		.cat
79MANDOC_CMD?=	mandoc -Tascii
80
81MCOMPRESS_CMD?=	${COMPRESS_CMD}
82MCOMPRESS_EXT?=	${COMPRESS_EXT}
83
84SECTIONS=	1 2 3 4 5 6 7 8 9
85.SUFFIXES:	${SECTIONS:S/^/./g}
86
87# Backwards compatibility.
88.if !defined(MAN)
89.for __sect in ${SECTIONS}
90MANGROUPS+=	MAN${__sect}
91.endfor
92.endif
93
94# Following the conventions of MANGROUPS, manpage links should be defined
95# as ${group}LINKS, which means the default groups' links would be called
96# MANLINKS.  However it's actually called MLINKS, so for compatibility,
97# use ${MLINKS} as the default group's links if it's set.
98.if defined(MLINKS)
99MANLINKS=	${MLINKS}
100.endif
101
102maninstall: realmaninstall manlinksinstall .PHONY
103# Make sure all manpages are installed before we try to link any.
104.ORDER: realmaninstall manlinksinstall
105realmaninstall: .PHONY
106manlinksinstall: .PHONY
107
108all-man:
109
110# Take groups from both MANGROUPS and MANGROUPS.yes, to allow syntax like
111# MANGROUPS.${MK_FOO}=FOO.  Sort and uniq the list of groups in case of
112# duplicates.
113.if defined(MANGROUPS) || defined(MANGROUPS.yes)
114MANGROUPS:=${MANGROUPS} ${MANGROUPS.yes}
115MANGROUPS:=${MANGROUPS:O:u}
116.endif
117
118.for __group in ${MANGROUPS}
119
120realmaninstall: realmaninstall-${__group}
121manlinksinstall: manlinksinstall-${__group}
122
123${__group}OWN?=		${MANOWN}
124${__group}GRP?=		${MANGRP}
125${__group}MODE?=	${MANMODE}
126# If MANSPLITPKG is enabled, ignore the requested man subpackage and put the
127# manpages in -man instead.
128.if ${MK_MANSPLITPKG} == "yes"
129${__group}SUBPACKAGE=	-man
130.else
131${__group}SUBPACKAGE?=	${MAN_SUBPACKAGE}
132.endif
133${__group}PACKAGE?=	${MAN_PACKAGE}${${__group}SUBPACKAGE}
134
135# Tag processing is only done for NO_ROOT installs.
136.if defined(NO_ROOT)
137.if !defined(${__group}TAGS) || ! ${${__group}TAGS:Mpackage=*}
138${__group}TAGS+=       package=${${__group}PACKAGE}
139.endif
140
141${__group}TAG_ARGS=	-T ${${__group}TAGS:ts,:[*]}
142.endif	# defined(NO_ROOT)
143
144${__group}INSTALL?=	${INSTALL} ${${__group}TAG_ARGS} \
145	-o ${${__group}OWN} -g ${${__group}GRP} -m ${${__group}MODE}
146
147.if ${MK_MANCOMPRESS} == "no"
148
149# Make special arrangements to filter to a temporary file at build time
150# for MK_MANCOMPRESS == no.
151.if defined(MANFILTER)
152FILTEXTENSION=		.filt
153.else
154FILTEXTENSION=
155.endif
156
157ZEXT=
158
159.if defined(MANFILTER)
160.if defined(${__group}) && !empty(${__group})
161CLEANFILES+=	${${__group}:T:S/$/${FILTEXTENSION}/g}
162CLEANFILES+=	${${__group}:T:S/$/${CATEXT}${FILTEXTENSION}/g}
163.for __page in ${${__group}}
164# Escape colons in target names to support manual pages whose
165# filenames contain colons.
166.for __target in ${__page:T:S/:/\:/g:S/$/${FILTEXTENSION}/g}
167all-man: ${__target}
168${__target}: ${MANSRC.${__page:T}:U${__page}}
169	${MANFILTER} < ${.ALLSRC} > ${.TARGET}
170.endfor
171.if defined(MANBUILDCAT) && !empty(MANBUILDCAT)
172.for __target in ${__page:T:S/:/\:/g:S/$/${CATEXT}${FILTEXTENSION}/g}
173all-man: ${__target}
174${__target}: ${MANSRC.${__page:T}:U${__page}}
175	${MANFILTER} < ${.ALLSRC} | ${MANDOC_CMD} > ${.TARGET}
176.endfor
177.endif
178.endfor
179.endif	# !empty(${__group})
180.else	# !defined(MANFILTER)
181.if defined(${__group}) && !empty(${__group})
182CLEANFILES+=	${${__group}:T:S/$/${CATEXT}/g}
183.if defined(MANBUILDCAT) && !empty(MANBUILDCAT)
184.for __page in ${${__group}}
185.for __target in ${__page:T:S/:/\:/g:S/$/${CATEXT}/g}
186all-man: ${__target}
187${__target}: ${MANSRC.${__page:T}:U${__page}}
188	${MANDOC_CMD} ${.ALLSRC} > ${.TARGET}
189.endfor
190.endfor
191.else
192.for __page in ${${__group}}
193.if defined(MANSRC.${__page:T})
194.for __target in ${__page:T:S/:/\:/g}
195all-man: ${__target}
196CLEANFILES+=	${__target}
197${__target}: ${MANSRC.${__page:T}}
198	${CP} ${.ALLSRC} ${.TARGET}
199.endfor
200.else
201all-man: ${__page}
202.endif
203.endfor
204.endif
205.endif
206.endif	# defined(MANFILTER)
207
208.else	# ${MK_MANCOMPRESS} == "yes"
209
210ZEXT=		${MCOMPRESS_EXT}
211
212.if defined(${__group}) && !empty(${__group})
213CLEANFILES+=	${${__group}:T:S/$/${MCOMPRESS_EXT}/g}
214CLEANFILES+=	${${__group}:T:S/$/${CATEXT}${MCOMPRESS_EXT}/g}
215.for __page in ${${__group}}
216.for __target in ${__page:T:S/:/\:/g:S/$/${MCOMPRESS_EXT}/}
217all-man: ${__target}
218${__target}: ${MANSRC.${__page:T}:U${__page}}
219.if defined(MANFILTER)
220	${MANFILTER} < ${.ALLSRC} | ${MCOMPRESS_CMD} > ${.TARGET}
221.else
222	${MCOMPRESS_CMD} ${.ALLSRC} > ${.TARGET}
223.endif
224.endfor
225.if defined(MANBUILDCAT) && !empty(MANBUILDCAT)
226.for __target in ${__page:T:S/:/\:/g:S/$/${CATEXT}${MCOMPRESS_EXT}/}
227all-man: ${__target}
228${__target}: ${MANSRC.${__page:T}:U${__page}}
229.if defined(MANFILTER)
230	${MANFILTER} < ${.ALLSRC} | ${MANDOC_CMD} | ${MCOMPRESS_CMD} > ${.TARGET}
231.else
232	${MANDOC_CMD} ${.ALLSRC} | ${MCOMPRESS_CMD} > ${.TARGET}
233.endif
234.endfor
235.endif
236.endfor
237.endif
238
239.endif	# ${MK_MANCOMPRESS} == "no"
240
241_MANLINKS=
242.if !defined(NO_MLINKS) && defined(${__group}LINKS) && !empty(${__group}LINKS)
243.for _oname _osect _dname _dsect in ${${__group}LINKS:C/\.([^.]*)$/.\1 \1/}
244_MANLINKS+=	${MANDIR}${_osect}${MANSUBDIR}/${_oname} \
245		${MANDIR}${_dsect}${MANSUBDIR}/${_dname}
246.if defined(MANBUILDCAT) && !empty(MANBUILDCAT)
247_MANLINKS+=	${CATDIR}${_osect}${MANSUBDIR}/${_oname} \
248		${CATDIR}${_dsect}${MANSUBDIR}/${_dname}
249.endif
250.endfor
251.endif
252
253.if defined(${__group}) && !empty(${__group})
254.if ${MK_STAGING_MAN} == "yes"
255STAGE_TARGETS+= stage_files.${__group}
256_mansets.${__group}:= ${${__group}:E:O:u:M*[1-9]:@s@man$s@}
257STAGE_SETS+= ${_mansets.${__group}}
258.for _page in ${${__group}}
259stage_files.${__group}.man${_page:T:E}: ${_page}
260.if target(${_page}${MCOMPRESS_EXT})
261stage_files.${__group}.man${_page:T:E}: ${_page}${MCOMPRESS_EXT}
262.endif
263STAGE_DIR.${__group}.man${_page:T:E}?= ${STAGE_OBJTOP}${MANDIR}${_page:T:E}${MANSUBDIR}
264.endfor
265.if !defined(NO_MLINKS) && !empty(${__group}LINKS)
266STAGE_SETS+= mlinks.${__group}
267STAGE_TARGETS+= stage_links.${__group}
268STAGE_LINKS.mlinks.${__group}:= ${${__group}LINKS:M*.[1-9]:@f@${f:S,^,${MANDIR}${f:E}${MANSUBDIR}/,}@}
269stage_links.mlinks.${__group}: ${_mansets.${__group}:@s@stage_files.${__group}.$s@}
270.endif
271.endif
272.endif
273
274realmaninstall-${__group}:
275.if defined(${__group}) && !empty(${__group})
276.for __page in ${${__group}}
277__mansrc.${__group}+=	${MANSRC.${__page:T}:U${__page}}
278.endfor
279realmaninstall-${__group}: ${__mansrc.${__group}}
280.if ${MK_MANCOMPRESS} == "no"
281.if defined(MANFILTER)
282.for __page in ${${__group}}
283	${${__group}INSTALL} ${__page:T:S/$/${FILTEXTENSION}/g} \
284		${DESTDIR}${MANDIR}${__page:E}${MANSUBDIR}/${__page}
285.if defined(MANBUILDCAT) && !empty(MANBUILDCAT)
286	${${__group}INSTALL} ${__page:T:S/$/${CATEXT}${FILTEXTENSION}/g} \
287		${DESTDIR}${CATDIR}${__page:E}${MANSUBDIR}/${__page}
288.endif
289.endfor
290.else	# !defined(MANFILTER)
291	@set ${.ALLSRC:C/\.([^.]*)$/.\1 \1/}; \
292	while : ; do \
293		case $$# in \
294			0) break;; \
295			1) echo "warn: missing extension: $$1"; break;; \
296		esac; \
297		page=$$1; shift; sect=$$1; shift; \
298		d=${DESTDIR}${MANDIR}$${sect}${MANSUBDIR}; \
299		${ECHO} ${${__group}INSTALL} $${page} $${d}; \
300		${${__group}INSTALL} $${page} $${d}; \
301	done
302.if defined(MANBUILDCAT) && !empty(MANBUILDCAT)
303.for __page in ${${__group}}
304	${${__group}INSTALL} ${__page:T:S/$/${CATEXT}/} \
305		${DESTDIR}${CATDIR}${__page:E}${MANSUBDIR}/${__page:T}
306.endfor
307.endif
308.endif	# defined(MANFILTER)
309.else	# ${MK_MANCOMPRESS} == "yes"
310.for __page in ${${__group}}
311	${${__group}INSTALL} ${__page:T:S/$/${MCOMPRESS_EXT}/g} \
312		${DESTDIR}${MANDIR}${__page:E}${MANSUBDIR}/
313.if defined(MANBUILDCAT) && !empty(MANBUILDCAT)
314	${${__group}INSTALL} ${__page:T:S/$/${CATEXT}${MCOMPRESS_EXT}/g} \
315		${DESTDIR}${CATDIR}${__page:E}${MANSUBDIR}/${__page:T:S/$/${MCOMPRESS_EXT}/}
316.endif
317.endfor
318.endif	# ${MK_MANCOMPRESS} == "no"
319.endif
320
321manlinksinstall-${__group}:
322.for l t in ${_MANLINKS}
323# On MacOS, assume case folding FS, and don't install links from foo.x to FOO.x.
324.if ${.MAKE.OS} != "Darwin" || ${l:tu} != ${t:tu}
325	${INSTALL_MANLINK} ${${__group}TAG_ARGS} ${DESTDIR}${l}${ZEXT} ${DESTDIR}${t}${ZEXT}
326.endif
327.endfor
328
329manlint: .PHONY checkmanlinks
330.if defined(${__group}) && !empty(${__group})
331.for __page in ${${__group}}
332manlint: ${__page:S/:/\:/g}lint
333${__page:S/:/\:/g}lint: .PHONY ${MANSRC.${__page:T}:U${__page}}
334.if defined(MANFILTER)
335	${MANFILTER} < ${.ALLSRC} | ${MANDOC_CMD} -Tlint
336.else
337	${MANDOC_CMD} -Tlint ${.ALLSRC}
338.endif
339.endfor
340.endif
341
342checkmanlinks: .PHONY
343.if defined(${__group}LINKS)
344checkmanlinks: checkmanlinks-${__group}
345checkmanlinks-${__group}: .PHONY
346.for __page __link in ${${__group}LINKS}
347checkmanlinks-${__group}: checkmanlinks-${__group}-${__link}
348checkmanlinks-${__group}-${__link}: .PHONY ${__page}
349	@if ! egrep -q "^(\.\\\\\" )?\.Nm ${__link:R}( ,)?$$" ${.ALLSRC}; then \
350		echo "${__group}LINKS: '.Nm ${__link:R}' not found in ${__page}"; \
351		exit 1; \
352	fi >&2
353.endfor # __page __link in ${${__group}LINKS}
354.endif # defined(${__group}LINKS)
355
356.endfor	# __group in ${MANGROUPS}
357