Explorar o código

Teach target_* commands to set INTERFACE properties of IMPORTED targets

Now, several `INTERFACE_*` properties can be set on `IMPORTED` targets,
not only via `set_property` and `set_target_properties` but also via
`target_compile_definitions`, `target_compile_features`,
`target_compile_options`, `target_include_directories`, `target_sources`
and `target_link_libraries`.

Fixes: #15689
Issue: #17197
Deniz Bahadir %!s(int64=8) %!d(string=hai) anos
pai
achega
fe4b25ec2f
Modificáronse 28 ficheiros con 91 adicións e 95 borrados
  1. 4 3
      Help/command/target_compile_definitions.rst
  2. 5 4
      Help/command/target_compile_features.rst
  3. 7 4
      Help/command/target_compile_options.rst
  4. 4 4
      Help/command/target_include_directories.rst
  5. 2 1
      Help/command/target_link_libraries.rst
  6. 4 3
      Help/command/target_sources.rst
  7. 1 10
      Source/cmTargetCompileDefinitionsCommand.cxx
  8. 0 1
      Source/cmTargetCompileDefinitionsCommand.h
  9. 2 11
      Source/cmTargetCompileFeaturesCommand.cxx
  10. 0 1
      Source/cmTargetCompileFeaturesCommand.h
  11. 2 11
      Source/cmTargetCompileOptionsCommand.cxx
  12. 0 1
      Source/cmTargetCompileOptionsCommand.h
  13. 2 12
      Source/cmTargetIncludeDirectoriesCommand.cxx
  14. 0 1
      Source/cmTargetIncludeDirectoriesCommand.h
  15. 29 1
      Source/cmTargetLinkLibrariesCommand.cxx
  16. 4 6
      Source/cmTargetPropCommandBase.cxx
  17. 0 1
      Source/cmTargetPropCommandBase.h
  18. 1 8
      Source/cmTargetSourcesCommand.cxx
  19. 0 1
      Source/cmTargetSourcesCommand.h
  20. 0 5
      Tests/RunCMake/add_library/UNKNOWNwithNoSourcesButLinkObjects-stderr.txt
  21. 1 1
      Tests/RunCMake/add_library/UNKNOWNwithNoSourcesButLinkObjects.cmake
  22. 4 3
      Tests/RunCMake/target_compile_features/imported_target-stderr.txt
  23. 8 2
      Tests/RunCMake/target_compile_features/imported_target.cmake
  24. 2 0
      Tests/RunCMake/target_link_libraries/ImportedTarget.cmake
  25. 0 0
      Tests/RunCMake/target_link_libraries/ImportedTargetFailure-result.txt
  26. 5 0
      Tests/RunCMake/target_link_libraries/ImportedTargetFailure-stderr.txt
  27. 2 0
      Tests/RunCMake/target_link_libraries/ImportedTargetFailure.cmake
  28. 2 0
      Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake

+ 4 - 3
Help/command/target_compile_definitions.rst

@@ -12,14 +12,15 @@ Add compile definitions to a target.
 Specify compile definitions to use when compiling a given ``<target>``.  The
 Specify compile definitions to use when compiling a given ``<target>``.  The
 named ``<target>`` must have been created by a command such as
 named ``<target>`` must have been created by a command such as
 :command:`add_executable` or :command:`add_library` and must not be an
 :command:`add_executable` or :command:`add_library` and must not be an
-:ref:`Imported Target <Imported Targets>`.
+:ref:`ALIAS target <Alias Targets>`.
 
 
 The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
 The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
 specify the scope of the following arguments.  ``PRIVATE`` and ``PUBLIC``
 specify the scope of the following arguments.  ``PRIVATE`` and ``PUBLIC``
 items will populate the :prop_tgt:`COMPILE_DEFINITIONS` property of
 items will populate the :prop_tgt:`COMPILE_DEFINITIONS` property of
 ``<target>``. ``PUBLIC`` and ``INTERFACE`` items will populate the
 ``<target>``. ``PUBLIC`` and ``INTERFACE`` items will populate the
