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