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