-:prop_tgt:`INTERFACE_COMPILE_DEFINITIONS` property of ``<target>``.  The
-following arguments specify compile definitions.  Repeated calls for the
+:prop_tgt:`INTERFACE_COMPILE_DEFINITIONS` property of ``<target>``.
+(:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.)
+The following arguments specify compile definitions.  Repeated calls for the
 same ``<target>`` append items in the order called.
 same ``<target>`` append items in the order called.
 
 
 Arguments to ``target_compile_definitions`` may use "generator expressions"
 Arguments to ``target_compile_definitions`` may use "generator expressions"

+ 5 - 4
Help/command/target_compile_features.rst

@@ -18,12 +18,13 @@ The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
 specify the scope of the features.  ``PRIVATE`` and ``PUBLIC`` items will
 specify the scope of the features.  ``PRIVATE`` and ``PUBLIC`` items will
 populate the :prop_tgt:`COMPILE_FEATURES` property of ``<target>``.
 populate the :prop_tgt:`COMPILE_FEATURES` property of ``<target>``.
 ``PUBLIC`` and ``INTERFACE`` items will populate the
 ``PUBLIC`` and ``INTERFACE`` items will populate the
-:prop_tgt:`INTERFACE_COMPILE_FEATURES` property of ``<target>``.  Repeated
-calls for the same ``<target>`` append items.
+:prop_tgt:`INTERFACE_COMPILE_FEATURES` property of ``<target>``.
+(:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.)
+Repeated calls for the same ``<target>`` append items.
 
 
 The named ``<target>`` must have been created by a command such as
 The named ``<target>`` must have been created by a command such as
-:command:`add_executable` or :command:`add_library` and must not be
-an ``IMPORTED`` target.
+:command:`add_executable` or :command:`add_library` and must not be an
+:ref:`ALIAS target <Alias Targets>`.
 
 
 Arguments to ``target_compile_features`` may use "generator expressions"
 Arguments to ``target_compile_features`` may use "generator expressions"
 with the syntax ``$<...>``.
 with the syntax ``$<...>``.

+ 7 - 4
Help/command/target_compile_options.rst

@@ -12,8 +12,10 @@ Add compile options to a target.
 Specify compile options to use when compiling a given target.  The
 Specify compile options to use when compiling a given target.  The
 named ``<target>`` must have been created by a command such as
 named ``<target>`` must have been created by a command such as
 :command:`add_executable` or :command:`add_library` and must not be an
 :command:`add_executable` or :command:`add_library` and must not be an
-:ref:`IMPORTED Target <Imported Targets>`.  If ``BEFORE`` is specified,
-the content will be prepended to the property instead of being appended.
+:ref:`ALIAS target <Alias Targets>`.
+
+If ``BEFORE`` is specified, the content will be prepended to the property
+instead of being appended.
 
 
 This command can be used to add any options, but
 This command can be used to add any options, but
 alternative commands exist to add preprocessor definitions
 alternative commands exist to add preprocessor definitions
@@ -27,8 +29,9 @@ The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
 specify the scope of the following arguments.  ``PRIVATE`` and ``PUBLIC``
 specify the scope of the following arguments.  ``PRIVATE`` and ``PUBLIC``
 items will populate the :prop_tgt:`COMPILE_OPTIONS` property of
 items will populate the :prop_tgt:`COMPILE_OPTIONS` property of
 ``<target>``.  ``PUBLIC`` and ``INTERFACE`` items will populate the
 ``<target>``.  ``PUBLIC`` and ``INTERFACE`` items will populate the
