CMake create custom target with dependency on generated file

28 views Asked by At

In CMake, I want to create a custom target with a dependency on a generated file.

It would be along the lines of:

configure_file(conf.py.in conf.py)

add_custom_target(doc
  COMMAND ${SPHINX_EXECUTABLE} -b html ${SPHINX_SOURCE} ${SPHINX_BUILD}
  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
  COMMENT "Generating documentation with Sphinx"
  DEPENDS conf.py)

I.e. I would like to avoid unconditionally generating conf.py; I would rather have a custom target with a dependency on it and thereby limit when conf.py is generated.

How can I do this?

I don't quite understand how I can "integrate" configure_file() into the add_custom_target() (presumably the COMMAND or argument?), or make the latter "depend on" the former.

1

There are 1 answers

0
jpr42 On BEST ANSWER

configure_file occurs during configuration.

add_custom_target occurs during the build step.

CMake is roughly broken up into 3 steps:

  • Configure (configure_file will run during this step.)
  • Generate
  • Build (add_custom_target will run during this step.)

IE the file configure_file produces will be ready before add_custom_target by definition.

I.e. I would like to avoid unconditionally generating conf.py; I would rather have a custom target with a dependency on it and thereby limit when conf.py is generated.

Then your work is already done. Configure file will only run when the input file changes.

From the CMake documentation: If the input file is modified the build system will re-run CMake to re-configure the file and generate the build system again. The generated file is modified and its timestamp updated on subsequent cmake runs only if its content is changed. - configure_file

As a result you don't need to DEPEND on this file. It's guaranteed to exist before the build starts.

# conf.py is now generated in the ${CMAKE_CURRENT_BINARY_DIR}
# This is by default where configure_file places the output file
configure_file(conf.py.in conf.py)

# NOTE: By default commands are executed in ${CMAKE_CURRENT_BINARY_DIR}
# So you don't need to specify working directory.
add_custom_target(doc
  COMMAND ${SPHINX_EXECUTABLE} -b html ${SPHINX_SOURCE} ${SPHINX_BUILD}
  COMMENT "Generating documentation with Sphinx"
)