1# - Run doxygen on source files as a custom target
2#
3#  include(DoxygenTargets)
4#  add_doxygen(<doxyfile> [OUTPUT_DIRECTORY <outputdir>]
5#   [EXTRA_INPUT <single path or quoted list of paths>]
6#   [EXTRA_STRIP_FROM_PATH <single path or quoted list of paths>]
7#   [EXTRA_STRIP_FROM_INC_PATH <single path or quoted list of paths>]
8#   [INSTALL_DESTINATION <installdir>
9#   [INSTALL_COMPONENT <installcomponent>]
10#   [INSTALL_PDF_NAME <installpdfname>] ]
11#   [DOC_TARGET <targetname>]
12#   [PROJECT_NUMBER <versionnumber>]
13#   [NO_WARNINGS]
14#   [NO_PDF])
15#
16# Requires these CMake modules:
17#  FindDoxygen
18#
19# Requires CMake 2.6 or newer (uses the 'function' command)
20#
21# Original Author:
22# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
23# http://academic.cleardefinition.com
24# Iowa State University HCI Graduate Program/VRAC
25#
26# Copyright Iowa State University 2009-2010.
27# Distributed under the Boost Software License, Version 1.0.
28# (See accompanying file LICENSE_1_0.txt or copy at
29# http://www.boost.org/LICENSE_1_0.txt)
30
31if(__add_doxygen)
32	return()
33endif()
34set(__add_doxygen YES)
35
36# We must run the following at "include" time, not at function call time,
37# to find the path to this module rather than the path to a calling list file
38get_filename_component(_doxygenmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
39
40if(APPLE)
41	list(APPEND CMAKE_PREFIX_PATH "/usr/texbin")
42endif()
43
44if(NOT DOXYGEN_FOUND)
45	find_package(Doxygen QUIET)
46endif()
47
48set(DOXYGEN_LATEX "NO")
49set(DOXYGEN_PDFLATEX "NO")
50set(DOXYGEN_DOT "NO")
51
52if(DOXYGEN_DOT_EXECUTABLE)
53	set(DOXYGEN_DOT "YES")
54endif()
55
56find_package(LATEX QUIET)
57if(LATEX_COMPILER AND MAKEINDEX_COMPILER)
58	set(DOXYGEN_LATEX "YES")
59endif()
60
61if(PDFLATEX_COMPILER)
62	set(DOXYGEN_PDFLATEX "YES")
63endif()
64
65set(_PF86 "ProgramFiles(x86)")
66find_program(DOXYGEN_MSCGEN_EXECUTABLE
67	mscgen
68	PATHS
69	"$ENV{ProgramFiles}/Mscgen"
70	"$ENV{${_PF86}}/Mscgen"
71	"$ENV{ProgramW6432}/Mscgen")
72if(DOXYGEN_MSCGEN_EXECUTABLE)
73	mark_as_advanced(DOXYGEN_MSCGEN_EXECUTABLE)
74endif()
75
76# An optional single-file install that supports cmake older than 2.8.0
77# For internal use
78function(_dt_install_file target filename dest rename)
79	if(CMAKE_VER VERSION_LESS 2.8.0)
80		set(INSTALL_CODE  "
81			if(EXISTS \"${filename}\")
82				message(STATUS \"Found: ${filename}\")
83				file(INSTALL
84					DESTINATION \"\${CMAKE_INSTALL_PREFIX}/${dest}\"
85					TYPE FILE
86					RENAME \"${rename}\"
87					FILES \"${filename}\")
88			else()
89				message(STATUS \"Skipping (build '${target}' to create): ${filename}\")
90			endif()
91			")
92		if(NOT ARGN STREQUAL "")
93			set(INSTALL_COMPONENT "${ARGN}")
94			set(INSTALL_CODE "
95			if(NOT CMAKE_INSTALL_COMPONENT OR \"\${CMAKE_INSTALL_COMPONENT}\" STREQUAL \"${INSTALL_COMPONENT}\")
96				${INSTALL_CODE}
97			endif()
98			")
99		endif()
100		install(CODE "${INSTALL_CODE}")
101	else()
102		set(COMPONENT_ARGS)
103		if(NOT ARGN STREQUAL "")
104			set(COMPONENT_ARGS COMPONENT "${ARGN}")
105		endif()
106		install(FILES
107			"${filename}"
108			DESTINATION
109			"${dest}"
110			RENAME "${rename}"
111			${COMPONENT_ARGS}
112			OPTIONAL)
113	endif()
114
115endfunction()
116
117# An optional single-directory install that supports cmake older than 2.8.0
118# For internal use
119function(_dt_install_dir target dir dest)
120	if(CMAKE_VER VERSION_LESS 2.8.0)
121		set(INSTALL_CODE  "
122			if(EXISTS \"${dir}\")
123				message(STATUS \"Found: ${dir}\")
124				file(INSTALL
125					DESTINATION \"\${CMAKE_INSTALL_PREFIX}/${dest}\"
126					TYPE DIRECTORY
127					FILES \"${dir}\")
128			else()
129				message(STATUS \"Skipping (build '${target}' to create): ${dir}\")
130			endif()
131			")
132		if(NOT ARGN STREQUAL "")
133			set(INSTALL_COMPONENT "${ARGN}")
134			set(INSTALL_CODE "
135
136			if(NOT CMAKE_INSTALL_COMPONENT OR \"\${CMAKE_INSTALL_COMPONENT}\" STREQUAL \"${INSTALL_COMPONENT}\")
137				${INSTALL_CODE}
138			endif()
139			")
140		endif()
141		install(CODE "${INSTALL_CODE}")
142	else()
143		set(COMPONENT_ARGS)
144		if(NOT ARGN STREQUAL "")
145			set(COMPONENT_ARGS COMPONENT "${ARGN}")
146		endif()
147		install(DIRECTORY
148			"${dir}"
149			DESTINATION
150			"${dest}"
151			${COMPONENT_ARGS}
152			OPTIONAL)
153	endif()
154
155endfunction()
156
157function(add_doxygen _doxyfile)
158	# parse arguments
159	set(WARNINGS YES)
160	set(_nowhere)
161	set(_curdest _nowhere)
162	set(_val_args
163		OUTPUT_DIRECTORY
164		EXTRA_INPUT
165		EXTRA_STRIP_FROM_PATH
166		EXTRA_STRIP_FROM_INC_PATH
167		DOC_TARGET
168		INSTALL_DESTINATION
169		INSTALL_COMPONENT
170		INSTALL_PDF_NAME
171		PROJECT_NUMBER)
172	set(_bool_args
173		NO_WARNINGS
174		NO_PDF)
175	foreach(_arg ${_val_args} ${_bool_args})
176		set(${_arg})
177	endforeach()
178	foreach(_element ${ARGN})
179		list(FIND _val_args "${_element}" _val_arg_find)
180		list(FIND _bool_args "${_element}" _bool_arg_find)
181		if("${_val_arg_find}" GREATER "-1")
182			set(_curdest "${_element}")
183		elseif("${_bool_arg_find}" GREATER "-1")
184			set("${_element}" ON)
185			set(_curdest _nowhere)
186		else()
187			list(APPEND ${_curdest} "${_element}")
188		endif()
189	endforeach()
190
191	if(_nowhere)
192		message(FATAL_ERROR "Syntax error in use of add_doxygen!")
193	endif()
194
195	if(NO_WARNINGS)
196		set(WARNINGS NO)
197	endif()
198
199	if(NOT DOC_TARGET)
200		set(DOC_TARGET doc)
201	endif()
202
203	if(NOT OUTPUT_DIRECTORY)
204		set(OUTPUT_DIRECTORY "docs-generated")
205	endif()
206
207	file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_DIRECTORY}")
208
209	if(NOT INSTALL_PDF_NAME)
210		set(INSTALL_PDF_NAME "docs-generated.pdf")
211	endif()
212
213	if(NOT PROJECT_NUMBER)
214		set(PROJECT_NUMBER "${CPACK_PACKAGE_VERSION}")
215	endif()
216
217	if(DOXYGEN_FOUND)
218		if(TARGET ${DOC_TARGET})
219			message(FATAL_ERROR "Documentation target ${DOC_TARGET} already exists!")
220		endif()
221
222		if(NOT IS_ABSOLUTE "${OUTPUT_DIRECTORY}")
223			get_filename_component(OUTPUT_DIRECTORY
224				"${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_DIRECTORY}"
225				ABSOLUTE)
226		endif()
227
228		set_property(DIRECTORY
229			APPEND
230			PROPERTY
231			ADDITIONAL_MAKE_CLEAN_FILES
232			"${OUTPUT_DIRECTORY}/html"
233			"${OUTPUT_DIRECTORY}/latex")
234
235		if(NOT TARGET ${DOC_TARGET}_open)
236			# Create a target to open the generated HTML file.
237			if(WIN32)
238				set(DOXYGEN_LAUNCHER_COMMAND start)
239			elseif(NOT APPLE)
240				set(DOXYGEN_LAUNCHER_COMMAND xdg-open)
241			endif()
242			if(DOXYGEN_LAUNCHER_COMMAND)
243				add_custom_target(${DOC_TARGET}_open
244					COMMAND ${DOXYGEN_LAUNCHER_COMMAND} "${OUTPUT_DIRECTORY}/html/index.html"
245					VERBATIM)
246				set_target_properties(${DOC_TARGET}_open
247					PROPERTIES
248					EXCLUDE_FROM_ALL
249					TRUE)
250				set_target_properties(${DOC_TARGET}_open
251					PROPERTIES
252					EXCLUDE_FROM_DEFAULT_BUILD
253					TRUE)
254				add_dependencies(${DOC_TARGET}_open ${DOC_TARGET})
255			endif()
256		endif()
257
258		get_filename_component(_doxyfileabs "${_doxyfile}" ABSOLUTE)
259		get_filename_component(INCLUDE_FILE "${_doxyfileabs}" NAME)
260		get_filename_component(INCLUDE_PATH "${_doxyfileabs}" PATH)
261
262		# Doesn't currently work on Windows, so don't bother
263		if(DOXYGEN_LATEX AND NOT NO_PDF AND NOT WIN32)
264			set(MAKE_PDF YES)
265			set(GENERATE_LATEX YES)
266		else()
267			set(MAKE_PDF NO)
268			set(GENERATE_LATEX NO)
269		endif()
270
271		if(DOXYGEN_PDFLATEX AND MAKE_PDF)
272			set(USE_PDFLATEX YES)
273		else()
274			set(USE_PDFLATEX NO)
275		endif()
276
277		if(DOXYGEN_DOT)
278			set(HAVE_DOT YES)
279			set(DOT_PATH ${DOXYGEN_DOT_PATH})
280		else()
281			set(HAVE_DOT NO)
282			set(DOT_PATH)
283		endif()
284
285		if(DOXYGEN_MSCGEN_EXECUTABLE)
286			get_filename_component(MSCGEN_PATH "${DOXYGEN_MSCGEN_EXECUTABLE}" PATH)
287		endif()
288
289		# See http://www.cmake.org/pipermail/cmake/2006-August/010786.html
290		# for info on this variable
291		if("${CMAKE_BUILD_TOOL}" MATCHES "(msdev|devenv)")
292			set(WARN_FORMAT "\"$file($line) : $text \"")
293		else()
294			set(WARN_FORMAT "\"$file:$line: $text \"")
295		endif()
296
297		configure_file("${_doxygenmoddir}/DoxygenTargets.doxyfile.in"
298			"${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.${DOC_TARGET}.additional"
299			@ONLY)
300
301		if(IN_DASHBOARD_SCRIPT)
302			set(ALL_IN_DASHBOARD ALL)
303		else()
304			set(ALL_IN_DASHBOARD)
305		endif()
306
307		add_custom_target(${DOC_TARGET} ${ALL_IN_DASHBOARD}
308			COMMAND
309			"${DOXYGEN_EXECUTABLE}"
310			"${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.${DOC_TARGET}.additional"
311			WORKING_DIRECTORY
312			"${CMAKE_CURRENT_SOURCE_DIR}"
313			#MAIN_DEPENDENCY ${DOC_TARGET}
314			COMMENT
315			"Running Doxygen with configuration ${_doxyfile}..."
316			VERBATIM)
317
318		if(NOT IN_DASHBOARD_SCRIPT)
319			set_target_properties(${DOC_TARGET}
320				PROPERTIES
321				EXCLUDE_FROM_ALL
322				TRUE)
323			set_target_properties(${DOC_TARGET}
324				PROPERTIES
325				EXCLUDE_FROM_DEFAULT_BUILD
326				TRUE)
327		endif()
328		if(MAKE_PDF)
329			add_custom_command(TARGET
330				${DOC_TARGET}
331				POST_BUILD
332				COMMAND
333				${CMAKE_MAKE_PROGRAM}
334				WORKING_DIRECTORY
335				"${OUTPUT_DIRECTORY}/latex"
336				COMMENT
337				"Generating PDF using PDFLaTeX..."
338				VERBATIM)
339		endif()
340
341		if(INSTALL_DESTINATION)
342			if(INSTALL_COMPONENT)
343				_dt_install_dir("${DOC_TARGET}" "${OUTPUT_DIRECTORY}/html" "${INSTALL_DESTINATION}" "${INSTALL_COMPONENT}")
344				if(MAKE_PDF)
345					_dt_install_file("${DOC_TARGET}" "${OUTPUT_DIRECTORY}/latex/refman.pdf" "${INSTALL_DESTINATION}" "${INSTALL_PDF_NAME}" "${INSTALL_COMPONENT}")
346				endif()
347
348			else()
349				_dt_install_dir("${DOC_TARGET}" "${OUTPUT_DIRECTORY}/html" "${INSTALL_DESTINATION}")
350				if(MAKE_PDF)
351					_dt_install_file("${DOC_TARGET}" "${OUTPUT_DIRECTORY}/latex/refman.pdf" "${INSTALL_DESTINATION}" "${INSTALL_PDF_NAME}")
352				endif()
353			endif()
354		endif()
355
356	endif()
357endfunction()
358