-:prop_tgt:`INTERFACE_COMPILE_OPTIONS` property of ``<target>``.  The
-following arguments specify compile options.  Repeated calls for the same
+:prop_tgt:`INTERFACE_COMPILE_OPTIONS` property of ``<target>``.
+(:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.)
+The following arguments specify compile options.  Repeated calls for the same
 ``<target>`` append items in the order called.
 ``<target>`` append items in the order called.
 
 
 Arguments to ``target_compile_options`` may use "generator expressions"
 Arguments to ``target_compile_options`` may use "generator expressions"

+ 4 - 4
Help/command/target_include_directories.rst

@@ -12,7 +12,7 @@ Add include directories to a target.
 Specify include directories to use when compiling a given target.
 Specify include directories to use when compiling a given target.
 The named ``<target>`` must have been created by a command such
 The named ``<target>`` must have been created by a command such
 as :command:`add_executable` or :command:`add_library` and must not be an
 as :command:`add_executable` or :command:`add_library` and must not be an
-:prop_tgt:`IMPORTED` target.
+:ref:`ALIAS target <Alias Targets>`.
 
 
 If ``BEFORE`` is specified, the content will be prepended to the property
 If ``BEFORE`` is specified, the content will be prepended to the property
 instead of being appended.
 instead of being appended.
@@ -21,9 +21,9 @@ The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to specify
 the scope of the following arguments.  ``PRIVATE`` and ``PUBLIC`` items will
 the scope of the following arguments.  ``PRIVATE`` and ``PUBLIC`` items will
 populate the :prop_tgt:`INCLUDE_DIRECTORIES` property of ``<target>``.
 populate the :prop_tgt:`INCLUDE_DIRECTORIES` property of ``<target>``.
 ``PUBLIC`` and ``INTERFACE`` items will populate the
 ``PUBLIC`` and ``INTERFACE`` items will populate the
-:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`
-property of ``<target>``.  The following arguments specify include
-directories.
+:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` property of ``<target>``.
+(:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.)
+The following arguments specify include directories.
 
 
 Specified include directories may be absolute paths or relative paths.
 Specified include directories may be absolute paths or relative paths.
 Repeated calls for the same <target> append items in the order called.  If
 Repeated calls for the same <target> append items in the order called.  If

+ 2 - 1
Help/command/target_link_libraries.rst

@@ -19,7 +19,8 @@ All of them have the general form::
   target_link_libraries(<target> ... <item>... ...)
   target_link_libraries(<target> ... <item>... ...)
 
 
 The named ``<target>`` must have been created in the current directory by
 The named ``<target>`` must have been created in the current directory by
-a command such as :command:`add_executable` or :command:`add_library`.
+a command such as :command:`add_executable` or :command:`add_library` and
+must not be an :ref:`ALIAS target <Alias Targets>`.
 Repeated calls for the same ``<target>`` append items in the order called.
 Repeated calls for the same ``<target>`` append items in the order called.
 Each ``<item>`` may be:
 Each ``<item>`` may be:
 
 

+ 4 - 3
Help/command/target_sources.rst

@@ -12,14 +12,15 @@ Add sources to a target.
 Specify sources to use when compiling a given target.  The
 Specify sources to use when compiling a given target.  The
 named ``<target>`` must have been created by a command such as
 named ``<target>`` must have been created by a command such as
 :command:`add_executable` or :command:`add_library` and must not be an
 :command:`add_executable` or :command:`add_library` and must not be an
-:ref:`IMPORTED Target <Imported Targets>`.
+:ref:`ALIAS target <Alias Targets>`.
 
 
 The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
 The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
 specify the scope of the following arguments.  ``PRIVATE`` and ``PUBLIC``
 specify the scope of the following arguments.  ``PRIVATE`` and ``PUBLIC``
 items will populate the :prop_tgt:`SOURCES` property of
 items will populate the :prop_tgt:`SOURCES` property of
 ``<target>``.  ``PUBLIC`` and ``INTERFACE`` items will populate the
 ``<target>``.  ``PUBLIC`` and ``INTERFACE`` items will populate the
