xref: /freebsd/share/mk/bsd.man.mk (revision 24e4dcf4ba5e9dedcf89efd358ea3e1fe5867020)
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# Backwards compatibility.
65MINSTALL?=	${MANINSTALL}
66
67CATDIR=		${MANDIR:H:S/$/\/cat/}
68CATEXT=		.cat
69MANDOC_CMD?=	mandoc -Tascii
70
71MCOMPRESS_CMD?=	${COMPRESS_CMD}
72MCOMPRESS_EXT?=	${COMPRESS_EXT}
73
74SECTIONS=	1 2 3 4 5 6 7 8 9
75.SUFFIXES:	${SECTIONS:S/^/./g}
76
77# Backwards compatibility.
78.if !defined(MAN)
79.for __sect in ${SECTIONS}
80MANGROUPS+=	MAN${__sect}
81.endfor
82.endif
83
84# Following the conventions of MANGROUPS, manpage links should be defined
85# as ${group}LINKS, which means the default groups' links would be called
86# MANLINKS.  However it's actually called MLINKS, so for compatibility,
87# use ${MLINKS} as the default group's links if it's set.
88.if defined(MLINKS)
89MANLINKS=	${MLINKS}
90.endif
91
92maninstall: realmaninstall manlinksinstall .PHONY
93# Make sure all manpages are installed before we try to link any.
94.ORDER: realmaninstall manlinksinstall
95realmaninstall: .PHONY
96manlinksinstall: .PHONY
97
98all-man:
99
100.for __group in ${MANGROUPS}
101
102realmaninstall: realmaninstall-${__group}
103manlinksinstall: manlinksinstall-${__group}
104
105${__group}OWN?=		${MANOWN}
106${__group}GRP?=		${MANGRP}
107${__group}MODE?=	${MANMODE}
108${__group}PACKAGE?=	${PACKAGE:Uutilities}
109
110# Tag processing is only done for NO_ROOT installs.
111.if defined(NO_ROOT)
112
113.if !defined(${__group}TAGS) || ! ${${__group}TAGS:Mpackage=*}
114.if ${MK_MANSPLITPKG} == "no" || ${${__group}PACKAGE:M*-man}
115${__group}TAGS+=	package=${${__group}PACKAGE}
116.else
117${__group}TAGS+=	package=${${__group}PACKAGE}-man
118.endif
119.endif
120
121${__group}TAG_ARGS=	-T ${${__group}TAGS:ts,:[*]}
122.endif	# defined(NO_ROOT)
123
124${__group}INSTALL?=	${INSTALL} ${${__group}TAG_ARGS} \
125	-o ${${__group}OWN} -g ${${__group}GRP} -m ${${__group}MODE}
126
127.if ${MK_MANCOMPRESS} == "no"
128
129# Make special arrangements to filter to a temporary file at build time
130# for MK_MANCOMPRESS == no.
131.if defined(MANFILTER)
132FILTEXTENSION=		.filt
133.else
134FILTEXTENSION=
135.endif
136
137ZEXT=
138
139.if defined(MANFILTER)
140.if defined(${__group}) && !empty(${__group})
141CLEANFILES+=	${${__group}:T:S/$/${FILTEXTENSION}/g}
142CLEANFILES+=	${${__group}:T:S/$/${CATEXT}${FILTEXTENSION}/g}
143.for __page in ${${__group}}
144# Escape colons in target names to support manual pages whose
145# filenames contain colons.
146.for __target in ${__page:T:S/:/\:/g:S/$/${FILTEXTENSION}/g}
147all-man: ${__target}
148${__target}: ${MANSRC.${__page:T}:U${__page}}
149	${MANFILTER} < ${.ALLSRC} > ${.TARGET}
150.endfor
151.if defined(MANBUILDCAT) && !empty(MANBUILDCAT)
152.for __target in ${__page:T:S/:/\:/g:S/$/${CATEXT}${FILTEXTENSION}/g}
153all-man: ${__target}
154${__target}: ${MANSRC.${__page:T}:U${__page}}
155	${MANFILTER} < ${.ALLSRC} | ${MANDOC_CMD} > ${.TARGET}
156.endfor
157.endif
158.endfor
159.endif	# !empty(${__group})
160.else	# !defined(MANFILTER)
161.if defined(${__group}) && !empty(${__group})
162CLEANFILES+=	${${__group}:T:S/$/${CATEXT}/g}
163.if defined(MANBUILDCAT) && !empty(MANBUILDCAT)
164.for __page in ${${__group}}
165.for __target in ${__page:T:S/:/\:/g:S/$/${CATEXT}/g}
166all-man: ${__target}
167${__target}: ${MANSRC.${__page:T}:U${__page}}
168	${MANDOC_CMD} ${.ALLSRC} > ${.TARGET}
169.endfor
170.endfor
171.else
172.for __page in ${${__group}}
173.if defined(MANSRC.${__page:T})
174.for __target in ${__page:T:S/:/\:/g}
175all-man: ${__target}
176CLEANFILES+=	${__target}
177${__target}: ${MANSRC.${__page:T}}
178	${CP} ${.ALLSRC} ${.TARGET}
179.endfor
180.else
181all-man: ${__page}
182.endif
183.endfor
184.endif
185.endif
186.endif	# defined(MANFILTER)
187
188.else	# ${MK_MANCOMPRESS} == "yes"
189
190ZEXT=		${MCOMPRESS_EXT}
191
192.if defined(${__group}) && !empty(${__group})
193CLEANFILES+=	${${__group}:T:S/$/${MCOMPRESS_EXT}/g}
194CLEANFILES+=	${${__group}:T:S/$/${CATEXT}${MCOMPRESS_EXT}/g}
195.for __page in ${${__group}}
196.for __target in ${__page:T:S/:/\:/g:S/$/${MCOMPRESS_EXT}/}
197all-man: ${__target}
198${__target}: ${MANSRC.${__page:T}:U${__page}}
199.if defined(MANFILTER)
200	${MANFILTER} < ${.ALLSRC} | ${MCOMPRESS_CMD} > ${.TARGET}
201.else
202	${MCOMPRESS_CMD} ${.ALLSRC} > ${.TARGET}
203.endif
204.endfor
205.if defined(MANBUILDCAT) && !empty(MANBUILDCAT)
206.for __target in ${__page:T:S/:/\:/g:S/$/${CATEXT}${MCOMPRESS_EXT}/}
207all-man: ${__target}
208${__target}: ${MANSRC.${__page:T}:U${__page}}
209.if defined(MANFILTER)
210	${MANFILTER} < ${.ALLSRC} | ${MANDOC_CMD} | ${MCOMPRESS_CMD} > ${.TARGET}
211.else
212	${MANDOC_CMD} ${.ALLSRC} | ${MCOMPRESS_CMD} > ${.TARGET}
213.endif
214.endfor
215.endif
216.endfor
217.endif
218
219.endif	# ${MK_MANCOMPRESS} == "no"
220
221_MANLINKS=
222.if !defined(NO_MLINKS) && defined(${__group}LINKS) && !empty(${__group}LINKS)
223.for _oname _osect _dname _dsect in ${${__group}LINKS:C/\.([^.]*)$/.\1 \1/}
224_MANLINKS+=	${MANDIR}${_osect}${MANSUBDIR}/${_oname} \
225		${MANDIR}${_dsect}${MANSUBDIR}/${_dname}
226.if defined(MANBUILDCAT) && !empty(MANBUILDCAT)
227_MANLINKS+=	${CATDIR}${_osect}${MANSUBDIR}/${_oname} \
228		${CATDIR}${_dsect}${MANSUBDIR}/${_dname}
229.endif
230.endfor
231.endif
232
233.if defined(${__group}) && !empty(${__group})
234.if ${MK_STAGING_MAN} == "yes"
235STAGE_TARGETS+= stage_files.${__group}
236_mansets.${__group}:= ${${__group}:E:O:u:M*[1-9]:@s@man$s@}
237STAGE_SETS+= ${_mansets.${__group}}
238.for _page in ${${__group}}
239stage_files.${__group}.man${_page:T:E}: ${_page}
240.if target(${_page}${MCOMPRESS_EXT})
241stage_files.${__group}.man${_page:T:E}: ${_page}${MCOMPRESS_EXT}
242.endif
243STAGE_DIR.${__group}.man${_page:T:E}?= ${STAGE_OBJTOP}${MANDIR}${_page:T:E}${MANSUBDIR}
244.endfor
245.if !defined(NO_MLINKS) && !empty(${__group}LINKS)
246STAGE_SETS+= mlinks.${__group}
247STAGE_TARGETS+= stage_links.${__group}
248STAGE_LINKS.mlinks.${__group}:= ${${__group}LINKS:M*.[1-9]:@f@${f:S,^,${MANDIR}${f:E}${MANSUBDIR}/,}@}
249stage_links.mlinks.${__group}: ${_mansets.${__group}:@s@stage_files.${__group}.$s@}
250.endif
251.endif
252.endif
253
254realmaninstall-${__group}:
255.if defined(${__group}) && !empty(${__group})
256.for __page in ${${__group}}
257__mansrc.${__group}+=	${MANSRC.${__page:T}:U${__page}}
258.endfor
259realmaninstall-${__group}: ${__mansrc.${__group}}
260.if ${MK_MANCOMPRESS} == "no"
261.if defined(MANFILTER)
262.for __page in ${${__group}}
263	${${__group}INSTALL} ${__page:T:S/$/${FILTEXTENSION}/g} \
264		${DESTDIR}${MANDIR}${__page:E}${MANSUBDIR}/${__page}
265.if defined(MANBUILDCAT) && !empty(MANBUILDCAT)
266	${${__group}INSTALL} ${__page:T:S/$/${CATEXT}${FILTEXTENSION}/g} \
267		${DESTDIR}${CATDIR}${__page:E}${MANSUBDIR}/${__page}
268.endif
269.endfor
270.else	# !defined(MANFILTER)
271	@set ${.ALLSRC:C/\.([^.]*)$/.\1 \1/}; \
272	while : ; do \
273		case $$# in \
274			0) break;; \
275			1) echo "warn: missing extension: $$1"; break;; \
276		esac; \
277		page=$$1; shift; sect=$$1; shift; \
278		d=${DESTDIR}${MANDIR}$${sect}${MANSUBDIR}; \
279		${ECHO} ${${__group}INSTALL} $${page} $${d}; \
280		${${__group}INSTALL} $${page} $${d}; \
281	done
282.if defined(MANBUILDCAT) && !empty(MANBUILDCAT)
283.for __page in ${${__group}}
284	${${__group}INSTALL} ${__page:T:S/$/${CATEXT}/} \
285		${DESTDIR}${CATDIR}${__page:E}${MANSUBDIR}/${__page:T}
286.endfor
287.endif
288.endif	# defined(MANFILTER)
289.else	# ${MK_MANCOMPRESS} == "yes"
290.for __page in ${${__group}}
291	${${__group}INSTALL} ${__page:T:S/$/${MCOMPRESS_EXT}/g} \
292		${DESTDIR}${MANDIR}${__page:E}${MANSUBDIR}/
293.if defined(MANBUILDCAT) && !empty(MANBUILDCAT)
294	${${__group}INSTALL} ${__page:T:S/$/${CATEXT}${MCOMPRESS_EXT}/g} \
295		${DESTDIR}${CATDIR}${__page:E}${MANSUBDIR}/${__page:T:S/$/${MCOMPRESS_EXT}/}
296.endif
297.endfor
298.endif	# ${MK_MANCOMPRESS} == "no"
299.endif
300
301manlinksinstall-${__group}:
302.for l t in ${_MANLINKS}
303# On MacOS, assume case folding FS, and don't install links from foo.x to FOO.x.
304.if ${.MAKE.OS} != "Darwin" || ${l:tu} != ${t:tu}
305	${INSTALL_MANLINK} ${${__group}TAG_ARGS} ${DESTDIR}${l}${ZEXT} ${DESTDIR}${t}${ZEXT}
306.endif
307.endfor
308
309manlint: .PHONY checkmanlinks
310.if defined(${__group}) && !empty(${__group})
311.for __page in ${${__group}}
312manlint: ${__page:S/:/\:/g}lint
313${__page:S/:/\:/g}lint: .PHONY ${MANSRC.${__page:T}:U${__page}}
314.if defined(MANFILTER)
315	${MANFILTER} < ${.ALLSRC} | ${MANDOC_CMD} -Tlint
316.else
317	${MANDOC_CMD} -Tlint ${.ALLSRC}
318.endif
319.endfor
320.endif
321
322checkmanlinks: .PHONY
323.if defined(${__group}LINKS)
324checkmanlinks: checkmanlinks-${__group}
325checkmanlinks-${__group}: .PHONY
326.for __page __link in ${${__group}LINKS}
327checkmanlinks-${__group}: checkmanlinks-${__group}-${__link}
328checkmanlinks-${__group}-${__link}: .PHONY ${__page}
329	@if ! egrep -q "^(\.\\\\\" )?\.Nm ${__link:R}( ,)?$$" ${.ALLSRC}; then \
330		echo "${__group}LINKS: '.Nm ${__link:R}' not found in ${__page}"; \
331		exit 1; \
332	fi >&2
333.endfor # __page __link in ${${__group}LINKS}
334.endif # defined(${__group}LINKS)
335
336.endfor	# __group in ${MANGROUPS}
337