commit c5a6429ce7fc1eb06d335e3125855934c360ee29
Author: Sam Thursfield <sam.thursfield@codethink.co.uk>
Date:   Thu Oct 8 09:37:01 2015 +0200

    Add initial CMake macros for GTK-Doc
    
    These are based on macros shipped as part of the FILTREE real-time image
    filtering system, at <https://github.com/rjw57/firtree/tree/master/>.
    
    See the manual and the GtkDocConfig.cmake module for more information.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=756297

diff --git a/Makefile.am b/Makefile.am
index 47c9008..3fe249d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
 ## Process this file with automake to produce Makefile.in
 ACLOCAL_AMFLAGS=-I m4 ${ACLOCAL_FLAGS}
 
-SUBDIRS = help tests
+SUBDIRS = cmake help tests
 
 bin_SCRIPTS = \
 	gtkdoc-check    \
diff --git a/cmake/GtkDocConfig.cmake b/cmake/GtkDocConfig.cmake
new file mode 100644
index 0000000..ea96ef6
--- /dev/null
+++ b/cmake/GtkDocConfig.cmake
@@ -0,0 +1,338 @@
+# CMake macros to use the GtkDoc documentation system
+#
+# See the GTK-Doc manual (help/manual/C/index.docbook) for an example of how to
+# use this.
+
+# Output variables:
+#
+#   GTKDOC_FOUND            ... set to 1
+#
+#   GTKDOC_SCAN_EXE         ... the location of the gtkdoc-scan executable
+#   GTKDOC_SCANGOBJ_EXE     ... the location of the gtkdoc-scangobj executable
+#   GTKDOC_MKDB_EXE         ... the location of the gtkdoc-mkdb executable
+#   GTKDOC_MKHTML_EXE       ... the location of the gtkdoc-mkhtml executable
+#   GTKDOC_FIXXREF_EXE      ... the location of the gtkdoc-fixxref executable
+
+
+#=============================================================================
+# Copyright 2009 Rich Wareham
+# Copyright 2015 Lautsprecher Teufel GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#=============================================================================
+
+include(CMakeParseArguments)
+
+set(GTKDOC_FOUND 1)
+
+set(GTKDOC_SCAN_EXE ${exec_prefix}/bin/gtkdoc-scan)
+set(GTKDOC_SCANGOBJ_EXE ${exec_prefix}/bin/gtkdoc-scangobj)
+set(GTKDOC_MKDB_EXE ${exec_prefix}/bin/gtkdoc-mkdb)
+set(GTKDOC_MKHTML_EXE ${exec_prefix}/bin/gtkdoc-mkhtml)
+set(GTKDOC_FIXXREF_EXE ${exec_prefix}/bin/gtkdoc-fixxref)
+
+get_filename_component(_this_dir ${CMAKE_CURRENT_LIST_FILE} PATH)
+find_file(GTKDOC_SCANGOBJ_WRAPPER GtkDocScanGObjWrapper.cmake PATH ${_this_dir})
+
+# ::
+#
+# gtk_doc_add_module(doc_prefix sourcedir
+#                    XML xmlfile
+#                    [LIBRARIES depend1...]
+#                    [FIXXREFOPTS fixxrefoption1...]
+#                    [IGNOREHEADERS header1...])
+#
+# Add a module with documentation to be processed with GTK-Doc.
+#
+# sourcedir must be the *full* path to the source directory.
+#
+# If omitted, xmlfile defaults to the auto generated ${doc_prefix}/${doc_prefix}-docs.xml.
+#
+# The `gtkdoc-scangobj` program is used to get introspection information for
+# the module. You should pass the target(s) to be scanned as LIRARIES. This
+# will try to set the correct compiler and link flags for the introspection
+# build to use, and the correct LD_LIBRARY_PATH for it to run, and the correct
+# dependencies for the doc target.
+#
+# You *can* also set the compile and link flags manually, using the 'CFLAGS'
+# and 'LDFLAGS' options. The 'LDPATH' option controls the LD_LIBRARY_PATH. You
+# can also manually add additional targets as dependencies of the
+# documentation build with the DEPENDS option.
+#
+# This function a target named "doc-${doc_prefix}". You will need to manually
+# add it to the ALL target if you want it to be built by default, you can do
+# something like this:
+#
+#   gtk_doc_add_module(doc-mymodule ${CMAKE_SOURCE_DIR}/module
+#                      LIBRARIES mylibrary)
+#   add_custom_target(all-documentation ALL)
+#   add_dependencies(all-documentation doc-mymodule)
+#
+function(gtk_doc_add_module _doc_prefix _doc_sourcedir)
+    set(_one_value_args "XML")
+    set(_multi_value_args "FIXXREFOPTS" "IGNOREHEADERS" "LIBRARIES" "SUFFIXES"
+                          "CFLAGS" "DEPENDS" "LDFLAGS" "LDPATH")
+    cmake_parse_arguments("GTK_DOC" "" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
+
+    set(_xml ${GTK_DOC_XML})
+
+    set(_fixxrefopts ${GTK_DOC_FIXXREFOPTS})
+    set(_ignoreheaders ${GTK_DOC_IGNOREHEADERS})
+    set(_libraries ${GTK_DOC_LIBRARIES})
+    set(_suffixes ${GTK_DOC_SUFFIXES})
+
+    set(_extra_cflags ${GTK_DOC_CFLAGS})
+    set(_depends ${GTK_DOC_DEPENDS})
+    set(_extra_ldflags ${GTK_DOC_LDFLAGS})
+    set(_extra_ldpath ${GTK_DOC_LDPATH})
+
+    if(_suffixes)
+        set(_doc_source_suffixes "")
+        foreach(_suffix ${_suffixes})
+            if(_doc_source_suffixes)
+                set(_doc_source_suffixes "${_doc_source_suffixes},${_suffix}")
+            else(_doc_source_suffixes)
+                set(_doc_source_suffixes "${_suffix}")
+            endif(_doc_source_suffixes)
+        endforeach(_suffix)
+    else(_suffixes)
+        set(_doc_source_suffixes "h")
+    endif(_suffixes)
+
+    # Parse the LIBRARIES option and collect compile and link flags for those
+    # targets.
+    foreach(target ${_libraries})
+        _gtk_doc_get_cflags_for_target(_target_cflags ${target})
+        _gtk_doc_get_ldflags_for_target(_target_ldflags ${target} "${_libraries}")
+        list(APPEND _extra_cflags ${_target_cflags})
+        list(APPEND _extra_ldflags ${_target_ldflags})
+        list(APPEND _extra_ldpath $<TARGET_FILE_DIR:${target}>)
+    endforeach()
+
+    # a directory to store output.
+    set(_output_dir "${CMAKE_CURRENT_BINARY_DIR}/${_doc_prefix}")
+    set(_output_dir_stamp "${_output_dir}/dir.stamp")
+
+    # set default sgml file if not specified
+    set(_default_xml_file "${_output_dir}/${_doc_prefix}-docs.xml")
+    get_filename_component(_default_xml_file ${_default_xml_file} ABSOLUTE)
+
+    # a directory to store html output.
+    set(_output_html_dir "${_output_dir}/html")
+    set(_output_html_dir_stamp "${_output_dir}/html_dir.stamp")
+
+    # The output files
+    set(_output_decl_list "${_output_dir}/${_doc_prefix}-decl-list.txt")
+    set(_output_decl "${_output_dir}/${_doc_prefix}-decl.txt")
+    set(_output_overrides "${_output_dir}/${_doc_prefix}-overrides.txt")
+    set(_output_sections "${_output_dir}/${_doc_prefix}-sections.txt")
+    set(_output_types "${_output_dir}/${_doc_prefix}.types")
+
+    set(_output_signals "${_output_dir}/${_doc_prefix}.signals")
+
+    set(_output_unused "${_output_dir}/${_doc_prefix}-unused.txt")
+    set(_output_undeclared "${_output_dir}/${_doc_prefix}-undeclared.txt")
+    set(_output_undocumented "${_output_dir}/${_doc_prefix}-undocumented.txt")
+
+    set(_output_xml_dir "${_output_dir}/xml")
+    set(_output_sgml_stamp "${_output_dir}/sgml.stamp")
+
+    set(_output_html_stamp "${_output_dir}/html.stamp")
+
+    # add a command to create output directory
+    add_custom_command(
+        OUTPUT "${_output_dir_stamp}" "${_output_dir}"
+        COMMAND ${CMAKE_COMMAND} -E make_directory "${_output_dir}"
+        COMMAND ${CMAKE_COMMAND} -E touch ${_output_dir_stamp}
+        VERBATIM)
+
+    set(_ignore_headers_opt "")
+    if(_ignore_headers)
+        set(_ignore_headers_opt "--ignore-headers=")
+        foreach(_header ${_ignore_headers})
+            set(_ignore_headers_opt "${_ignore_headers_opt}${_header} ")
+        endforeach(_header ${_ignore_headers})
+    endif(_ignore_headers)
+
+    # add a command to scan the input
+    add_custom_command(
+        OUTPUT
+            "${_output_decl_list}"
+            "${_output_decl}"
+            "${_output_decl}.bak"
+            "${_output_overrides}"
+            "${_output_sections}"
+            "${_output_types}"
+            "${_output_types}.bak"
+        DEPENDS
+            "${_output_dir}"
+            ${_depends}
+        COMMAND ${GTKDOC_SCAN_EXE}
+            "--module=${_doc_prefix}"
+            "${_ignore_headers_opt}"
+            "--rebuild-sections"
+            "--rebuild-types"
+            "--source-dir=${_doc_sourcedir}"
+        WORKING_DIRECTORY "${_output_dir}"
+        VERBATIM)
+
+    # add a command to scan the input via gtkdoc-scangobj
+    # This is such a disgusting hack!
+    add_custom_command(
+        OUTPUT
+            "${_output_signals}"
+        DEPENDS
+            "${_output_types}"
+        COMMAND ${CMAKE_COMMAND}
+            -D "GTKDOC_SCANGOBJ_EXE:STRING=${GTKDOC_SCANGOBJ_EXE}"
+            -D "doc_prefix:STRING=${_doc_prefix}"
+            -D "output_types:STRING=${_output_types}"
+            -D "output_dir:STRING=${_output_dir}"
+            -D "EXTRA_CFLAGS:STRING=${_extra_cflags}"
+            -D "EXTRA_LDFLAGS:STRING=${_extra_ldflags}"
+            -D "EXTRA_LDPATH:STRING=${_extra_ldpath}"
+            -P ${GTKDOC_SCANGOBJ_WRAPPER}
+        WORKING_DIRECTORY "${_output_dir}"
+        VERBATIM)
+
+    set(_copy_xml_if_needed "")
+    if(_xml_file)
+        get_filename_component(_xml_file ${_xml_file} ABSOLUTE)
+        set(_copy_xml_if_needed
+            COMMAND ${CMAKE_COMMAND} -E copy "${_xml_file}" "${_default_xml_file}")
+    endif(_xml_file)
+
+    set(_remove_xml_if_needed "")
+    if(_xml_file)
+        set(_remove_xml_if_needed
+            COMMAND ${CMAKE_COMMAND} -E remove ${_default_xml_file})
+    endif(_xml_file)
+
+    # add a command to make the database
+    add_custom_command(
+        OUTPUT
+            "${_output_sgml_stamp}"
+            "${_default_xml_file}"
+        DEPENDS
+            "${_output_types}"
+            "${_output_signals}"
+            "${_output_sections}"
+            "${_output_overrides}"
+            ${_depends}
+        ${_remove_xml_if_needed}
+        COMMAND ${CMAKE_COMMAND} -E remove_directory ${_output_xml_dir}
+        COMMAND ${GTKDOC_MKDB_EXE}
+            "--module=${_doc_prefix}"
+            "--source-dir=${_doc_sourcedir}"
+            "--source-suffixes=${_doc_source_suffixes}"
+            "--output-format=xml"
+            "--main-sgml-file=${_default_xml_file}"
+        ${_copy_xml_if_needed}
+        WORKING_DIRECTORY "${_output_dir}"
+        VERBATIM)
+
+    # add a command to create html directory
+    add_custom_command(
+        OUTPUT "${_output_html_dir_stamp}" "${_output_html_dir}"
+        COMMAND ${CMAKE_COMMAND} -E make_directory ${_output_html_dir}
+        COMMAND ${CMAKE_COMMAND} -E touch ${_output_html_dir_stamp}
+        VERBATIM)
+
+    # add a command to output HTML
+    add_custom_command(
+        OUTPUT
+            "${_output_html_stamp}"
+        DEPENDS
+            "${_output_html_dir_stamp}"
+            "${_output_sgml_stamp}"
+            "${_xml_file}"
+            ${_depends}
+        ${_copy_xml_if_needed}
+        COMMAND
+            cd "${_output_html_dir}" && ${GTKDOC_MKHTML_EXE}
+                "${_doc_prefix}"
+                "${_default_xml_file}"
+        COMMAND
+            cd "${_output_dir}" && ${GTKDOC_FIXXREF_EXE}
+                "--module=${_doc_prefix}"
+                "--module-dir=${_output_html_dir}"
+                ${_fixxref_opts}
+                ${_remove_xml_if_needed}
+        VERBATIM)
+
+    add_custom_target(doc-${_doc_prefix}
+        DEPENDS "${_output_html_stamp}")
+endfunction(gtk_doc_add_module)
+
+# These two functions reimplement some of the core logic of CMake, in order
+# to generate compiler and linker flags from the relevant target properties.
+# It sucks that we have to do this, but CMake's own code for this doesn't seem
+# to be reusable -- there's no way to say "tell me the flags that you would
+# pass to a linker for this target".
+
+function(_gtk_doc_get_cflags_for_target result_var target)
+    get_target_property(target_definitions ${target} COMPILE_DEFINITIONS)
+    if(target_definitions)
+        list(APPEND cflags ${target_definitions})
+    endif()
+
+    get_target_property(target_options ${target} COMPILE_OPTIONS)
+    if(target_options)
+        list(APPEND cflags ${target_options})
+    endif()
+
+    get_target_property(target_include_dirs ${target} INCLUDE_DIRECTORIES)
+    foreach(target_include_dir ${target_include_dirs})
+        list(APPEND cflags -I${target_include_dir})
+    endforeach()
+
+    list(REMOVE_DUPLICATES cflags)
+    list(SORT cflags)
+
+    set(${result_var} ${cflags} PARENT_SCOPE)
+endfunction()
+
+function(_gtk_doc_get_ldflags_for_target result_var target all_targets)
+    get_target_property(target_link_flags ${target} LINK_FLAGS)
+    if(target_link_flags)
+        list(APPEND ldflags ${target_link_flags})
+    endif()
+
+    get_target_property(target_link_libraries ${target} LINK_LIBRARIES)
+    foreach(target_library ${target_link_libraries})
+        # The IN_LIST operator is new in CMake 3.3, so I've tried to avoid using it.
+        list(FIND all_targets ${target_library} target_library_is_explicit_dependency)
+        if(NOT ${target_library_is_explicit_dependency} EQUAL -1)
+            # This target is part of the current project. We will add it to
+            # LDFLAGS explicitly, so don't try to add it with -l<target> as
+            # well. In fact, we can't do that, as the containing directory
+            # probably won't be in the linker search path, and we can't find
+            # that out and add it ourselves.
+        elseif(EXISTS ${target_library})
+            # Pass the filename directly to the linker.
+            list(APPEND ldflags "${target_library}")
+        else()
+            # Pass -l<filename> to the linker.
+            list(APPEND ldflags "${CMAKE_LINK_LIBRARY_FLAG}${target_library}")
+        endif()
+    endforeach()
+
+    # Link in the actual target, as well.
+    list(APPEND ldflags $<TARGET_FILE:${target}>)
+
+    list(REMOVE_DUPLICATES ldflags)
+    list(SORT ldflags)
+
+    set(${result_var} ${ldflags} PARENT_SCOPE)
+endfunction()
diff --git a/cmake/GtkDocScanGObjWrapper.cmake b/cmake/GtkDocScanGObjWrapper.cmake
new file mode 100644
index 0000000..4ad7d2e
--- /dev/null
+++ b/cmake/GtkDocScanGObjWrapper.cmake
@@ -0,0 +1,67 @@
+# Internal -- for use with UseGtkDoc.cmake
+#
+#=============================================================================
+# Copyright 2009 Rich Wareham
+# Copyright 2015 Lautsprecher Teufel GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#=============================================================================
+
+# This is needed for find_package(PkgConfig) to work correctly --
+# CMAKE_MINIMUM_REQUIRED_VERSION needs to be defined.
+cmake_minimum_required(VERSION 3.2)
+
+if(NOT APPLE)
+    # We use pkg-config to find glib et al
+    find_package(PkgConfig)
+    # Find glib et al
+    pkg_check_modules(GLIB REQUIRED glib-2.0 gobject-2.0)
+
+foreach(_flag ${EXTRA_CFLAGS} ${GLIB_CFLAGS})
+    set(ENV{CFLAGS} "$ENV{CFLAGS} \"${_flag}\"")
+endforeach(_flag)
+
+foreach(_flag ${EXTRA_LDFLAGS} ${GLIB_LDFLAGS})
+    set(ENV{LDFLAGS} "$ENV{LDFLAGS} \"${_flag}\"")
+endforeach(_flag)
+
+foreach(_flag ${EXTRA_LDPATH})
+    if(ENV{LD_LIBRARY_PATH})
+        set(ENV{LD_LIBRARY_PATH} "$ENV{LD_LIBRARY_PATH}:\"${_flag}\"")
+    else(ENV{LD_LIBRARY_PATH})
+        set(ENV{LD_LIBRARY_PATH} "${_flag}")
+    endif(ENV{LD_LIBRARY_PATH})
+endforeach(_flag)
+
+message(STATUS "Executing gtkdoc-scangobj with:")
+message(STATUS "   CFLAGS: $ENV{CFLAGS}")
+message(STATUS "  LDFLAGS: $ENV{LDFLAGS}")
+message(STATUS "   LDPATH: $ENV{LD_LIBRARY_PATH}")
+
+execute_process(COMMAND ${GTKDOC_SCANGOBJ_EXE}
+    "--module=${doc_prefix}"
+    "--types=${output_types}"
+    "--output-dir=${output_dir}"
+    WORKING_DIRECTORY "${output_dir}"
+    RESULT_VARIABLE _scan_result)
+
+if(_scan_result EQUAL 0)
+    message(STATUS "Scan succeeded.")
+else(_scan_result EQUAL 0)
+    message(SEND_ERROR "Scan failed.")
+endif(_scan_result EQUAL 0)
+
+endif(NOT APPLE)
+
+# vim:sw=4:ts=4:et:autoindent
diff --git a/cmake/Makefile.am b/cmake/Makefile.am
new file mode 100644
index 0000000..3b5d88a
--- /dev/null
+++ b/cmake/Makefile.am
@@ -0,0 +1,9 @@
+EXTRA_DIST = \
+	GtkDocConfig.cmake.in
+	GtkDocConfigVersion.cmake.in
+
+cmakedir = $(libdir)/cmake/GtkDoc
+cmake_DATA = \
+	GtkDocConfig.cmake \
+	GtkDocConfigVersion.cmake \
+	GtkDocScanGObjWrapper.cmake
diff --git a/configure.ac b/configure.ac
index 1e092af..dea22f6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -240,6 +240,9 @@ gtk-doc.dsl
 gtk-doc.spec
 gtk-doc.cat
 gtkdoc-common.pl
+cmake/Makefile
+cmake/GtkDocConfig.cmake
+cmake/GtkDocConfigVersion.cmake
 help/Makefile
 help/manual/Makefile
 tests/Makefile
diff --git a/help/manual/C/index.docbook b/help/manual/C/index.docbook
index cac2db7..5a51123 100644
--- a/help/manual/C/index.docbook
+++ b/help/manual/C/index.docbook
@@ -639,6 +639,42 @@ gtkdoc-fixxref --module=$(DOC_MODULE) --module-dir=html
       </para>
     </sect1>
 
+    <sect1 id="cmake">
+       <title>Integration with CMake build systems</title>
+
+       <para>
+          GTK-Doc now provides a <filename>GtkDocConfig.cmake</filename> module
+          (and the corresponding <filename>GtkDocConfigVersion.cmake</filename>
+          module). This provides a <literal>gtk_doc_add_module</literal>
+          command that you can set in your <filename>CMakeLists.txt</filename>
+          file.
+       </para>
+
+       <para>
+          The following example shows how to use this command.
+          <example><title>Example of using GTK-Doc from CMake</title>
+             <programlisting><![CDATA[
+find_package(GtkDoc 1.25 REQUIRED)
+
+# Create the doc-libmeep target.
+gtk_doc_add_module(
+   libmeep ${CMAKE_SOURCE_DIR}/libmeep
+      XML meep-docs.xml
+      LIBRARIES libmeep
+)
+
+# Build doc-libmeep as part of the default target. Without this, you would
+# have to explicitly run something like `make doc-libmeep` to build the docs.
+add_custom_target(documentation ALL DEPENDS doc-libmeep)
+
+# Install the docs. (This assumes you're using the GNUInstallDirs CMake module
+# to set the CMAKE_INSTALL_DOCDIR variable correctly).
+install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/libmeep/html
+        DESTINATION ${CMAKE_INSTALL_DOCDIR})
+]]></programlisting>
+         </example>
+       </para>
+     </sect1>
   </chapter>
 
   <chapter id="documenting">
