MantisBT - CMake
View Issue Details
0015844CMakeCMakepublic2015-11-11 15:042016-05-02 08:30
Роман Донченко 
 
normalminoralways
closedno change required 
CMake 3.3.2 
 
0015844: Custom command executing for file the target doesn't depend on
If two targets have the same sources, it's possible for one of them to execute a custom command for a file that it doesn't depend on.
Create foo1.txt and foo2.txt with any contents and the following CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)

set(S "${CMAKE_CURRENT_SOURCE_DIR}")
set(B "${CMAKE_CURRENT_BINARY_DIR}")

add_custom_command(OUTPUT bar1.txt
                   COMMAND "${CMAKE_COMMAND}" -E md5sum
                       "${S}/foo1.txt" "${S}/foo2.txt" > "${B}/bar1.txt"
                   MAIN_DEPENDENCY "${S}/foo1.txt"
                   DEPENDS "${S}/foo2.txt"
                   VERBATIM)

add_custom_target(bar1 DEPENDS "${B}/bar1.txt"
                  SOURCES "${S}/foo1.txt" "${S}/foo2.txt")

add_custom_command(OUTPUT bar2.txt
                   COMMAND "${CMAKE_COMMAND}" -E md5sum
                       "${S}/foo2.txt" "${S}/foo1.txt" > "${B}/bar2.txt"
                   MAIN_DEPENDENCY "${S}/foo2.txt"
                   DEPENDS "${S}/foo1.txt"
                   VERBATIM)

add_custom_target(bar2 DEPENDS "${B}/bar2.txt"
                  SOURCES "${S}/foo1.txt" "${S}/foo2.txt")

Now:

$ /opt/cmake-3.3.2/bin/cmake /source/dir
[...]
-- Build files have been written to: /build/dir
$ make bar1
Scanning dependencies of target bar1
[ 50%] Generating bar1.txt
[100%] Generating bar2.txt
[100%] Built target bar1

Even though bar1 doesn't depend on bar2.txt, it gets generated anyway. Similarly, if you make bar2, it will generate bar1.txt.
No tags attached.
Issue History
2015-11-11 15:04Роман ДонченкоNew Issue
2015-11-11 15:21Brad KingNote Added: 0039866
2015-11-11 15:21Brad KingStatusnew => resolved
2015-11-11 15:21Brad KingResolutionopen => no change required
2015-11-16 14:16Роман ДонченкоNote Added: 0039874
2015-11-16 14:34Brad KingNote Added: 0039875
2016-05-02 08:30Robert MaynardNote Added: 0040961
2016-05-02 08:30Robert MaynardStatusresolved => closed

Notes
(0039866)
Brad King   
2015-11-11 15:21   
The MAIN_DEPENDENCY option explicitly attaches the custom command to the specified source file. If you list that source file in a target then the custom command will be built as part of that target. This comes from the VS IDE project file model of custom commands being attached to sources (inputs) rather than outputs. The purpose of MAIN_DEPENDENCY is to specify this attachment.
(0039874)
Роман Донченко   
2015-11-16 14:16   
OK, thanks for the explanation. But why does the command get attached to the source file in every target? In VS, if you add the same source file to two projects, you can specify different commands in each. Or was that not always the case?
(0039875)
Brad King   
2015-11-16 14:34   
Re 0015844:0039874:

> why does the command get attached to the source file in every target?

At one time (long ago) in CMake each source was compiled only once even if it was used in multiple targets and the object file was re-used. Properties on source files are scoped at the directory level. Later we split compilation to be separate for each target, but custom commands are all still directory scoped.
(0040961)
Robert Maynard   
2016-05-02 08:30   
Closing resolved issues that have not been updated in more than 4 months.