View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0015681CMakeCMakepublic2015-08-04 17:182016-06-10 14:21
ReporterDan Liew 
Assigned ToBrad King 
PrioritynormalSeveritymajorReproducibilityalways
StatusclosedResolutionfixed 
PlatformLinuxOSArch LinuxOS Version
Product VersionCMake 3.2.3 
Target VersionCMake 3.5Fixed in VersionCMake 3.5 
Summary0015681: Clarify why add_custom_command(TARGET ...) can't see in scope target
Description'm observing a problem with CMake's add_custom_command() when using
the TARGET version of the signature.

Code demonstrating the issue can be found at [1]

In ``test/CMakeLists.txt`` [2] I try using add_custom_command() to
build and run an executable every time the ``foolib`` library is
rebuilt. The motivation behind doing this is to have some very quick
and simple library tests run every time the library is built.

This use of add_custom_command() does not seem to work at all.

Using CMake 2.8.12.2 the requested command is not invoked when running
``make foolib``. I am aware that the custom command won't run if
``foolib`` has already been made but even if I do a clean build the
custom command specified does not run.

When using CMake 3.2.3 I get a warning about CMP0040 which complains
that the target passed to the TARGET argument in
``add_custom_command()`` doesn't exist.

```
  Policy CMP0040 is not set: The target in the TARGET signature of
  add_custom_command() must exist. Run "cmake --help-policy CMP0040" for
  policy details. Use the cmake_policy command to set the policy and
  suppress this warning.

  The target name "foolib" is unknown in this context.
This warning is for project developers. Use -Wno-dev to suppress it
```


This doesn't make sense the target **clearly exists and is in scope**
because the ``simple_test`` executable links against it and also it is
possible to read properties of the target.

Seems like there's some sort of weird scope issue going on here.


[1] https://github.com/delcypher/cmake_add_custom_command_bug [^]
[2] https://github.com/delcypher/cmake_add_custom_command_bug/blob/master/test/CMakeLists.txt [^]
Steps To Reproduce$ git clone https://github.com/delcypher/cmake_add_custom_command_bug.git [^]
$ cd cmake_add_custom_command_bug
$ mkdir build
$ cd build
# Under new versions of CMake a warning is emitted about the "foolib" target not being known in this context
$ cmake ../

$ make foolib VERBOSE=1

you will see that none of the custom commands are executed
TagsNo tags attached.
Attached Filespatch file icon 0001-Distinguish-between-warnings-when-target-is-not-exis.patch [^] (5,606 bytes) 2016-01-28 04:57 [Show Content]

 Relationships

  Notes
(0040329)
Bartosz (reporter)
2016-01-27 09:28

Hello Dan.
I have also the same issue.
As you already mention, it is especially visible, when you enable CMP0040 to NEW.

Did you found some workaround for that issue?
(0040330)
Brad King (manager)
2016-01-27 09:32

For reference, the sample code linked in the description is:

--------------------------------------------------------------------
add_executable(simple_test simple.cpp)
target_link_libraries(simple_test PRIVATE foolib)

# FIXME: This seems like a bug in CMake, this custom
# command does not fire when foolib gets built
# Tried with 2.8.12.2
#
# With CMake 3.2.3 I get a warning about CMP0040
# (target in the TARGET of signature of add_custom_command()
# must exist).
#
# This doesn't make sense since we can read properties of the foolib target so
# it MUST EXIST!!!
add_custom_command(TARGET foolib
                   POST_BUILD
                   COMMAND echo XXXXXXXX
                   COMMAND simple_test
                   COMMENT "Running simple_test")

# Demonstrate that the foolib target does exist in this scope!
get_target_property(foolib_loc foolib LOCATION)

message(STATUS "The reported location of the foolib target is ${foolib_loc}")
--------------------------------------------------------------------
(0040331)
Brad King (manager)
2016-01-27 09:36

The "foolib" target does exist and is globally visible for some commands, but add_custom_command(TARGET) is willing to look only for targets defined in the current directory. The implementation is here:

 https://cmake.org/gitweb?p=cmake.git;a=blob;f=Source/cmMakefile.cxx;hb=v3.4.3#l778 [^]

The "this->Targets" member of cmMakefile holds only the targets defined with add_executable, add_library, or add_custom_target calls in the current CMakeLists.txt file.
(0040333)
Bartosz (reporter)
2016-01-27 10:55

Thanks Brad.
I think the CMP0040 warning is not a problem, but only shows the issue with add_custom_command()

Do you think it is possible to make add_custom_command(TARGET) to look target also from other directories, without impacting performance?