-:prop_tgt:`INTERFACE_SOURCES` property of ``<target>``.  The
-following arguments specify sources.  Repeated calls for the same
+:prop_tgt:`INTERFACE_SOURCES` property of ``<target>``.
+(:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.)
+The following arguments specify sources.  Repeated calls for the same
 ``<target>`` append items in the order called.
 ``<target>`` append items in the order called.
 
 
 Arguments to ``target_sources`` may use "generator expressions"
 Arguments to ``target_sources`` may use "generator expressions"

+ 1 - 10
Source/cmTargetCompileDefinitionsCommand.cxx

@@ -17,15 +17,6 @@ bool cmTargetCompileDefinitionsCommand::InitialPass(
   return this->HandleArguments(args, "COMPILE_DEFINITIONS");
   return this->HandleArguments(args, "COMPILE_DEFINITIONS");
 }
 }
 
 
-void cmTargetCompileDefinitionsCommand::HandleImportedTarget(
-  const std::string& tgt)
-{
-  std::ostringstream e;
-  e << "Cannot specify compile definitions for imported target \"" << tgt
-    << "\".";
-  this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
-}
-
 void cmTargetCompileDefinitionsCommand::HandleMissingTarget(
 void cmTargetCompileDefinitionsCommand::HandleMissingTarget(
   const std::string& name)
   const std::string& name)
 {
 {
@@ -56,5 +47,5 @@ bool cmTargetCompileDefinitionsCommand::HandleDirectContent(
   cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
   cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
 {
 {
   tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content).c_str());
   tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content).c_str());
-  return true;
+  return true; // Successfully handled.
 }
 }

+ 0 - 1
Source/cmTargetCompileDefinitionsCommand.h

@@ -30,7 +30,6 @@ public:
                    cmExecutionStatus& status) override;
                    cmExecutionStatus& status) override;
 
 
 private:
 private:
-  void HandleImportedTarget(const std::string& tgt) override;
   void HandleMissingTarget(const std::string& name) override;
   void HandleMissingTarget(const std::string& name) override;
 
 
   bool HandleDirectContent(cmTarget* tgt,
   bool HandleDirectContent(cmTarget* tgt,

+ 2 - 11
Source/cmTargetCompileFeaturesCommand.cxx

@@ -17,15 +17,6 @@ bool cmTargetCompileFeaturesCommand::InitialPass(
   return this->HandleArguments(args, "COMPILE_FEATURES", NO_FLAGS);
   return this->HandleArguments(args, "COMPILE_FEATURES", NO_FLAGS);
 }
 }
 
 
-void cmTargetCompileFeaturesCommand::HandleImportedTarget(
-  const std::string& tgt)
-{
-  std::ostringstream e;
-  e << "Cannot specify compile features for imported target \"" << tgt
-    << "\".";
-  this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
-}
-
 void cmTargetCompileFeaturesCommand::HandleMissingTarget(
 void cmTargetCompileFeaturesCommand::HandleMissingTarget(
   const std::string& name)
   const std::string& name)
 {
 {
@@ -49,8 +40,8 @@ bool cmTargetCompileFeaturesCommand::HandleDirectContent(
     std::string error;
     std::string error;
     if (!this->Makefile->AddRequiredTargetFeature(tgt, it, &error)) {
     if (!this->Makefile->AddRequiredTargetFeature(tgt, it, &error)) {
       this->SetError(error);
       this->SetError(error);
-      return false;
+      return false; // Not (successfully) handled.
     }
     }
   }
   }
-  return true;
+  return true; // Successfully handled.
 }
 }

+ 0 - 1
Source/cmTargetCompileFeaturesCommand.h

@@ -22,7 +22,6 @@ class cmTargetCompileFeaturesCommand : public cmTargetPropCommandBase
                    cmExecutionStatus& status) override;
                    cmExecutionStatus& status) override;
 
 
 private:
 private:
