handle_manual.cmake revision 0bbfda8a
1#
2# Handle stuff related to building the manual in various ways
3#
4
5
6# Lookup the asciidoc[tor] bits
7include(find_asciidoc_bits)
8
9
10
11#
12# Setup some vars for the various steps in the process
13#
14
15# The original source.
16set(ADOC_SRC ${MANSRCDIR}/ctwm.1.adoc)
17
18# Where we build stuff.  Because we need to process the ADOC_SRC to
19# replace build paths etc, we need to dump it somewhere.  We could just
20# leave it right in the build dir root, but is cleaner.
21set(MAN_TMPDIR ${CMAKE_BINARY_DIR}/mantmp)
22
23# Where we copy the source to during rewrites, and then do the actual
24# build from.
25set(ADOC_TMPSRC ${MAN_TMPDIR}/ctwm.1.adoc)
26
27# Where the end products wind up
28set(MANPAGE ${CMAKE_BINARY_DIR}/ctwm.1)
29set(MANHTML ${CMAKE_BINARY_DIR}/ctwm.1.html)
30set(MANDBXML ${CMAKE_BINARY_DIR}/ctwm.1.xml)
31set(MANPDF   ${CMAKE_BINARY_DIR}/ctwm.1.pdf)
32
33# How we rewrite vars in the manual.  I decided not to use
34# configure_file() for this, as it opens up too many chances for
35# something to accidentally get sub'd, since we assume people will write
36# pretty freeform in the manual.
37# \-escaped @ needed for pre-3.1 CMake compat and warning avoidance;
38# x-ref `cmake --help-policy CMP0053`
39set(MANSED_CMD sed -e \"s,\@ETCDIR@,${ETCDIR},\"
40	-e \"s,\@ctwm_version_str@,`head -1 ${CMAKE_SOURCE_DIR}/VERSION`,\")
41
42# Pregen'd doc file paths we might have, in case we can't build them
43# ourselves.
44set(MAN_PRESRC ${GENSRCDIR}/ctwm.1)
45set(HTML_PRESRC ${GENSRCDIR}/ctwm.1.html)
46
47
48
49
50
51# Figure what we can build
52#
53# These are both boolean "We can build this type of output" flags, and
54# enums for later code for "What method we use to build this type of
55# output".
56
57# We use the DocBook XML output for PDF (if manually requested), and
58# _can_ use it in very special cases for manpages.  So find out first if
59# we can even build it.
60set(MANUAL_BUILD_DBXML)
61if(ASCIIDOCTOR AND ASCIIDOCTOR_CAN_DBXML)
62	set(MANUAL_BUILD_DBXML asciidoctor)
63elseif(ASCIIDOC AND ASCIIDOC_CAN_DBXML)
64	set(MANUAL_BUILD_DBXML asciidoc)
65endif()
66
67# If we have asciidoctor, use it to build the HTML.  Else, we could use
68# asciidoc, but leave it disabled because it's very slow.
69set(MANUAL_BUILD_HTML)
70if(ASCIIDOCTOR AND ASCIIDOCTOR_CAN_HTML)
71	set(MANUAL_BUILD_HTML asciidoctor)
72elseif(ASCIIDOC)
73	set(MANUAL_BUILD_HTML asciidoc)
74	if(NOT ENABLE_ASCIIDOC_HTML)
75		set(NOAUTO_HTML 1)
76		message(STATUS "Not enabling HTML manual build; asciidoc is slow.")
77	endif()
78endif()
79
80# For the manpage output, asciidoctor has to be of a certain version.  If
81# it's not there or not high enough version, we fall back to asciidoc/a2x
82# (which is very slow at this too, but we need to build a manpage, so eat
83# the expense).  And it's possible to go via the DocBook XML output, but
84# it takes very odd cases to wind up there.
85set(MANUAL_BUILD_MANPAGE)
86if(ASCIIDOCTOR AND ASCIIDOCTOR_CAN_MAN)
87	set(MANUAL_BUILD_MANPAGE asciidoctor)
88elseif(A2X AND ASCIIDOC_CAN_MAN)
89	set(MANUAL_BUILD_MANPAGE a2x)
90elseif(XMLTO AND XMLTO_CAN_STUFF AND MANUAL_BUILD_DBXML)
91	# Should probably never happen in reality
92	set(MANUAL_BUILD_MANPAGE xmlto)
93endif()
94
95# PDF output is not hooked into the build process by default, but is made
96# available by an extra target.
97set(MANUAL_BUILD_PDF)
98if(DBLATEX AND DBLATEX_CAN_PDF AND MANUAL_BUILD_DBXML)
99	set(MANUAL_BUILD_PDF dblatex)
100endif()
101
102
103# Override: allow forcing use of pregen'd files.
104if(FORCE_PREGEN_FILES)
105	set(MANUAL_BUILD_HTML)
106	set(MANUAL_BUILD_MANPAGE)
107	set(MANUAL_BUILD_DBXML)
108endif()
109
110
111# If we can build stuff, prepare bits for it.  Technically unnecessary if
112# we're not building stuff, but doesn't do anything bad to define it in
113# those cases, and it's easier than listing every MANUAL_BUILD_* in the
114# conditions.
115set(SETUP_MAN_REWRITE 1)
116if(SETUP_MAN_REWRITE)
117	# Setup a temp dir under the build for our processing
118	file(MAKE_DIRECTORY ${MAN_TMPDIR})
119
120	# We hop through a temporary file to process in definitions for e.g.
121	# $ETCDIR.
122	add_custom_command(OUTPUT ${ADOC_TMPSRC}
123		DEPENDS ${ADOC_SRC} ${CMAKE_SOURCE_DIR}/VERSION
124		COMMAND ${MANSED_CMD} < ${ADOC_SRC} > ${ADOC_TMPSRC}
125		COMMENT "Processing ctwm.1.adoc -> mantmp/ctwm.1.adoc"
126	)
127
128	# We can't actually make other targets depend just on that generated
129	# source file, because cmake will try to multi-build it in parallel.
130	# To work around, we add a do-nothing custom target that depends on
131	# $ADOC_TMPSRC, that uses of it depend on.
132	#
133	# x-ref http://public.kitware.com/Bug/view.php?id=12311
134	#
135	# Note, however, that this _doesn't_ transmit the dependancy on
136	# ${ADOC_TMPDIR} through; it serves only to serialize the build so it
137	# doesn't try to happen twice at once.  So we still need to include
138	# ${ADOC_TMPSRC} in the DEPENDS for the targets building off it, or
139	# they don't notice when they go out of date.
140	add_custom_target(mk_adoc_tmpsrc DEPENDS ${ADOC_TMPSRC})
141endif(SETUP_MAN_REWRITE)
142
143
144
145
146#
147# Building the manpage variant
148#
149set(HAS_MAN 0)
150if(MANUAL_BUILD_MANPAGE)
151	# Got the tool to build it
152	message(STATUS "Building manpage with ${MANUAL_BUILD_MANPAGE}.")
153	set(HAS_MAN 1)
154
155	if(${MANUAL_BUILD_MANPAGE} STREQUAL "asciidoctor")
156		# We don't need the hoops for a2x here, since asciidoctor lets us
157		# specify the output directly.
158		asciidoctor_mk_manpage(${MANPAGE} ${ADOC_TMPSRC} DEPENDS mk_adoc_tmpsrc)
159	elseif(${MANUAL_BUILD_MANPAGE} STREQUAL "a2x")
160		# a2x has to jump through some stupid hoops
161		a2x_mk_manpage(${MANPAGE} ${ADOC_TMPSRC} DEPENDS mk_adoc_tmpsrc)
162	elseif(${MANUAL_BUILD_MANPAGE} STREQUAL "xmlto")
163		# xmlto does its own hoops too
164		xmlto_mk_manpage(${MANPAGE} ${MANDBXML})
165	else()
166		message(FATAL_ERROR "I don't know what to do with that manpage "
167			"building type!")
168	endif()
169elseif(EXISTS ${MAN_PRESRC})
170	# Can't build it ourselves, but we've got a prebuilt version.
171	message(STATUS "Can't build manpage, using prebuilt version.")
172	set(HAS_MAN 1)
173
174	# We still have to do the substitutions like above, but we're doing
175	# it on the built version now, rather than the source.
176	add_custom_command(OUTPUT ${MANPAGE}
177		DEPENDS ${MAN_PRESRC} ${CMAKE_SOURCE_DIR}/VERSION
178		COMMAND ${MANSED_CMD} < ${MAN_PRESRC} > ${MANPAGE}
179		COMMENT "Processing prebuilt manpage -> ctwm.1"
180	)
181else()
182	# Can't build it, no prebuilt.  Not quite fatal, but very bad.
183	message(WARNING "Can't build manpage, and no prebuilt version "
184		"available.  You won't get one.")
185endif(MANUAL_BUILD_MANPAGE)
186
187
188# Assuming we have it, compress manpage (conditionally).  We could add
189# more magic to allow different automatic compression, but that's
190# probably way more involved than we need to bother with.  Most systems
191# use gzip, and for the few that don't, the packagers can use
192# NOMANCOMPRESS and handle it out of band.
193if(HAS_MAN)
194	if(NOT NOMANCOMPRESS)
195		find_program(GZIP_CMD gzip)
196		add_custom_command(OUTPUT "${MANPAGE}.gz"
197			DEPENDS ${MANPAGE}
198			COMMAND ${GZIP_CMD} -nc ${MANPAGE} > ${MANPAGE}.gz
199			COMMENT "Compressing ctwm.1.gz"
200		)
201		add_custom_target(man ALL DEPENDS "${MANPAGE}.gz")
202		set(INSTMAN "${MANPAGE}.gz")
203	else()
204		add_custom_target(man ALL DEPENDS ${MANPAGE})
205		set(INSTMAN ${MANPAGE})
206	endif(NOT NOMANCOMPRESS)
207endif(HAS_MAN)
208
209
210
211
212#
213# Do the HTML manual
214#
215set(HAS_HTML 0)
216if(MANUAL_BUILD_HTML AND NOAUTO_HTML)
217	message(STATUS "Not autobuilding HTML manual with ${MANUAL_BUILD_HTML}.")
218endif()
219# Separate if() rather than an elseif() so that the above case can still
220# fall into the elseif(EXISTS ${HTML_PRESRC}) below and use the pregen'd
221# version.
222if(MANUAL_BUILD_HTML AND NOT NOAUTO_HTML)
223	# Got the tool to build it
224	message(STATUS "Building HTML manual with ${MANUAL_BUILD_HTML}.")
225	set(HAS_HTML 1)
226
227	if(${MANUAL_BUILD_HTML} STREQUAL "asciidoctor")
228		asciidoctor_mk_html(${MANHTML} ${ADOC_TMPSRC} DEPENDS mk_adoc_tmpsrc)
229	elseif(${MANUAL_BUILD_HTML} STREQUAL "asciidoc")
230		asciidoc_mk_html(${MANHTML} ${ADOC_TMPSRC} DEPENDS mk_adoc_tmpsrc)
231	else()
232		message(FATAL_ERROR "I don't know what to do with that HTML manual "
233			"building type!")
234	endif()
235elseif(EXISTS ${HTML_PRESRC})
236	# Can't build it ourselves, but we've got a prebuilt version.
237	message(STATUS "Can't build HTML manual, using prebuilt version.")
238	set(HAS_HTML 1)
239	set(NOAUTO_HTML) # Clear so ALL target get set below
240
241	# As with the manpage above, we need to do the processing on the
242	# generated version for build options.
243	add_custom_command(OUTPUT ${MANHTML}
244		DEPENDS ${HTML_PRESRC} ${CMAKE_SOURCE_DIR}/VERSION
245		COMMAND ${MANSED_CMD} < ${HTML_PRESRC} > ${MANHTML}
246		COMMENT "Processing prebuilt manual -> ctwm.1.html"
247	)
248
249else()
250	# Can't build it, no prebuilt.
251	# Left as STATUS, since this is "normal" for now.
252	message(STATUS "Can't build HTML manual, and no prebuilt version "
253		"available.")
254endif()  # Variants of building HTML manual
255
256
257# If we have (or are building) the HTML, add an easy target for it, and
258# define a var for the install process to notice.
259if(HAS_HTML)
260	if(NOAUTO_HTML)
261		add_custom_target(man-html DEPENDS ${MANHTML})
262	else()
263		add_custom_target(man-html ALL DEPENDS ${MANHTML})
264		set(INSTHTML ${MANHTML})
265	endif(NOAUTO_HTML)
266endif(HAS_HTML)
267
268
269
270
271#
272# Building DocBook XML
273#
274set(HAS_DBXML 0)
275if(MANUAL_BUILD_DBXML)
276	# Got the tool to build it
277	#message(STATUS "Building DocBook XML with ${MANUAL_BUILD_DBXML}.")
278	set(HAS_DBXML 1)
279
280	if(${MANUAL_BUILD_DBXML} STREQUAL "asciidoctor")
281		# We don't need the hoops for a2x here, since asciidoctor lets us
282		# specify the output directly.
283		asciidoctor_mk_docbook(${MANDBXML} ${ADOC_TMPSRC} DEPENDS mk_adoc_tmpsrc)
284	elseif(${MANUAL_BUILD_DBXML} STREQUAL "asciidoc")
285		# a2x has to jump through some stupid hoops
286		asciidoc_mk_docbook(${MANDBXML} ${ADOC_TMPSRC} DEPENDS mk_adoc_tmpsrc)
287	else()
288		message(FATAL_ERROR "I don't know what to do with that DocBook "
289			"building type!")
290	endif()
291endif(MANUAL_BUILD_DBXML)
292
293
294
295
296#
297# And the PDF output
298#
299set(HAS_PDF 0)
300if(MANUAL_BUILD_PDF)
301	# Got the tool to build it
302	#message(STATUS "Building PDF with ${MANUAL_BUILD_PDF}.")
303	set(HAS_PDF 1)
304
305	if(${MANUAL_BUILD_PDF} STREQUAL "dblatex")
306		dblatex_mk_pdf(${MANPDF} ${MANDBXML})
307	else()
308		message(FATAL_ERROR "I don't know what to do with that PDF "
309			"building type!")
310	endif()
311endif(MANUAL_BUILD_PDF)
312
313if(HAS_PDF)
314	add_custom_target(man-pdf DEPENDS ${MANPDF})
315endif(HAS_PDF)
316
317
318
319
320#
321# Handy target
322#
323set(MAN_TYPES)
324if(HAS_MAN)
325	list(APPEND MAN_TYPES man)
326endif()
327if(HAS_HTML)
328	list(APPEND MAN_TYPES man-html)
329endif()
330if(HAS_PDF)
331	list(APPEND MAN_TYPES man-pdf)
332endif()
333add_custom_target(man-all DEPENDS ${MAN_TYPES})
334