20

I am having the following directory structure:

/CMakeLists.txt
/component-a/CMakeLists.txt
           /...
/component-b/CMakeLists.txt
           /...
/doc/CMakeLists.txt
    /create-doc.sh

The shell script create-doc.sh creates a documentation file (doc.pdf). How can I use CMake to execute this shell script at build time and copy the file doc.pdf to the build directory?

I tried it by using add_custom_command in the CMakeLists.txt file inside the directory doc:

add_custom_command ( OUTPUT doc.pdf 
                     COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/create-doc.sh 
                     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/)

Unfortunately the command is never run.

I also tried execute_process:

execute_process ( COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/create-doc.sh  
                  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ ) 

Now the script is executed during the configuration phase, but not at build time.

Marcello90
  • 1,313
  • 4
  • 18
  • 33
  • 2
    Possible duplicate of [CMake add\_custom\_command not being run](http://stackoverflow.com/questions/2937128/cmake-add-custom-command-not-being-run) – Tsyvarev Oct 10 '16 at 14:30

1 Answers1

23

You got almost there with add_custom_command. This is indeed the correct way to tell CMake how to generate a file. However, CMake will only run that when something depends on that file.

When, as in your case, the file itself is the end product and is not used any further by subsequent build steps, the usual approach is to create a custom target to drive the relevant custom command(s):

add_custom_target(
  BuildDocs ALL
  DEPENDS doc.pdf
)

This (custom target driver for custom commands) is a very common idiom in CMake.

You can of course play around with arguments for add_custom_target (e.g. ALL, COMMENT) as it suits you.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • Thank you. :) Do I have to use a special CMake command to copy the doc.pdf to the build directory? `doc.pdf` is created in the directory `doc` but not being copied. – Marcello90 Oct 10 '16 at 14:47
  • @Marcello90 If you want the file to be produced in the binary directory, and the script lacks the capability to do that on its own (e.g. by passing the desired output location), then you can use an additional custom command to copy the file (and have the target depend on the *final* output location); `${CMAKE_COMMAND} -E copy_if_different` or something similar can be used to achieve platform-independent copy at build time. – Angew is no longer proud of SO Oct 10 '16 at 20:08