-  void HandleImportedTarget(const std::string& tgt) override;
   void HandleMissingTarget(const std::string& name) override;
   void HandleMissingTarget(const std::string& name) override;
 
 
   bool HandleDirectContent(cmTarget* tgt,
   bool HandleDirectContent(cmTarget* tgt,

+ 2 - 11
Source/cmTargetCompileOptionsCommand.cxx

@@ -18,21 +18,12 @@ bool cmTargetCompileOptionsCommand::InitialPass(
   return this->HandleArguments(args, "COMPILE_OPTIONS", PROCESS_BEFORE);
   return this->HandleArguments(args, "COMPILE_OPTIONS", PROCESS_BEFORE);
 }
 }
 
 
-void cmTargetCompileOptionsCommand::HandleImportedTarget(
-  const std::string& tgt)
-{
-  std::ostringstream e;
-  e << "Cannot specify compile options for imported target \"" << tgt << "\".";
-  this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
-}
-
 void cmTargetCompileOptionsCommand::HandleMissingTarget(
 void cmTargetCompileOptionsCommand::HandleMissingTarget(
   const std::string& name)
   const std::string& name)
 {
 {
   std::ostringstream e;
   std::ostringstream e;
   e << "Cannot specify compile options for target \"" << name
   e << "Cannot specify compile options for target \"" << name
-    << "\" "
-       "which is not built by this project.";
+    << "\" which is not built by this project.";
   this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
   this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
 }
 }
 
 
@@ -47,5 +38,5 @@ bool cmTargetCompileOptionsCommand::HandleDirectContent(
 {
 {
   cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
   cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
   tgt->InsertCompileOption(this->Join(content), lfbt);
   tgt->InsertCompileOption(this->Join(content), lfbt);
-  return true;
+  return true; // Successfully handled.
 }
 }

+ 0 - 1
Source/cmTargetCompileOptionsCommand.h

@@ -30,7 +30,6 @@ public:
                    cmExecutionStatus& status) override;
                    cmExecutionStatus& status) override;
 
 
 private:
 private:
-  void HandleImportedTarget(const std::string& tgt) override;
   void HandleMissingTarget(const std::string& name) override;
   void HandleMissingTarget(const std::string& name) override;
 
 
   bool HandleDirectContent(cmTarget* tgt,
   bool HandleDirectContent(cmTarget* tgt,

+ 2 - 12
Source/cmTargetIncludeDirectoriesCommand.cxx

@@ -21,22 +21,12 @@ bool cmTargetIncludeDirectoriesCommand::InitialPass(
                                ArgumentFlags(PROCESS_BEFORE | PROCESS_SYSTEM));
                                ArgumentFlags(PROCESS_BEFORE | PROCESS_SYSTEM));
 }
 }
 
 
-void cmTargetIncludeDirectoriesCommand::HandleImportedTarget(
-  const std::string& tgt)
-{
-  std::ostringstream e;
-  e << "Cannot specify include directories for imported target \"" << tgt
-    << "\".";
-  this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
-}
-
 void cmTargetIncludeDirectoriesCommand::HandleMissingTarget(
 void cmTargetIncludeDirectoriesCommand::HandleMissingTarget(
   const std::string& name)
   const std::string& name)
 {
 {
   std::ostringstream e;
   std::ostringstream e;
   e << "Cannot specify include directories for target \"" << name
   e << "Cannot specify include directories for target \"" << name
-    << "\" "
-       "which is not built by this project.";
+    << "\" which is not built by this project.";
   this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
   this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
 }
 }
 
 
@@ -79,7 +69,7 @@ bool cmTargetIncludeDirectoriesCommand::HandleDirectContent(
     }
     }
     tgt->AddSystemIncludeDirectories(sdirs);
     tgt->AddSystemIncludeDirectories(sdirs);
   }
   }
