Integrate Doxygen with CMake

In the previous article Doxygen with C/C++, we went through how to setup the most basic documentation generation from source code. But let us integrate with CMake so that we can make it part of the building process. Furthermore, integrating it with CMake, for instance, can allow for integrating it as part of the CI/CD process.

Project Hierarchy Structure

When setting up the structure, we only need to setup the root CMake, see Setup Basic CMake, See the following for an example tree structure of our project.

  • Root Directory
    • CMakeLists.txt
    • src/code.h
    • docs
      • CMakeLists.txt
      • Doxyfile.in

The documentation will have its own dedicated folder called docs, where it has its own CMakeLists.txt file.

Inside the root CMakeLists.txt, add the following lines of code, ti will both add an option that can be enabled and disabled via command line or GUI in some applications. Followed by the ADD_SUBDIRECTORY that specifies a directory where a CMake file can be located and added to the CMake project structure.

#################################
# Generate Docs
#################################
OPTION(BUILD_WITH_DOCS "Generate Docs" ON)
IF(TASKSCH_BUILD_WITH_DOCS)
	ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/docs)
ENDIF()

Setup the documentation generation with the CMakeLists.txt file is relatively straightforward. See the following code.

FIND_PACKAGE( Doxygen )

IF(DOXYGEN_FOUND)
    MESSAGE(STATUS "Doxygen found: ${DOXYGEN_EXECUTABLE} -- ${DOXYGEN_VERSION}")

	# Set Doxygen input and output files.
	SET(DOXYGEN_INPUT_DIR ${PROJECT_SOURCE_DIR}/include)
	SET(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/doxygen)
	SET(DOXYGEN_INDEX_FILE ${DOXYGEN_OUTPUT_DIR}/xml/index.xml)
	SET(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
	SET(DOXYFILE_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)


	# Generate DoxyFile from the input file.
	CONFIGURE_FILE(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY)

	# Create Output directory.
	FILE(MAKE_DIRECTORY ${DOXYGEN_OUTPUT_DIR})


	# Command for generating doc from Doxygen config file.
	ADD_CUSTOM_COMMAND(OUTPUT ${DOXYGEN_INDEX_FILE}
					COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT}
					MAIN_DEPENDENCY ${DOXYFILE_OUT} ${DOXYFILE_IN}
					COMMENT "Generating Doxygen documentation"
					VERBATIM)


	# Create CMake Target for generating doc.
	ADD_CUSTOM_TARGET(docs ALL DEPENDS ${DOXYGEN_INDEX_FILE})

ENDIF()


The first part of the code will attempt to find Doxygen on the system.

Next, it will just create variables for each input and output file, like input directory, as well output directory where the resulting file will be located.

The CONFIGURE_FILE is quite important since it will take an input file and generate the final Doxyfile that will be used for generating the documentation.

CONFIGURE_FILE(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY)

Finally, the Custom Command will setup the command, whereas the Custom Target will be linked to the custom command. Where the Custom Target can be either be called explicitly via make, or part of all.


Last, inside the Doxyfile.in, adding the following values will allow changing the directory path from the CMake, rather hard code the directory/file paths. This is tied to the DOXYGEN_INPUT_DIR, variable that is declared in the CMakeLists.txt inside the docs folder.

INPUT                  = "@DOXYGEN_INPUT_DIR@"

Building

Once the Doxygen and CMake configuration files are configured accordingly, it is simply a matter of running CMake and running the build target.

mkdir build && cd build
cmake -DBUILD_WITH_DOCS=ON ..
make docs