View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0015844CMakeCMakepublic2015-11-11 15:042016-05-02 08:30
ReporterРоман Донченко 
Assigned To 
PrioritynormalSeverityminorReproducibilityalways
StatusclosedResolutionno change required 
PlatformOSOS Version
Product VersionCMake 3.3.2 
Target VersionFixed in Version 
Summary0015844: Custom command executing for file the target doesn't depend on
DescriptionIf 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.
Steps To ReproduceCreate 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.
TagsNo tags attached.
Attached Files

 Relationships

  Notes
(0039866)
Brad King (manager)
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)
Роман Донченко (reporter)
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 (manager)
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 (manager)
2016-05-02 08:30

Closing resolved issues that have not been updated in more than 4 months.

 Issue History
Date Modified Username Field Change
2015-11-11 15:04 Роман Донченко New Issue
2015-11-11 15:21 Brad King Note Added: 0039866
2015-11-11 15:21 Brad King Status new => resolved
2015-11-11 15:21 Brad King Resolution open => no change required
2015-11-16 14:16 Роман Донченко Note Added: 0039874
2015-11-16 14:34 Brad King Note Added: 0039875
2016-05-02 08:30 Robert Maynard Note Added: 0040961
2016-05-02 08:30 Robert Maynard Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team