cleanup: move 'cmake' to a subdir buildsystems
[gtk-doc.git] / buildsystems / cmake / GtkDocConfig.cmake.in
blob9d41696bd94daa801c44ea281e2ffd746e596529
1 # CMake macros to use the GtkDoc documentation system
3 # See the GTK-Doc manual (help/manual/C/index.docbook) for an example of how to
4 # use this.
6 # Output variables:
8 #   GTKDOC_FOUND            ... set to 1
10 #   GTKDOC_SCAN_EXE         ... the location of the gtkdoc-scan executable
11 #   GTKDOC_SCANGOBJ_EXE     ... the location of the gtkdoc-scangobj executable
12 #   GTKDOC_MKDB_EXE         ... the location of the gtkdoc-mkdb executable
13 #   GTKDOC_MKHTML_EXE       ... the location of the gtkdoc-mkhtml executable
14 #   GTKDOC_FIXXREF_EXE      ... the location of the gtkdoc-fixxref executable
17 #=============================================================================
18 # Copyright 2009 Rich Wareham
19 # Copyright 2015 Lautsprecher Teufel GmbH
21 # This program is free software; you can redistribute it and/or modify
22 # it under the terms of the GNU General Public License as published by
23 # the Free Software Foundation; either version 2 of the License, or
24 # (at your option) any later version.
26 # This program is distributed in the hope that it will be useful,
27 # but WITHOUT ANY WARRANTY; without even the implied warranty of
28 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29 # GNU General Public License for more details.
31 # You should have received a copy of the GNU General Public License
32 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
33 #=============================================================================
35 include(CMakeParseArguments)
37 set(GTKDOC_FOUND 1)
39 set(GTKDOC_SCAN_EXE @bindir@/gtkdoc-scan)
40 set(GTKDOC_SCANGOBJ_EXE @bindir@/gtkdoc-scangobj)
41 set(GTKDOC_MKDB_EXE @bindir@/gtkdoc-mkdb)
42 set(GTKDOC_MKHTML_EXE @bindir@/gtkdoc-mkhtml)
43 set(GTKDOC_FIXXREF_EXE @bindir@/gtkdoc-fixxref)
45 get_filename_component(_this_dir ${CMAKE_CURRENT_LIST_FILE} PATH)
46 find_file(GTKDOC_SCANGOBJ_WRAPPER GtkDocScanGObjWrapper.cmake PATH ${_this_dir})
48 # ::
50 # gtk_doc_add_module(doc_prefix
51 #                    SOURCE <sourcedir> [...]
52 #                    XML xmlfile
53 #                    [LIBRARIES depend1...]
54 #                    [FIXXREFOPTS fixxrefoption1...]
55 #                    [IGNOREHEADERS header1...])
57 # Add a module with documentation to be processed with GTK-Doc.
59 # <sourcedir> must be the *full* path to the source directory.
61 # If omitted, xmlfile defaults to the auto generated ${doc_prefix}/${doc_prefix}-docs.xml.
63 # The `gtkdoc-scangobj` program is used to get introspection information for
64 # the module. You should pass the target(s) to be scanned as LIRARIES. This
65 # will try to set the correct compiler and link flags for the introspection
66 # build to use, and the correct LD_LIBRARY_PATH for it to run, and the correct
67 # dependencies for the doc target.
69 # You *can* also set the compile and link flags manually, using the 'CFLAGS'
70 # and 'LDFLAGS' options. The 'LDPATH' option controls the LD_LIBRARY_PATH. You
71 # can also manually add additional targets as dependencies of the
72 # documentation build with the DEPENDS option.
74 # This function a target named "doc-${doc_prefix}". You will need to manually
75 # add it to the ALL target if you want it to be built by default, you can do
76 # something like this:
78 #   gtk_doc_add_module(doc-mymodule
79 #                      SOURCE ${CMAKE_SOURCE_DIR}/module ${CMAKE_BINARY_DIR}/module
80 #                      LIBRARIES mylibrary
81 #                      LIBRARY_DIRS ${GLIB_LIBRARY_DIRS} ${FOO_LIBRARY_DIRS}
82 #   add_custom_target(all-documentation ALL)
83 #   add_dependencies(all-documentation doc-mymodule)
85 function(gtk_doc_add_module _doc_prefix)
86     set(_one_value_args "XML")
87     set(_multi_value_args "FIXXREFOPTS" "IGNOREHEADERS" "LIBRARIES" "LIBRARY_DIRS" "SOURCE" "SUFFIXES"
88                           "CFLAGS" "DEPENDS" "LDFLAGS" "LDPATH")
89     cmake_parse_arguments("GTK_DOC" "" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
91     if(NOT GTK_DOC_SOURCE)
92         message(FATAL_ERROR "No SOURCE specified for gtk_doc_add_module ${_doc_prefix}")
93     endif()
95     set(_xml_file ${GTK_DOC_XML})
97     set(_fixxrefopts ${GTK_DOC_FIXXREFOPTS})
98     set(_ignore_headers ${GTK_DOC_IGNOREHEADERS})
99     set(_libraries ${GTK_DOC_LIBRARIES})
100     set(_library_dirs ${GTK_DOC_LIBRARY_DIRS})
101     set(_suffixes ${GTK_DOC_SUFFIXES})
103     set(_extra_cflags ${GTK_DOC_CFLAGS})
104     set(_depends ${GTK_DOC_DEPENDS})
105     set(_extra_ldflags ${GTK_DOC_LDFLAGS})
106     set(_extra_ldpath ${GTK_DOC_LDPATH})
108     if(_suffixes)
109         set(_doc_source_suffixes "")
110         foreach(_suffix ${_suffixes})
111             if(_doc_source_suffixes)
112                 set(_doc_source_suffixes "${_doc_source_suffixes},${_suffix}")
113             else(_doc_source_suffixes)
114                 set(_doc_source_suffixes "${_suffix}")
115             endif(_doc_source_suffixes)
116         endforeach(_suffix)
117     else(_suffixes)
118         set(_doc_source_suffixes "h")
119     endif(_suffixes)
121     # Parse the LIBRARIES option and collect compile and link flags for those
122     # targets.
123     foreach(target ${_libraries})
124         _gtk_doc_get_cflags_for_target(_target_cflags ${target})
125         _gtk_doc_get_ldflags_for_target(_target_ldflags ${target} "${_libraries}")
126         list(APPEND _extra_cflags ${_target_cflags})
127         list(APPEND _extra_ldflags ${_target_ldflags})
128         list(APPEND _extra_ldpath $<TARGET_FILE_DIR:${target}>)
130         list(APPEND _depends ${target})
131     endforeach()
133     # Link directories can't be specified per target, only for every target
134     # under a given directory.
135     get_property(all_library_directories DIRECTORY PROPERTY LINK_DIRECTORIES)
136     foreach(library_dir ${all_library_directories})
137         list(APPEND _extra_ldflags ${CMAKE_LIBRARY_PATH_FLAG}${library_dir})
138         list(APPEND _extra_ldpath ${library_dir})
139     endforeach()
141     # a directory to store output.
142     set(_output_dir "${CMAKE_CURRENT_BINARY_DIR}/${_doc_prefix}")
143     set(_output_dir_stamp "${_output_dir}/dir.stamp")
145     # set default sgml file if not specified
146     set(_default_xml_file "${_output_dir}/${_doc_prefix}-docs.xml")
147     get_filename_component(_default_xml_file ${_default_xml_file} ABSOLUTE)
149     # a directory to store html output.
150     set(_output_html_dir "${_output_dir}/html")
151     set(_output_html_dir_stamp "${_output_dir}/html_dir.stamp")
153     # The output files
154     set(_output_decl_list "${_output_dir}/${_doc_prefix}-decl-list.txt")
155     set(_output_decl "${_output_dir}/${_doc_prefix}-decl.txt")
156     set(_output_overrides "${_output_dir}/${_doc_prefix}-overrides.txt")
157     set(_output_sections "${_output_dir}/${_doc_prefix}-sections.txt")
158     set(_output_types "${_output_dir}/${_doc_prefix}.types")
160     set(_output_signals "${_output_dir}/${_doc_prefix}.signals")
162     set(_output_unused "${_output_dir}/${_doc_prefix}-unused.txt")
163     set(_output_undeclared "${_output_dir}/${_doc_prefix}-undeclared.txt")
164     set(_output_undocumented "${_output_dir}/${_doc_prefix}-undocumented.txt")
166     set(_output_xml_dir "${_output_dir}/xml")
167     set(_output_sgml_stamp "${_output_dir}/sgml.stamp")
169     set(_output_html_stamp "${_output_dir}/html.stamp")
171     # add a command to create output directory
172     add_custom_command(
173         OUTPUT "${_output_dir_stamp}" "${_output_dir}"
174         COMMAND ${CMAKE_COMMAND} -E make_directory "${_output_dir}"
175         COMMAND ${CMAKE_COMMAND} -E touch ${_output_dir_stamp}
176         VERBATIM)
178     set(_ignore_headers_opt "")
179     if(_ignore_headers)
180         set(_ignore_headers_opt "--ignore-headers=")
181         foreach(_header ${_ignore_headers})
182             set(_ignore_headers_opt "${_ignore_headers_opt}${_header} ")
183         endforeach(_header ${_ignore_headers})
184     endif(_ignore_headers)
186     foreach(source_dir ${GTK_DOC_SOURCE})
187         set(_source_dirs_opt ${_source_dirs_opt} --source-dir=${source_dir})
188     endforeach()
190     # add a command to scan the input
191     add_custom_command(
192         OUTPUT
193             "${_output_decl_list}"
194             "${_output_decl}"
195             "${_output_overrides}"
196             "${_output_sections}"
197             "${_output_types}"
198         DEPENDS
199             "${_output_dir_stamp}"
200             ${_depends}
201         COMMAND
202             ${GTKDOC_SCAN_EXE}
203             --module=${_doc_prefix}
204             ${_ignore_headers_opt}
205             ${_source_dirs_opt}
206             --rebuild-sections
207             --rebuild-types
208         WORKING_DIRECTORY ${_output_dir}
209         VERBATIM)
211     # add a command to scan the input via gtkdoc-scangobj
212     # This is such a disgusting hack!
213     add_custom_command(
214         OUTPUT
215             ${_output_signals}
216         DEPENDS
217             ${_output_types}
218         COMMAND ${CMAKE_COMMAND}
219             -D "GTKDOC_SCANGOBJ_EXE:STRING=${GTKDOC_SCANGOBJ_EXE}"
220             -D "doc_prefix:STRING=${_doc_prefix}"
221             -D "output_types:STRING=${_output_types}"
222             -D "output_dir:STRING=${_output_dir}"
223             -D "EXTRA_CFLAGS:STRING=${_extra_cflags}"
224             -D "EXTRA_LDFLAGS:STRING=${_extra_ldflags}"
225             -D "EXTRA_LDPATH:STRING=${_extra_ldpath}"
226             -P ${GTKDOC_SCANGOBJ_WRAPPER}
227         WORKING_DIRECTORY "${_output_dir}"
228         VERBATIM)
230     set(_copy_xml_if_needed "")
231     if(_xml_file)
232         get_filename_component(_xml_file ${_xml_file} ABSOLUTE)
233         set(_copy_xml_if_needed
234             COMMAND ${CMAKE_COMMAND} -E copy "${_xml_file}" "${_default_xml_file}")
235     endif(_xml_file)
237     set(_remove_xml_if_needed "")
238     if(_xml_file)
239         set(_remove_xml_if_needed
240             COMMAND ${CMAKE_COMMAND} -E remove ${_default_xml_file})
241     endif(_xml_file)
243     # add a command to make the database
244     add_custom_command(
245         OUTPUT
246             ${_output_sgml_stamp}
247             ${_default_xml_file}
248         DEPENDS
249             ${_output_types}
250             ${_output_signals}
251             ${_output_sections}
252             ${_output_overrides}
253             ${_depends}
254         ${_remove_xml_if_needed}
255         COMMAND ${CMAKE_COMMAND} -E remove_directory ${_output_xml_dir}
256         COMMAND ${GTKDOC_MKDB_EXE}
257             --module=${_doc_prefix}
258             ${_source_dirs_opt}
259             --source-suffixes=${_doc_source_suffixes}
260             --output-format=xml
261             --main-sgml-file=${_default_xml_file}
262         ${_copy_xml_if_needed}
263         WORKING_DIRECTORY "${_output_dir}"
264         VERBATIM)
266     # add a command to create html directory
267     add_custom_command(
268         OUTPUT "${_output_html_dir_stamp}" "${_output_html_dir}"
269         COMMAND ${CMAKE_COMMAND} -E make_directory ${_output_html_dir}
270         COMMAND ${CMAKE_COMMAND} -E touch ${_output_html_dir_stamp}
271         VERBATIM)
273     # add a command to output HTML
274     add_custom_command(
275         OUTPUT
276             ${_output_html_stamp}
277         DEPENDS
278             ${_output_html_dir_stamp}
279             ${_output_sgml_stamp}
280             ${_xml_file}
281             ${_depends}
282         ${_copy_xml_if_needed}
283         # The binary dir needs adding to --path in order for mkhtml to pick up
284         # any version.xml file there might be in there
285         COMMAND
286             cd ${_output_html_dir} && ${GTKDOC_MKHTML_EXE}
287                 ${_doc_prefix}
288                 ${_default_xml_file}
289         COMMAND
290             cd ${_output_dir} && ${GTKDOC_FIXXREF_EXE}
291                 --module=${_doc_prefix}
292                 --module-dir=${_output_html_dir}
293                 ${_fixxref_opts}
294         COMMENT
295             "Generating HTML documentation for ${_doc_prefix} module with gtkdoc-mkhtml"
296         VERBATIM)
298     add_custom_target(doc-${_doc_prefix}
299         DEPENDS "${_output_html_stamp}")
300 endfunction(gtk_doc_add_module)
302 # These two functions reimplement some of the core logic of CMake, in order
303 # to generate compiler and linker flags from the relevant target properties.
304 # It sucks that we have to do this, but CMake's own code for this doesn't seem
305 # to be reusable -- there's no way to say "tell me the flags that you would
306 # pass to a linker for this target".
308 function(_gtk_doc_get_cflags_for_target result_var target)
309     get_target_property(target_definitions ${target} COMPILE_DEFINITIONS)
310     if(target_definitions)
311         list(APPEND cflags ${target_definitions})
312     endif()
314     get_target_property(target_options ${target} COMPILE_OPTIONS)
315     if(target_options)
316         list(APPEND cflags ${target_options})
317     endif()
319     get_target_property(target_include_dirs ${target} INCLUDE_DIRECTORIES)
320     foreach(target_include_dir ${target_include_dirs})
321         list(APPEND cflags -I${target_include_dir})
322     endforeach()
324     list(REMOVE_DUPLICATES cflags)
325     list(SORT cflags)
327     set(${result_var} ${cflags} PARENT_SCOPE)
328 endfunction()
330 function(_gtk_doc_get_ldflags_for_target result_var target all_targets)
331     get_target_property(target_link_flags ${target} LINK_FLAGS)
332     if(target_link_flags)
333         list(APPEND ldflags ${target_link_flags})
334     endif()
336     get_target_property(target_link_libraries ${target} LINK_LIBRARIES)
337     foreach(target_library ${target_link_libraries})
338         # The IN_LIST operator is new in CMake 3.3, so I've tried to avoid using it.
339         list(FIND all_targets ${target_library} target_library_is_explicit_dependency)
340         if(NOT ${target_library_is_explicit_dependency} EQUAL -1)
341             # This target is part of the current project. We will add it to
342             # LDFLAGS explicitly, so don't try to add it with -l<target> as
343             # well. In fact, we can't do that, as the containing directory
344             # probably won't be in the linker search path, and we can't find
345             # that out and add it ourselves.
346         elseif(EXISTS ${target_library})
347             # Pass the filename directly to the linker.
348             list(APPEND ldflags "${target_library}")
349         else()
350             # Pass -l<filename> to the linker.
351             list(APPEND ldflags "${CMAKE_LINK_LIBRARY_FLAG}${target_library}")
352         endif()
353     endforeach()
355     # Link in the actual target, as well.
356     list(APPEND ldflags $<TARGET_FILE:${target}>)
358     list(REMOVE_DUPLICATES ldflags)
359     list(SORT ldflags)
361     set(${result_var} ${ldflags} PARENT_SCOPE)
362 endfunction()