CMake supports generating doxygen-based autodocs pretty much out of the box; it's little more than
find_package( Doxygen REQUIRED dot )
doxygen_add_docs( doc ../src )
This creates a new make target doc that is not built by default, i.e. only upon make doc
. This builds it by default:
doxygen_add_docs( doc ../src ALL )
In this case, it always builds it, i.e. it always runs doxygen.
By default, CMake does not install doxygen autodocs at all. This has to be done manually.
One approach is to create a custom make target like install-doc:
add_custom_target( install-doc
DEPENDS doc
COMMAND mkdir -m 755 -p ${DOC_INSTALL_DIR}/html
COMMAND install -m 644 ${DOC_FILES} ${DOC_INSTALL_DIR}
COMMAND cp -r ${CMAKE_CURRENT_BINARY_DIR}/html ${DOC_INSTALL_DIR}
COMMENT "Installing documentation to ${DOC_INSTALL_DIR}" )
Another approach is to rely on make install
and on the fact that we are not building docs by default, i.e. only when you invoke CMake with the BUILD_DOC=on option:
mkdir build
cd build
cmake -DBUILD_DOC=on ..
In that case, it is possible to add an install statement for the autodocs. Then each make install
will also install the autodocs. But that only works well if the autodocs are always built.
doxygen_add_docs( doc ../src ALL )
install( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION ${DOC_INSTALL_DIR} )
On the downside, that means that now building everything else should be explicitly disabled e.g. when building the -doc subpackage because now there is no more explicit install-doc target; it's just plain make install
which will normally build everything else (the lib in src/
, the examples in examples/
, ...):
mkdir build
cd build
cmake -DBUILD_DOC=on -DBUILD_SRC=off -DBUILD_EXAMPLES=off -DBUILD_PKGCONFIG=off -DLEGACY_BUILDTOOLS=off ..
This now needs to go into the .spec file of the -doc subpackage, and when there is a new subdirectory with a new build target, this should be updated.
For the sake of keeping it simple, we use the explicit make doc
and make install-doc
approach; otherwise we would just be moving complexity around from doc/CMakeLists.txt
to package/*-doc.spec
where it is least expected (and thus less likely to be properly maintained).
This uses a custom make install-doc
, and make doc
(i.e. doxygen) needs to be explicitly invoked when desired:
# CMakeLists.txt for libyui/doc
include( ../VERSION.cmake )
find_package( Doxygen REQUIRED dot )
set( PKG_NAME libyui${SONAME_MAJOR} )
set( DOC_INSTALL_DIR ${DOC_DESTDIR}/usr/share/doc/packages/${PKG_NAME} )
#
# Doxygen-generated autodocs
#
if ( DOXYGEN_FOUND )
set( DOXYGEN_GENERATE_TREEVIEW yes ) # Enable views tree HTML frame
set( DOXYGEN_QUIET yes ) # Less verbose output
set( DOXYGEN_WARN_LOGFILE doxygen-warnings.log )
# See build/CMakeDoxyfile.in for more supported variables
doxygen_add_docs( doc ../src )
else()
message( WARNING "Missing doxygen package" )
endif()
#
# Other (manually written) docs
#
file( GLOB DOC_FILES *.md ) # Collect all *.md files by wildcard
# Don't glob *.txt (CMakeLists.txt!)
# The license files (../COPYING*) are handled in the .spec file
# Define a new custom make target "install-doc".
# Notice that we can't use DESTDIR here since CMake only sets that
# for "make install", not for this custom "make install-doc".
add_custom_target( install-doc
DEPENDS doc
COMMAND mkdir -m 755 -p ${DOC_INSTALL_DIR}/html
COMMAND install -m 644 ${DOC_FILES} ${DOC_INSTALL_DIR}
COMMAND cp -r ${CMAKE_CURRENT_BINARY_DIR}/html ${DOC_INSTALL_DIR}
COMMENT "Installing documentation to ${DOC_INSTALL_DIR}" )
This automatically always invokes make doc
, and the autodocs are installed implicitly with make install
:
# CMakeLists.txt for libyui/doc
include( ../VERSION.cmake )
find_package( Doxygen REQUIRED dot )
set( PKG_NAME libyui${SONAME_MAJOR} )
set( DOC_INSTALL_DIR /usr/share/doc/packages/${PKG_NAME} )
#
# Doxygen-generated autodocs
#
if ( DOXYGEN_FOUND )
set( DOXYGEN_GENERATE_TREEVIEW yes ) # Enable views tree HTML frame
set( DOXYGEN_QUIET yes ) # Less verbose output
set( DOXYGEN_WARN_LOGFILE doxygen-warnings.log )
# See build/CMakeDoxyfile.in for more supported variables
doxygen_add_docs( doc ../src ALL )
install( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html
DESTINATION ${DOC_INSTALL_DIR} )
else()
message( WARNING "Missing doxygen package" )
endif()
#
# Other (manually written) docs
#
file( GLOB DOC_FILES *.md ) # Collect all *.md files by wildcard
# Don't glob *.txt (CMakeLists.txt!)
# The license files (../COPYING*) are handled in the .spec file
install( FILES ${DOC_FILES} DESTINATION ${DOC_INSTALL_DIR} )
In the context of RPM / OBS builds, we need to support installing to $RPM_BUILD_ROOT. For make install
, CMake supports this with the $DESTDIR environment variable which it makes available as the $DESTDIR CMake variable; it also automatically uses that as a prefix in common CMake install(...)
calls.
For custom targets like make install-doc
, it proved to be impossible to set or use that $DESTDIR variable; it's just always empty. It is only set when make install
is called, not for any other make targets.
So, we had to introduce a separate $DOC_DESTDIR variable which is set via a CMake option:
cmake -DBUILD_DOC=on -DDOC_DESTDIR=$RPM_BUILD_ROOT ..
make install-doc
I'd prefer the make DESTDIR=$RPM_BUILD_ROOT install way also because we use a single spec file for lib and docs