1#.rst:
2# FindGtkDoc
3# ----------
4#
5# CMake macros to find and use the GtkDoc documentation system
6
7# Output variables:
8#
9#   GTKDOC_FOUND            ... set to 1 if GtkDoc was foung
10#
11# If GTKDOC_FOUND == 1:
12#
13#   GTKDOC_SCAN_EXE         ... the location of the gtkdoc-scan executable
14#   GTKDOC_SCANGOBJ_EXE     ... the location of the gtkdoc-scangobj executable
15#   GTKDOC_MKDB_EXE         ... the location of the gtkdoc-mkdb executable
16#   GTKDOC_MKHTML_EXE       ... the location of the gtkdoc-mkhtml executable
17#   GTKDOC_FIXXREF_EXE      ... the location of the gtkdoc-fixxref executable
18
19#=============================================================================
20# Copyright 2009 Rich Wareham
21# Copyright 2015 Lautsprecher Teufel GmbH
22#
23# Distributed under the OSI-approved BSD License (the "License");
24# see accompanying file Copyright.txt for details.
25#
26# This software is distributed WITHOUT ANY WARRANTY; without even the
27# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
28# See the License for more information.
29#=============================================================================
30# (To distribute this file outside of CMake, substitute the full
31#  License text for the above reference.)
32
33include(CMakeParseArguments)
34include(FindPackageHandleStandardArgs)
35
36find_package(PkgConfig REQUIRED)
37
38# The UseGtkDoc.cmake module requires at least 1.9, because it doesn't use
39# the deprecated `gtkdoc-mktmpl` tool. We will check if the version satisfies
40# the user's specified dependencies later (with the
41# find_package_handle_standard_args() command).
42pkg_check_modules(GtkDoc REQUIRED gtk-doc>=1.9)
43
44find_program(GTKDOC_SCAN_EXE gtkdoc-scan PATH "${GLIB_PREFIX}/bin")
45find_program(GTKDOC_SCANGOBJ_EXE gtkdoc-scangobj PATH "${GLIB_PREFIX}/bin")
46
47get_filename_component(_this_dir ${CMAKE_CURRENT_LIST_FILE} PATH)
48find_file(GTKDOC_SCANGOBJ_WRAPPER GtkDocScanGObjWrapper.cmake PATH ${_this_dir})
49
50find_program(GTKDOC_MKDB_EXE gtkdoc-mkdb PATH "${GLIB_PREFIX}/bin")
51find_program(GTKDOC_MKHTML_EXE gtkdoc-mkhtml PATH "${GLIB_PREFIX}/bin")
52find_program(GTKDOC_FIXXREF_EXE gtkdoc-fixxref PATH "${GLIB_PREFIX}/bin")
53
54find_package_handle_standard_args(GtkDoc
55    REQUIRED_VARS GTKDOC_SCAN_EXE GTKDOC_SCANGOBJ_EXE GTKDOC_SCANGOBJ_WRAPPER GTKDOC_MKDB_EXE GTKDOC_MKHTML_EXE GTKDOC_FIXXREF_EXE
56    VERSION_VAR GtkDoc_VERSION)
57
58# ::
59#
60# gtk_doc_add_module(doc_prefix sourcedir
61#                    [XML xmlfile]
62#                    [FIXXREFOPTS fixxrefoption1...]
63#                    [IGNOREHEADERS header1...]
64#                    [DEPENDS depend1...] )
65#
66# sourcedir must be the *full* path to the source directory.
67#
68# If omitted, sgmlfile defaults to the auto generated ${doc_prefix}/${doc_prefix}-docs.xml.
69macro(gtk_doc_add_module _doc_prefix _doc_sourcedir)
70    set(_one_value_args "XML")
71    set(_multi_value_args "DEPENDS" "XML" "FIXXREFOPTS" "IGNOREHEADERS"
72                          "CFLAGS" "LDFLAGS" "LDPATH" "SUFFIXES")
73    cmake_parse_arguments("GTK_DOC" "" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
74
75    set(_depends ${GTK_DOC_DEPENDS})
76    set(_xml ${GTK_DOC_XML})
77    set(_fixxrefopts ${GTK_DOC_FIXXREFOPTS})
78    set(_ignoreheaders ${GTK_DOC_IGNOREHEADERS})
79    set(_extra_cflags ${GTK_DOC_CFLAGS})
80    set(_extra_ldflags ${GTK_DOC_LDFLAGS})
81    set(_extra_ldpath ${GTK_DOC_LDPATH})
82    set(_suffixes ${GTK_DOC_SUFFIXES})
83
84    list(LENGTH _xml_file _xml_file_length)
85
86    if(_suffixes)
87        set(_doc_source_suffixes "")
88        foreach(_suffix ${_suffixes})
89            if(_doc_source_suffixes)
90                set(_doc_source_suffixes "${_doc_source_suffixes},${_suffix}")
91            else(_doc_source_suffixes)
92                set(_doc_source_suffixes "${_suffix}")
93            endif(_doc_source_suffixes)
94        endforeach(_suffix)
95    else(_suffixes)
96        set(_doc_source_suffixes "h")
97    endif(_suffixes)
98
99    # set(_do_all ALL)
100
101    set(_opts_valid 1)
102    if(NOT _xml_file_length LESS 2)
103        message(SEND_ERROR "Must have at most one sgml file specified.")
104        set(_opts_valid 0)
105    endif(NOT _xml_file_length LESS 2)
106
107    if(_opts_valid)
108        # a directory to store output.
109        set(_output_dir "${CMAKE_CURRENT_BINARY_DIR}/${_doc_prefix}")
110        set(_output_dir_stamp "${_output_dir}/dir.stamp")
111
112        # set default sgml file if not specified
113        set(_default_xml_file "${_output_dir}/${_doc_prefix}-docs.xml")
114        get_filename_component(_default_xml_file ${_default_xml_file} ABSOLUTE)
115
116        # a directory to store html output.
117        set(_output_html_dir "${_output_dir}/html")
118        set(_output_html_dir_stamp "${_output_dir}/html_dir.stamp")
119
120        # The output files
121        set(_output_decl_list "${_output_dir}/${_doc_prefix}-decl-list.txt")
122        set(_output_decl "${_output_dir}/${_doc_prefix}-decl.txt")
123        set(_output_overrides "${_output_dir}/${_doc_prefix}-overrides.txt")
124        set(_output_sections "${_output_dir}/${_doc_prefix}-sections.txt")
125        set(_output_types "${_output_dir}/${_doc_prefix}.types")
126
127        set(_output_signals "${_output_dir}/${_doc_prefix}.signals")
128
129        set(_output_unused "${_output_dir}/${_doc_prefix}-unused.txt")
130        set(_output_undeclared "${_output_dir}/${_doc_prefix}-undeclared.txt")
131        set(_output_undocumented "${_output_dir}/${_doc_prefix}-undocumented.txt")
132
133        set(_output_xml_dir "${_output_dir}/xml")
134        set(_output_sgml_stamp "${_output_dir}/sgml.stamp")
135
136        set(_output_html_stamp "${_output_dir}/html.stamp")
137
138        # add a command to create output directory
139        add_custom_command(
140            OUTPUT "${_output_dir_stamp}" "${_output_dir}"
141            COMMAND ${CMAKE_COMMAND} -E make_directory "${_output_dir}"
142            COMMAND ${CMAKE_COMMAND} -E touch ${_output_dir_stamp}
143            VERBATIM)
144
145        set(_ignore_headers_opt "")
146        if(_ignore_headers)
147            set(_ignore_headers_opt "--ignore-headers=")
148            foreach(_header ${_ignore_headers})
149                set(_ignore_headers_opt "${_ignore_headers_opt}${_header} ")
150            endforeach(_header ${_ignore_headers})
151        endif(_ignore_headers)
152
153        # add a command to scan the input
154        add_custom_command(
155            OUTPUT
156                "${_output_decl_list}"
157                "${_output_decl}"
158                "${_output_decl}.bak"
159                "${_output_overrides}"
160                "${_output_sections}"
161                "${_output_types}"
162                "${_output_types}.bak"
163            DEPENDS
164                "${_output_dir}"
165                ${_depends}
166            COMMAND ${GTKDOC_SCAN_EXE}
167                "--module=${_doc_prefix}"
168                "${_ignore_headers_opt}"
169                "--rebuild-sections"
170                "--rebuild-types"
171                "--source-dir=${_doc_sourcedir}"
172            WORKING_DIRECTORY "${_output_dir}"
173            VERBATIM)
174
175        # add a command to scan the input via gtkdoc-scangobj
176        # This is such a disgusting hack!
177        add_custom_command(
178            OUTPUT
179                "${_output_signals}"
180            DEPENDS
181                "${_output_types}"
182            COMMAND ${CMAKE_COMMAND}
183                -D "GTKDOC_SCANGOBJ_EXE:STRING=${GTKDOC_SCANGOBJ_EXE}"
184                -D "doc_prefix:STRING=${_doc_prefix}"
185                -D "output_types:STRING=${_output_types}"
186                -D "output_dir:STRING=${_output_dir}"
187                -D "EXTRA_CFLAGS:STRING=${_extra_cflags}"
188                -D "EXTRA_LDFLAGS:STRING=${_extra_ldflags}"
189                -D "EXTRA_LDPATH:STRING=${_extra_ldpath}"
190                -P ${GTKDOC_SCANGOBJ_WRAPPER}
191            WORKING_DIRECTORY "${_output_dir}"
192            VERBATIM)
193
194        set(_copy_xml_if_needed "")
195        if(_xml_file)
196            get_filename_component(_xml_file ${_xml_file} ABSOLUTE)
197            set(_copy_xml_if_needed
198                COMMAND ${CMAKE_COMMAND} -E copy "${_xml_file}" "${_default_xml_file}")
199        endif(_xml_file)
200
201        set(_remove_xml_if_needed "")
202        if(_xml_file)
203            set(_remove_xml_if_needed
204                COMMAND ${CMAKE_COMMAND} -E remove ${_default_xml_file})
205        endif(_xml_file)
206
207        # add a command to make the database
208        add_custom_command(
209            OUTPUT
210                "${_output_sgml_stamp}"
211                "${_default_xml_file}"
212            DEPENDS
213                "${_output_types}"
214                "${_output_signals}"
215                "${_output_sections}"
216                "${_output_overrides}"
217                ${_depends}
218            ${_remove_xml_if_needed}
219            COMMAND ${CMAKE_COMMAND} -E remove_directory ${_output_xml_dir}
220            COMMAND ${GTKDOC_MKDB_EXE}
221                "--module=${_doc_prefix}"
222                "--source-dir=${_doc_sourcedir}"
223                "--source-suffixes=${_doc_source_suffixes}"
224                "--output-format=xml"
225                "--main-sgml-file=${_default_xml_file}"
226            ${_copy_xml_if_needed}
227            WORKING_DIRECTORY "${_output_dir}"
228            VERBATIM)
229
230        # add a command to create html directory
231        add_custom_command(
232            OUTPUT "${_output_html_dir_stamp}" "${_output_html_dir}"
233            COMMAND ${CMAKE_COMMAND} -E make_directory ${_output_html_dir}
234            COMMAND ${CMAKE_COMMAND} -E touch ${_output_html_dir_stamp}
235            VERBATIM)
236
237        # add a command to output HTML
238        add_custom_command(
239            OUTPUT
240                "${_output_html_stamp}"
241            DEPENDS
242                "${_output_html_dir_stamp}"
243                "${_output_sgml_stamp}"
244                "${_xml_file}"
245                ${_depends}
246            ${_copy_xml_if_needed}
247            COMMAND
248                cd "${_output_html_dir}" && ${GTKDOC_MKHTML_EXE}
249                    "${_doc_prefix}"
250                    "${_default_xml_file}"
251            COMMAND
252                cd "${_output_dir}" && ${GTKDOC_FIXXREF_EXE}
253                    "--module=${_doc_prefix}"
254                    "--module-dir=${_output_html_dir}"
255                    ${_fixxref_opts}
256                    ${_remove_xml_if_needed}
257            VERBATIM)
258
259        add_custom_target(doc-${_doc_prefix} ${_do_all}
260            DEPENDS "${_output_html_stamp}")
261    endif(_opts_valid)
262endmacro(gtk_doc_add_module)
263