-  return true;
+  return true; // Successfully handled.
 }
 }
 
 
 void cmTargetIncludeDirectoriesCommand::HandleInterfaceContent(
 void cmTargetIncludeDirectoriesCommand::HandleInterfaceContent(

+ 0 - 1
Source/cmTargetIncludeDirectoriesCommand.h

@@ -30,7 +30,6 @@ public:
                    cmExecutionStatus& status) override;
                    cmExecutionStatus& status) override;
 
 
 private:
 private:
-  void HandleImportedTarget(const std::string& tgt) override;
   void HandleMissingTarget(const std::string& name) override;
   void HandleMissingTarget(const std::string& name) override;
 
 
   bool HandleDirectContent(cmTarget* tgt,
   bool HandleDirectContent(cmTarget* tgt,

+ 29 - 1
Source/cmTargetLinkLibrariesCommand.cxx

@@ -39,6 +39,16 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
   this->Target =
   this->Target =
     this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(
     this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(
       args[0]);
       args[0]);
+  if (!this->Target) {
+    const std::vector<cmTarget*>& importedTargets =
+      this->Makefile->GetOwnedImportedTargets();
+    for (cmTarget* importedTarget : importedTargets) {
+      if (importedTarget->GetName() == args[0]) {
+        this->Target = importedTarget;
+        break;
+      }
+    }
+  }
   if (!this->Target) {
   if (!this->Target) {
     cmake::MessageType t = cmake::FATAL_ERROR; // fail by default
     cmake::MessageType t = cmake::FATAL_ERROR; // fail by default
     std::ostringstream e;
     std::ostringstream e;
@@ -228,7 +238,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
     } else {
     } else {
       // Lookup old-style cache entry if type is unspecified.  So if you
       // Lookup old-style cache entry if type is unspecified.  So if you
       // do a target_link_libraries(foo optimized bar) it will stay optimized
       // do a target_link_libraries(foo optimized bar) it will stay optimized
-      // and not use the lookup.  As there maybe the case where someone has
+      // and not use the lookup.  As there may be the case where someone has
       // specifed that a library is both debug and optimized.  (this check is
       // specifed that a library is both debug and optimized.  (this check is
       // only there for backwards compatibility when mixing projects built
       // only there for backwards compatibility when mixing projects built
       // with old versions of CMake and new)
       // with old versions of CMake and new)
@@ -299,6 +309,14 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
       "target_link_libraries");
       "target_link_libraries");
     return false;
     return false;
   }
   }
+  if (this->Target->IsImported() &&
+      this->CurrentProcessingState != ProcessingKeywordLinkInterface) {
+    this->Makefile->IssueMessage(
+      cmake::FATAL_ERROR,
+      "IMPORTED library can only be used with the INTERFACE keyword of "
+      "target_link_libraries");
+    return false;
+  }
 
 
   cmTarget::TLLSignature sig =
   cmTarget::TLLSignature sig =
     (this->CurrentProcessingState == ProcessingPlainPrivateInterface ||
     (this->CurrentProcessingState == ProcessingPlainPrivateInterface ||
@@ -354,6 +372,16 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
 
 
     cmTarget* t =
     cmTarget* t =
       this->Makefile->FindLocalNonAliasTarget(this->Target->GetName());
       this->Makefile->FindLocalNonAliasTarget(this->Target->GetName());
+    if (!t) {
+      const std::vector<cmTarget*>& importedTargets =
+        this->Makefile->GetOwnedImportedTargets();
+      for (cmTarget* importedTarget : importedTargets) {
+        if (importedTarget->GetName() == this->Target->GetName()) {
+          t = importedTarget;
+          break;
+        }
+      }
+    }
     if (!t) {
     if (!t) {
       std::ostringstream e;
       std::ostringstream e;
       e << "Attempt to add link library \"" << lib << "\" to target \""
       e << "Attempt to add link library \"" << lib << "\" to target \""

+ 4 - 6
Source/cmTargetPropCommandBase.cxx

@@ -84,17 +84,15 @@ bool cmTargetPropCommandBase::ProcessContentArgs(
     this->SetError("called with invalid arguments");
     this->SetError("called with invalid arguments");
     return false;
     return false;
   }
   }
-
-  if (this->Target->IsImported()) {
-    this->HandleImportedTarget(args[0]);
-    return false;
-  }
-
   if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
   if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
       scope != "INTERFACE") {
       scope != "INTERFACE") {
     this->SetError("may only set INTERFACE properties on INTERFACE targets");
     this->SetError("may only set INTERFACE properties on INTERFACE targets");
     return false;
     return false;
   }
   }
+  if (this->Target->IsImported() && scope != "INTERFACE") {
+    this->SetError("may only set INTERFACE properties on IMPORTED targets");
+    return false;
+  }
 
 
   ++argIndex;
   ++argIndex;
 
 

+ 0 - 1
Source/cmTargetPropCommandBase.h

@@ -35,7 +35,6 @@ protected:
                                       bool prepend, bool system);
                                       bool prepend, bool system);
 
 
 private:
 private:
