Reputation: 16156
I want to build my documentation (doxygen) alongside my project with CMake by default. I let CMake generate Makefiles. I know of these approaches so far:
1)
add_custom_target(doc ALL
COMMAND ${DOXYGEN_COMMAND})
2)
add_custom_command(
TARGET my-executable
POST_BUILD
COMMAND ${DOXYGEN_COMMAND})
The issue I have with the first approach is that the target is build both during build and install (i.e. when running make
and when running make install
). This is a no-go.
The issue with the second approach is that it is not actually correct: the documentation doesn't have to be built after the executable (in fact, it can be done in parallel even). Moreover I cannot build only the executable now.
Is there a way to create this custom command / target such that it is run only during make
(building) and not during make install
(installing) but independently from other targets such as executables?
Basically I'd need a "default target". Also I really want to avoid having to execute CMake recursively or make directly.
Upvotes: 1
Views: 1822
Reputation: 16156
The solution given by @Tsyvarev works perfectly except for one issue:
Running make docs
manually doesn't cause a re-build of the documentation because the "output file" ${documentation_file}
is always considered up to date (there are no dependencies specified that could be newer).
Three workarounds I found:
Run make -B docs
. The -B
flags causes GNU Make to consider all targets out of date, and thus causes the documentation to be build.
Add a "manual docs" target which depends on first a docs-clean
target which removes ${documentation_file}
and then on docs
itself (to build the documentation and the file), and run make docs-manual
:
add_custom_target(docs-clean
COMMAND ${CMAKE_COMMAND} -E remove ${documentation_file})
add_custom_target(docs-manual)
add_dependencies(docs-manual docs-clean docs)
Note that I fear that this is just a dirty hack: AFAIK the order in which the dependencies (docs-clean
and docs
) are build isn't specified, and as they don't have a dependency between them, they could even be built in parallel.
Using add_custom_command
with a TARGET docs-manual
and PRE_BUILD
(which runs the command before building dependencies) instead of the docs-clean
target would've been perfect, but this only works for Visual Studio 7 or later.
Add a custom target that depends on docs
but removes the generated ${documentation_file}
:
add_custom_target(docs-manual
COMMAND ${CMAKE_COMMAND} -E remove ${documentation_file})
add_dependencies(docs-manual docs)
This works except for when running it the first time after a make docs
, because then the generated file will still be there when docs
is built.
edit: Use add_dependencies
instead of DEPENDS
of add_custom_target
because the later is only intended for files, not for dependencies on targets.
Upvotes: 1
Reputation: 65928
Just create a file, which existence means that documentation file have been built:
set(documentation_file ${CMAKE__BINARY_DIR}/docs_ready)
# Documentation target
add_custom_target(docs ALL DEPENDS ${documentation_file})
# Documentation command
add_custom_command(OUTPUT ${documentation_file}
COMMAND ${DOXYGEN_COMMAND}
# And mark that documentation is created
COMMAND ${CMAKE_COMMAND} -E touch ${documentation_file}
)
Upvotes: 1