Browse Source

Merge topic 'clarify-add_custom_command-TARGET-scope'

d257d681 add_custom_command: Clarify error when TARGET is out of scope (#15681)
4d53e0a7 Help: Clarify `add_custom_command(TARGET)` scope (#15681)
8c615af4 Help: Clarify policy `CMP0040` documentation (#15681)
63c5808f Help: Clarify scope of `if(TARGET)` expression
a336e438 Help: Improve markup in `if` command documentation
88968265 Help: Improve markup in `get_target_property` documentation
Brad King 9 years ago
parent
commit
c022b6f686

+ 5 - 2
Help/command/add_custom_command.rst

@@ -178,7 +178,7 @@ target is already built, the command will not execute.
 
 
 ::
 ::
 
 
-  add_custom_command(TARGET target
+  add_custom_command(TARGET <target>
                      PRE_BUILD | PRE_LINK | POST_BUILD
                      PRE_BUILD | PRE_LINK | POST_BUILD
                      COMMAND command1 [ARGS] [args1...]
                      COMMAND command1 [ARGS] [args1...]
                      [COMMAND command2 [ARGS] [args2...] ...]
                      [COMMAND command2 [ARGS] [args2...] ...]
@@ -188,7 +188,10 @@ target is already built, the command will not execute.
                      [VERBATIM] [USES_TERMINAL])
                      [VERBATIM] [USES_TERMINAL])
 
 
 This defines a new command that will be associated with building the
 This defines a new command that will be associated with building the
-specified target.  When the command will happen is determined by which
+specified ``<target>``.  The ``<target>`` must be defined in the current
+directory; targets defined in other directories may not be specified.
+
+When the command will happen is determined by which
 of the following is specified:
 of the following is specified:
 
 
 ``PRE_BUILD``
 ``PRE_BUILD``

+ 1 - 1
Help/command/get_target_property.rst

@@ -13,6 +13,6 @@ the variable ``VAR``.  If the property is not found, ``VAR`` will be set to
 Properties are usually used to control how a target is built, but some
 Properties are usually used to control how a target is built, but some
 query the target instead.  This command can get properties for any
 query the target instead.  This command can get properties for any
 target so far created.  The targets do not need to be in the current
 target so far created.  The targets do not need to be in the current
-CMakeLists.txt file.
+``CMakeLists.txt`` file.
 
 
 See also the more general :command:`get_property` command.
 See also the more general :command:`get_property` command.

+ 5 - 4
Help/command/if.rst

@@ -67,9 +67,10 @@ Possible expressions are:
  True if the given name is an existing policy (of the form ``CMP<NNNN>``).
  True if the given name is an existing policy (of the form ``CMP<NNNN>``).
 
 
 ``if(TARGET target-name)``
 ``if(TARGET target-name)``
- True if the given name is an existing logical target name such as those
- created by the :command:`add_executable`, :command:`add_library`, or
- :command:`add_custom_target` commands.
+ True if the given name is an existing logical target name created
+ by a call to the :command:`add_executable`, :command:`add_library`,
+ or :command:`add_custom_target` command that has already been invoked
+ (in any directory).
 
 
 ``if(TEST test-name)``
 ``if(TEST test-name)``
  True if the given name is an existing test name created by the
  True if the given name is an existing test name created by the
@@ -80,7 +81,7 @@ Possible expressions are:
  only for full paths.
  only for full paths.
 
 
 ``if(file1 IS_NEWER_THAN file2)``
 ``if(file1 IS_NEWER_THAN file2)``
- True if file1 is newer than file2 or if one of the two files doesn't
+ True if ``file1`` is newer than ``file2`` or if one of the two files doesn't
  exist.  Behavior is well-defined only for full paths.  If the file
  exist.  Behavior is well-defined only for full paths.  If the file
  time stamps are exactly the same, an ``IS_NEWER_THAN`` comparison returns
  time stamps are exactly the same, an ``IS_NEWER_THAN`` comparison returns
  true, so that any dependent build operations will occur in the event
  true, so that any dependent build operations will occur in the event

+ 11 - 8
Help/policy/CMP0040.rst

@@ -1,18 +1,21 @@
 CMP0040
 CMP0040
 -------
 -------
 
 
-The target in the TARGET signature of add_custom_command() must exist.
+The target in the ``TARGET`` signature of :command:`add_custom_command`
+must exist and must be defined in current directory.
 
 
 CMake 2.8.12 and lower silently ignored a custom command created with
 CMake 2.8.12 and lower silently ignored a custom command created with
-the TARGET signature of :command:`add_custom_command`
-if the target is unknown.
+the ``TARGET`` signature of :command:`add_custom_command`
+if the target is unknown or was defined outside the current directory.
 
 
-The OLD behavior for this policy is to ignore custom commands
-for unknown targets. The NEW behavior for this policy is to report an error
-if the target referenced in :command:`add_custom_command` is unknown.
+The ``OLD`` behavior for this policy is to ignore custom commands
+for unknown targets.  The ``NEW`` behavior for this policy is to report
+an error if the target referenced in :command:`add_custom_command` is
+unknown or was defined outside the current directory.
 
 
 This policy was introduced in CMake version 3.0.  CMake version
 This policy was introduced in CMake version 3.0.  CMake version
-|release| warns when the policy is not set and uses OLD behavior.  Use
-the cmake_policy command to set it to OLD or NEW explicitly.
+|release| warns when the policy is not set and uses ``OLD`` behavior.
+Use the :command:`cmake_policy` command to set it to ``OLD`` or
+``NEW`` explicitly.
 
 
 .. include:: DEPRECATED.txt
 .. include:: DEPRECATED.txt

+ 18 - 1
Source/cmMakefile.cxx

@@ -791,7 +791,24 @@ cmMakefile::AddCustomCommandToTarget(const std::string& target,
 
 
     if(issueMessage)
     if(issueMessage)
       {
       {
-      e << "The target name \"" << target << "\" is unknown in this context.";
+      if (cmTarget const* t = this->FindTargetToUse(target))
+        {
+        if (t->IsImported())
+          {
+          e << "TARGET '" << target
+            << "' is IMPORTED and does not build here.";
+          }
+        else
+          {
+          e << "TARGET '" << target
+            << "' was not created in this directory.";
+          }
+        }
+      else
+        {
+        e << "No TARGET '" << target
+          << "' has been created in this directory.";
+        }
       IssueMessage(messageType, e.str());
       IssueMessage(messageType, e.str());
       }
       }
 
 

+ 1 - 1
Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-stderr.txt

@@ -1,4 +1,4 @@
 CMake Error at CMP0040-NEW-missing-target.cmake:3 \(add_custom_command\):
 CMake Error at CMP0040-NEW-missing-target.cmake:3 \(add_custom_command\):
-  The target name "foobar" is unknown in this context.
+  No TARGET 'foobar' has been created in this directory.
 Call Stack \(most recent call first\):
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
   CMakeLists.txt:3 \(include\)

+ 1 - 1
Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-stderr.txt

@@ -4,7 +4,7 @@ CMake Warning \(dev\) at CMP0040-WARN-missing-target.cmake:2 \(add_custom_comman
   policy details.  Use the cmake_policy command to set the policy and
   policy details.  Use the cmake_policy command to set the policy and
   suppress this warning.
   suppress this warning.
 +
 +
-  The target name "foobar" is unknown in this context.
+  No TARGET 'foobar' has been created in this directory.
 Call Stack \(most recent call first\):
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
   CMakeLists.txt:3 \(include\)
 This warning is for project developers.  Use -Wno-dev to suppress it.
 This warning is for project developers.  Use -Wno-dev to suppress it.

+ 2 - 0
Tests/RunCMake/add_custom_command/RunCMakeTest.cmake

@@ -8,3 +8,5 @@ run_cmake(NoOutputOrTarget)
 run_cmake(OutputAndTarget)
 run_cmake(OutputAndTarget)
 run_cmake(SourceByproducts)
 run_cmake(SourceByproducts)
 run_cmake(SourceUsesTerminal)
 run_cmake(SourceUsesTerminal)
+run_cmake(TargetImported)
+run_cmake(TargetNotInDir)

+ 1 - 0
Tests/RunCMake/add_custom_command/TargetImported-result.txt

@@ -0,0 +1 @@
+1

+ 4 - 0
Tests/RunCMake/add_custom_command/TargetImported-stderr.txt

@@ -0,0 +1,4 @@
+^CMake Error at TargetImported.cmake:2 \(add_custom_command\):
+  TARGET 'TargetImported' is IMPORTED and does not build here.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 2 - 0
Tests/RunCMake/add_custom_command/TargetImported.cmake

@@ -0,0 +1,2 @@
+add_library(TargetImported UNKNOWN IMPORTED)
+add_custom_command(TARGET TargetImported COMMAND ${CMAKE_COMMAND} -E echo tada)

+ 1 - 0
Tests/RunCMake/add_custom_command/TargetNotInDir-result.txt

@@ -0,0 +1 @@
+1

+ 4 - 0
Tests/RunCMake/add_custom_command/TargetNotInDir-stderr.txt

@@ -0,0 +1,4 @@
+^CMake Error at TargetNotInDir.cmake:2 \(add_custom_command\):
+  TARGET 'TargetNotInDir' was not created in this directory.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 2 - 0
Tests/RunCMake/add_custom_command/TargetNotInDir.cmake

@@ -0,0 +1,2 @@
+add_subdirectory(TargetNotInDir)
+add_custom_command(TARGET TargetNotInDir COMMAND ${CMAKE_COMMAND} -E echo tada)

+ 1 - 0
Tests/RunCMake/add_custom_command/TargetNotInDir/CMakeLists.txt

@@ -0,0 +1 @@
+add_custom_target(TargetNotInDir)