-  virtual void HandleImportedTarget(const std::string& tgt) = 0;
   virtual void HandleMissingTarget(const std::string& name) = 0;
   virtual void HandleMissingTarget(const std::string& name) = 0;
 
 
   virtual bool HandleDirectContent(cmTarget* tgt,
   virtual bool HandleDirectContent(cmTarget* tgt,

+ 1 - 8
Source/cmTargetSourcesCommand.cxx

@@ -17,13 +17,6 @@ bool cmTargetSourcesCommand::InitialPass(std::vector<std::string> const& args,
   return this->HandleArguments(args, "SOURCES");
   return this->HandleArguments(args, "SOURCES");
 }
 }
 
 
-void cmTargetSourcesCommand::HandleImportedTarget(const std::string& tgt)
-{
-  std::ostringstream e;
-  e << "Cannot specify sources for imported target \"" << tgt << "\".";
-  this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
-}
-
 void cmTargetSourcesCommand::HandleMissingTarget(const std::string& name)
 void cmTargetSourcesCommand::HandleMissingTarget(const std::string& name)
 {
 {
   std::ostringstream e;
   std::ostringstream e;
@@ -43,5 +36,5 @@ bool cmTargetSourcesCommand::HandleDirectContent(
   cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
   cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
 {
 {
   tgt->AppendProperty("SOURCES", this->Join(content).c_str());
   tgt->AppendProperty("SOURCES", this->Join(content).c_str());
-  return true;
+  return true; // Successfully handled.
 }
 }

+ 0 - 1
Source/cmTargetSourcesCommand.h

@@ -30,7 +30,6 @@ public:
                    cmExecutionStatus& status) override;
                    cmExecutionStatus& status) override;
 
 
 private:
 private:
-  void HandleImportedTarget(const std::string& tgt) override;
   void HandleMissingTarget(const std::string& name) override;
   void HandleMissingTarget(const std::string& name) override;
 
 
   bool HandleDirectContent(cmTarget* tgt,
   bool HandleDirectContent(cmTarget* tgt,

+ 0 - 5
Tests/RunCMake/add_library/UNKNOWNwithNoSourcesButLinkObjects-stderr.txt

@@ -1,5 +0,0 @@
-^CMake Error at UNKNOWNwithNoSourcesButLinkObjects.cmake:[0-9]+ \(target_link_libraries\):
-  Cannot specify link libraries for target \"TestUnknownLibWithoutSources\"
-  which is not built by this project.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:[0-9]+ \(include\)$

+ 1 - 1
Tests/RunCMake/add_library/UNKNOWNwithNoSourcesButLinkObjects.cmake

@@ -2,4 +2,4 @@ enable_language(CXX)
 add_library(ObjectLibDependency OBJECT test.cpp)
 add_library(ObjectLibDependency OBJECT test.cpp)
 
 
 add_library(TestUnknownLibWithoutSources UNKNOWN IMPORTED)
 add_library(TestUnknownLibWithoutSources UNKNOWN IMPORTED)
-target_link_libraries(TestUnknownLibWithoutSources PUBLIC $<TARGET_OBJECTS:ObjectLibDependency>)
+target_link_libraries(TestUnknownLibWithoutSources INTERFACE $<TARGET_OBJECTS:ObjectLibDependency>)

+ 4 - 3
Tests/RunCMake/target_compile_features/imported_target-stderr.txt

@@ -1,4 +1,5 @@
-CMake Error at imported_target.cmake:[0-9]+ \(target_compile_features\):
-  Cannot specify compile features for imported target "main".
+^CMake Error at imported_target.cmake:[0-9]+ \(target_compile_features\):
+  target_compile_features may only set INTERFACE properties on INTERFACE
+  targets
 Call Stack \(most recent call first\):
 Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
+  CMakeLists.txt:3 \(include\)$

+ 8 - 2
Tests/RunCMake/target_compile_features/imported_target.cmake

@@ -1,4 +1,10 @@
 enable_language(CXX)
 enable_language(CXX)
 
 
-add_library(main INTERFACE IMPORTED)
-target_compile_features(main INTERFACE cxx_delegating_constructors)
+add_library(lib1-interface INTERFACE IMPORTED)
+target_compile_features(lib1-interface INTERFACE cxx_delegating_constructors)
+
+add_library(lib2-interface INTERFACE IMPORTED)
+target_compile_features(lib2-interface PUBLIC cxx_delegating_constructors)
+
+add_library(lib-shared SHARED IMPORTED)
+target_compile_features(lib-shared INTERFACE cxx_delegating_constructors)

+ 2 - 0
Tests/RunCMake/target_link_libraries/ImportedTarget.cmake

@@ -0,0 +1,2 @@
+add_library(UnknownImportedGlobal UNKNOWN IMPORTED GLOBAL)
+target_link_libraries(UnknownImportedGlobal INTERFACE z)

+ 0 - 0
Tests/RunCMake/add_library/UNKNOWNwithNoSourcesButLinkObjects-result.txt → Tests/RunCMake/target_link_libraries/ImportedTargetFailure-result.txt


+ 5 - 0
Tests/RunCMake/target_link_libraries/ImportedTargetFailure-stderr.txt

@@ -0,0 +1,5 @@
+^CMake Error at ImportedTargetFailure.cmake:[0-9]+ \(target_link_libraries\):
+  IMPORTED library can only be used with the INTERFACE keyword of
+  target_link_libraries
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$

+ 2 - 0
Tests/RunCMake/target_link_libraries/ImportedTargetFailure.cmake

@@ -0,0 +1,2 @@
+add_library(UnknownImportedGlobal UNKNOWN IMPORTED GLOBAL)
+target_link_libraries(UnknownImportedGlobal PRIVATE z)

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

@@ -4,6 +4,8 @@ run_cmake(CMP0023-WARN)
 run_cmake(CMP0023-NEW)
 run_cmake(CMP0023-NEW)
 run_cmake(CMP0023-WARN-2)
 run_cmake(CMP0023-WARN-2)
 run_cmake(CMP0023-NEW-2)
 run_cmake(CMP0023-NEW-2)
+run_cmake(ImportedTarget)
+run_cmake(ImportedTargetFailure)
 run_cmake(MixedSignature)
 run_cmake(MixedSignature)
 run_cmake(Separate-PRIVATE-LINK_PRIVATE-uses)
 run_cmake(Separate-PRIVATE-LINK_PRIVATE-uses)
 run_cmake(SubDirTarget)
 run_cmake(SubDirTarget)