[CMake] Building output of add_custom_command in multiple targets in Visual Studio

Fujii Hironori fujii.hironori at gmail.com
Mon Apr 18 02:26:25 EDT 2016


I have a problem building output of add_custom_command in multiple
projects causes unnecessary rebuild in Visual Studio.  This problem is
mentioned in the CMake documentation:

 add_custom_command — CMake 3.5.1 Documentation
 https://cmake.org/cmake/help/v3.5/command/add_custom_command.html

| Do not list the output in more than one independent target that may
| build in parallel or the two instances of the rule may conflict
| (instead use the add_custom_target() command to drive the command and
| make the other targets depend on that one).

But, the solution of using add_custom_target does not solve the problem.
This is a simplified CMake script:

| cmake_minimum_required(VERSION 3.5)
|
| project(hello VERSION 0.1 LANGUAGES CXX)
|
| add_custom_command(OUTPUT generated.cpp
|   COMMAND ${CMAKE_COMMAND} -E echo "int x;" >
${CMAKE_CURRENT_BINARY_DIR}/generated.cpp)
|
| add_executable(program_a
|   main_a.cxx
|   ${CMAKE_CURRENT_BINARY_DIR}/generated.cpp
| )
|
| add_executable(program_b
|   main_b.cxx
|   ${CMAKE_CURRENT_BINARY_DIR}/generated.cpp
| )
| add_dependencies(program_b program_a)

First time building ALL_BUILD, Visual Studio generates the
generated.cpp in both projects program_a and program_b.
Then, in the next time of ALL_BUILD, program_a is built because
generated.cpp is updated after building program_a.

Using add_custom_target does not solve the problem:

| cmake_minimum_required(VERSION 3.5)
|
| project(hello VERSION 0.1 LANGUAGES CXX)
|
| add_custom_command(OUTPUT generated.cpp
|   COMMAND ${CMAKE_COMMAND} -E echo "int x;" >
${CMAKE_CURRENT_BINARY_DIR}/generated.cpp)
|
| add_custom_target(generate DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated.cpp)
|
| set_source_files_properties(
|   ${CMAKE_CURRENT_BINARY_DIR}/generated.cpp
|   PROPERTIES GENERATED 1)
|
| add_executable(program_a
|   main_a.cxx
|   ${CMAKE_CURRENT_BINARY_DIR}/generated.cpp
| )
| add_dependencies(program_a generate)
|
| add_executable(program_b
|   main_b.cxx
|   ${CMAKE_CURRENT_BINARY_DIR}/generated.cpp
| )
| add_dependencies(program_b program_a)
| add_dependencies(program_b generate)

In this case, the generated.cpp is generated in three project
generate, program_a and program_b.
program_a is built twice unnecessarily.

Another example of using add_custom_target:

| cmake_minimum_required(VERSION 3.5)
|
| project(hello VERSION 0.1 LANGUAGES CXX)
|
| add_custom_target(generate
|     COMMAND ${CMAKE_COMMAND} -E echo "int x;" >
${CMAKE_CURRENT_BINARY_DIR}/generated.cpp)
|
| set_source_files_properties(
|   ${CMAKE_CURRENT_BINARY_DIR}/generated.cpp
|   PROPERTIES GENERATED 1)
|
| add_executable(program_a
|   main_a.cxx
|   ${CMAKE_CURRENT_BINARY_DIR}/generated.add
| )
| cpp_dependencies(program_a generate)
|
| add_executable(program_b
|   main_b.cxx
|   ${CMAKE_CURRENT_BINARY_DIR}/generated.cpp
| )
| add_dependencies(program_b generate)
| add_dependencies(program_b program_a)

In this case, the generated.cpp is generated every time.

Is there a way to specify not to invoke the custom command in
program_a and program_b?
I'm using Visual Studio 2015.


More information about the CMake mailing list