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.
-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake

Reply via email to