MantisBT - CMake
View Issue Details
0015681CMakeCMakepublic2015-08-04 17:182016-06-10 14:21
Dan Liew 
Brad King 
normalmajoralways
closedfixed 
LinuxArch Linux
CMake 3.2.3 
CMake 3.5CMake 3.5 
0015681: Clarify why add_custom_command(TARGET ...) can't see in scope target
'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 [^]
$ 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
No tags attached.
patch 0001-Distinguish-between-warnings-when-target-is-not-exis.patch (5,606) 2016-01-28 04:57
https://public.kitware.com/Bug/file/5617/0001-Distinguish-between-warnings-when-target-is-not-exis.patch
Issue History
2015-08-04 17:18Dan LiewNew Issue
2016-01-27 09:28BartoszNote Added: 0040329
2016-01-27 09:32Brad KingNote Added: 0040330
2016-01-27 09:36Brad KingNote Added: 0040331
2016-01-27 10:55BartoszNote Added: 0040333
2016-01-27 11:06BartoszNote Added: 0040334
2016-01-27 11:13BartoszNote Added: 0040335
2016-01-27 11:15Brad KingNote Added: 0040336
2016-01-28 04:57BartoszFile Added: 0001-Distinguish-between-warnings-when-target-is-not-exis.patch
2016-01-28 04:59BartoszNote Added: 0040337
2016-01-28 10:38Brad KingNote Added: 0040350
2016-01-28 10:39Brad KingAssigned To => Brad King
2016-01-28 10:39Brad KingStatusnew => resolved
2016-01-28 10:39Brad KingResolutionopen => fixed
2016-01-28 10:39Brad KingFixed in Version => CMake 3.5
2016-01-28 10:39Brad KingTarget Version => CMake 3.5
2016-01-28 10:39Brad KingSummaryadd_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:21Kitware RobotNote Added: 0041273
2016-06-10 14:21Kitware RobotStatusresolved => closed

Notes
(0040329)
Bartosz   
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   
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   
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   
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   
2016-01-27 11:06   
Similar issue on mailing list:
https://cmake.org/pipermail/cmake/2014-August/058359.html [^]
(0040335)
Bartosz   
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   
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   
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   
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   
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.