Or maybe we should not allow such usage ? Eg. We should update documentation and state that add_custom_command(TARGET) should be used with declaration of target. Then also "if(TARGET <TARGETNAME>)" should be updated to detect such case.

Unfortunately I cannot detect such issues, because if(TARGET <TARGETNAME>) is always returns TRUE in that case.

For example following code, doesn't make any difference:

--------------------------------------------------------
add_executable(simple_test simple.cpp)
target_link_libraries(simple_test PRIVATE foolib)

# FIXME: This seems like a bug in CMake, this custom
# command does not fire when foolib gets built
# Tried with 2.8.12.2
#
# With CMake 3.2.3 I get a warning about CMP0040
# (target in the TARGET of signature of add_custom_command()
# must exist).
#
# This doesn't make sense since we can read properties of the foolib target so
# it MUST EXIST!!!

if(TARGET foolib)
add_custom_command(TARGET foolib
                   POST_BUILD
                   COMMAND echo XXXXXXXX
                   COMMAND simple_test
                   COMMENT "Running simple_test")
endif()

# Demonstrate that the foolib target does exist in this scope!
get_target_property(foolib_loc foolib LOCATION)


message(STATUS "The reported location of the foolib target is ${foolib_loc}")
------------------------------------------------------------------
(0040334)
Bartosz (reporter)
2016-01-27 11:06

Similar issue on mailing list:
https://cmake.org/pipermail/cmake/2014-August/058359.html [^]
(0040335)
Bartosz (reporter)
2016-01-27 11:13

in get_target_property() the method:
 this->Makefile->FindTargetToUse(targetName))

is used.

https://cmake.org/gitweb?p=cmake.git;a=blob;f=Source/cmGetTargetPropertyCommand.cxx;hb=v3.4.3#l33 [^]

Maybe we could use the same method for add_executable, add_library, or add_custom_target ?
(0040336)
Brad King (manager)
2016-01-27 11:15

Re 0015681:0040333:

> Do you think it is possible to make add_custom_command(TARGET) to look target also from other directories, without impacting performance?

I doubt it would have any noticable impact on performance, but that is not the reason. The original idea is that the build rules for a target should be contained in the code within the directory defining the target.

Perhaps we can clarify this by improving the error message and documentation.
(0040337)
Bartosz (reporter)
2016-01-28 04:59

With attached patch I distinguish when target is not existing at all, from when target is existing, but it is not defined in current directory.

What will happen when we will add "add_custom_command" into function?
(0040350)
Brad King (manager)
2016-01-28 10:38

Thanks for working on a patch. I've split it out into several commits for the documentation updates:

 Help: Improve markup in `get_target_property` documentation
 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=88968265 [^]

 Help: Improve markup in `if` command documentation
 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a336e438 [^]

 Help: Clarify scope of `if(TARGET)` expression
 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=63c5808f [^]

 Help: Clarify policy `CMP0040` documentation
 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8c615af4 [^]

 Help: Clarify `add_custom_command(TARGET)` scope
 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4d53e0a7 [^]

Then I re-wrote the error message update and added test cases:

 add_custom_command: Clarify error when TARGET is out of scope
 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d257d681 [^]
(0041273)
Kitware Robot (administrator)
2016-06-10 14:21

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.

 Issue History
Date Modified Username Field Change
2015-08-04 17:18 Dan Liew New Issue
2016-01-27 09:28 Bartosz Note Added: 0040329
2016-01-27 09:32 Brad King Note Added: 0040330
2016-01-27 09:36 Brad King Note Added: 0040331
2016-01-27 10:55 Bartosz Note Added: 0040333
2016-01-27 11:06 Bartosz Note Added: 0040334
2016-01-27 11:13 Bartosz Note Added: 0040335
2016-01-27 11:15 Brad King Note Added: 0040336
2016-01-28 04:57 Bartosz File Added: 0001-Distinguish-between-warnings-when-target-is-not-exis.patch
2016-01-28 04:59 Bartosz Note Added: 0040337
2016-01-28 10:38 Brad King Note Added: 0040350
2016-01-28 10:39 Brad King Assigned To => Brad King
2016-01-28 10:39 Brad King Status new => resolved
2016-01-28 10:39 Brad King Resolution open => fixed
2016-01-28 10:39 Brad King Fixed in Version => CMake 3.5
2016-01-28 10:39 Brad King Target Version => CMake 3.5
2016-01-28 10:39 Brad King Summary add_custom_command(TARGET ...) can't see in scope target => Clarify why add_custom_command(TARGET ...) can't see in scope target
2016-06-10 14:21 Kitware Robot Note Added: 0041273
2016-06-10 14:21 Kitware Robot Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team