瀏覽代碼

Add the ALIAS target concept for libraries and executables.

* The ALIAS name must match a validity regex.
* Executables and libraries may be aliased.
* An ALIAS acts immutable. It can not be used as the lhs
  of target_link_libraries or other commands.
* An ALIAS can be used with add_custom_command, add_custom_target,
  and add_test in the same way regular targets can.
* The target of an ALIAS can be retrieved with the ALIASED_TARGET
  target property.
* An ALIAS does not appear in the generated buildsystem. It
  is kept separate from cmMakefile::Targets for that reason.
* A target may have multiple aliases.
* An ALIAS target may not itself have an alias.
* An IMPORTED target may not have an alias.
* An ALIAS may not be exported or imported.
Stephen Kelly 12 年之前
父節點
當前提交
370bf55415
共有 89 個文件被更改,包括 739 次插入18 次删除
  1. 7 0
      Source/cmAddDependenciesCommand.cxx
  2. 72 0
      Source/cmAddExecutableCommand.cxx
  3. 13 0
      Source/cmAddExecutableCommand.h
  4. 80 0
      Source/cmAddLibraryCommand.cxx
  5. 13 0
      Source/cmAddLibraryCommand.h
  6. 9 0
      Source/cmExportCommand.cxx
  7. 12 0
      Source/cmGeneratorExpressionEvaluator.cxx
  8. 12 0
      Source/cmGetPropertyCommand.cxx
  9. 19 6
      Source/cmGetTargetPropertyCommand.cxx
  10. 24 2
      Source/cmGlobalGenerator.cxx
  11. 6 1
      Source/cmGlobalGenerator.h
  12. 9 0
      Source/cmInstallCommand.cxx
  13. 46 4
      Source/cmMakefile.cxx
  14. 5 2
      Source/cmMakefile.h
  15. 5 0
      Source/cmSetPropertyCommand.cxx
  16. 5 0
      Source/cmSetTargetPropertiesCommand.cxx
  17. 6 0
      Source/cmTarget.cxx
  18. 5 0
      Source/cmTargetLinkLibrariesCommand.cxx
  19. 5 0
      Source/cmTargetPropCommandBase.cxx
  20. 47 0
      Tests/AliasTarget/CMakeLists.txt
  21. 28 0
      Tests/AliasTarget/bat.cpp
  22. 15 0
      Tests/AliasTarget/commandgenerator.cpp
  23. 7 0
      Tests/AliasTarget/empty.cpp
  24. 5 0
      Tests/AliasTarget/object.cpp
  25. 4 0
      Tests/AliasTarget/object.h
  26. 13 0
      Tests/AliasTarget/targetgenerator.cpp
  27. 1 0
      Tests/CMakeLists.txt
  28. 2 1
      Tests/CTestTestDepends/CMakeLists.txt
  29. 8 0
      Tests/GeneratorExpression/CMakeLists.txt
  30. 4 0
      Tests/GeneratorExpression/check-part3.cmake
  31. 4 2
      Tests/GeneratorExpression/empty.cpp
  32. 1 0
      Tests/RunCMake/CMakeLists.txt
  33. 3 0
      Tests/RunCMake/alias_targets/CMakeLists.txt
  34. 20 0
      Tests/RunCMake/alias_targets/RunCMakeTest.cmake
  35. 1 0
      Tests/RunCMake/alias_targets/add_dependencies-result.txt
  36. 5 0
      Tests/RunCMake/alias_targets/add_dependencies-stderr.txt
  37. 9 0
      Tests/RunCMake/alias_targets/add_dependencies.cmake
  38. 1 0
      Tests/RunCMake/alias_targets/add_executable-library-result.txt
  39. 5 0
      Tests/RunCMake/alias_targets/add_executable-library-stderr.txt
  40. 6 0
      Tests/RunCMake/alias_targets/add_executable-library.cmake
  41. 1 0
      Tests/RunCMake/alias_targets/add_library-executable-result.txt
  42. 5 0
      Tests/RunCMake/alias_targets/add_library-executable-stderr.txt
  43. 6 0
      Tests/RunCMake/alias_targets/add_library-executable.cmake
  44. 1 0
      Tests/RunCMake/alias_targets/alias-target-result.txt
  45. 5 0
      Tests/RunCMake/alias_targets/alias-target-stderr.txt
  46. 8 0
      Tests/RunCMake/alias_targets/alias-target.cmake
  47. 7 0
      Tests/RunCMake/alias_targets/empty.cpp
  48. 1 0
      Tests/RunCMake/alias_targets/exclude-from-all-result.txt
  49. 4 0
      Tests/RunCMake/alias_targets/exclude-from-all-stderr.txt
  50. 6 0
      Tests/RunCMake/alias_targets/exclude-from-all.cmake
  51. 1 0
      Tests/RunCMake/alias_targets/export-result.txt
  52. 4 0
      Tests/RunCMake/alias_targets/export-stderr.txt
  53. 8 0
      Tests/RunCMake/alias_targets/export.cmake
  54. 1 0
      Tests/RunCMake/alias_targets/imported-result.txt
  55. 4 0
      Tests/RunCMake/alias_targets/imported-stderr.txt
  56. 1 0
      Tests/RunCMake/alias_targets/imported-target-result.txt
  57. 5 0
      Tests/RunCMake/alias_targets/imported-target-stderr.txt
  58. 6 0
      Tests/RunCMake/alias_targets/imported-target.cmake
  59. 2 0
      Tests/RunCMake/alias_targets/imported.cmake
  60. 1 0
      Tests/RunCMake/alias_targets/install-export-result.txt
  61. 4 0
      Tests/RunCMake/alias_targets/install-export-stderr.txt
  62. 9 0
      Tests/RunCMake/alias_targets/install-export.cmake
  63. 1 0
      Tests/RunCMake/alias_targets/invalid-name-result.txt
  64. 4 0
      Tests/RunCMake/alias_targets/invalid-name-stderr.txt
  65. 6 0
      Tests/RunCMake/alias_targets/invalid-name.cmake
  66. 1 0
      Tests/RunCMake/alias_targets/invalid-target-result.txt
  67. 5 0
      Tests/RunCMake/alias_targets/invalid-target-stderr.txt
  68. 2 0
      Tests/RunCMake/alias_targets/invalid-target.cmake
  69. 1 0
      Tests/RunCMake/alias_targets/multiple-targets-result.txt
  70. 4 0
      Tests/RunCMake/alias_targets/multiple-targets-stderr.txt
  71. 7 0
      Tests/RunCMake/alias_targets/multiple-targets.cmake
  72. 1 0
      Tests/RunCMake/alias_targets/name-conflict-result.txt
  73. 5 0
      Tests/RunCMake/alias_targets/name-conflict-stderr.txt
  74. 8 0
      Tests/RunCMake/alias_targets/name-conflict.cmake
  75. 1 0
      Tests/RunCMake/alias_targets/no-targets-result.txt
  76. 4 0
      Tests/RunCMake/alias_targets/no-targets-stderr.txt
  77. 4 0
      Tests/RunCMake/alias_targets/no-targets.cmake
  78. 1 0
      Tests/RunCMake/alias_targets/set_property-result.txt
  79. 4 0
      Tests/RunCMake/alias_targets/set_property-stderr.txt
  80. 8 0
      Tests/RunCMake/alias_targets/set_property.cmake
  81. 1 0
      Tests/RunCMake/alias_targets/set_target_properties-result.txt
  82. 4 0
      Tests/RunCMake/alias_targets/set_target_properties-stderr.txt
  83. 8 0
      Tests/RunCMake/alias_targets/set_target_properties.cmake
  84. 1 0
      Tests/RunCMake/alias_targets/target_include_directories-result.txt
  85. 4 0
      Tests/RunCMake/alias_targets/target_include_directories-stderr.txt
  86. 8 0
      Tests/RunCMake/alias_targets/target_include_directories.cmake
  87. 1 0
      Tests/RunCMake/alias_targets/target_link_libraries-result.txt
  88. 4 0
      Tests/RunCMake/alias_targets/target_link_libraries-stderr.txt
  89. 9 0
      Tests/RunCMake/alias_targets/target_link_libraries.cmake

+ 7 - 0
Source/cmAddDependenciesCommand.cxx

@@ -24,6 +24,13 @@ bool cmAddDependenciesCommand
     }
 
   std::string target_name = args[0];
+  if(this->Makefile->IsAlias(target_name.c_str()))
+    {
+    cmOStringStream e;
+    e << "Cannot add target-level dependencies to alias target \""
+      << target_name << "\".\n";
+    this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+    }
   if(cmTarget* target = this->Makefile->FindTargetToUse(target_name.c_str()))
     {
     std::vector<std::string>::const_iterator s = args.begin();

+ 72 - 0
Source/cmAddExecutableCommand.cxx

@@ -30,6 +30,7 @@ bool cmAddExecutableCommand
   bool excludeFromAll = false;
   bool importTarget = false;
   bool importGlobal = false;
+  bool isAlias = false;
   while ( s != args.end() )
     {
     if (*s == "WIN32")
@@ -57,6 +58,11 @@ bool cmAddExecutableCommand
       ++s;
       importGlobal = true;
       }
+    else if(*s == "ALIAS")
+      {
+      ++s;
+      isAlias = true;
+      }
     else
       {
       break;
@@ -83,6 +89,72 @@ bool cmAddExecutableCommand
       }
     return false;
     }
+  if (isAlias)
+    {
+    if(!cmGeneratorExpression::IsValidTargetName(exename.c_str()))
+      {
+      this->SetError(("Invalid name for ALIAS: " + exename).c_str());
+      return false;
+      }
+    if(excludeFromAll)
+      {
+      this->SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
+      return false;
+      }
+    if(importTarget || importGlobal)
+      {
+      this->SetError("IMPORTED with ALIAS is not allowed.");
+      return false;
+      }
+    if(args.size() != 3)
+      {
+      cmOStringStream e;
+      e << "ALIAS requires exactly one target argument.";
+      this->SetError(e.str().c_str());
+      return false;
+      }
+
+    const char *aliasedName = s->c_str();
+    if(this->Makefile->IsAlias(aliasedName))
+      {
+      cmOStringStream e;
+      e << "cannot create ALIAS target \"" << exename
+        << "\" because target \"" << aliasedName << "\" is itself an ALIAS.";
+      this->SetError(e.str().c_str());
+      return false;
+      }
+    cmTarget *aliasedTarget =
+                    this->Makefile->FindTargetToUse(aliasedName, true);
+    if(!aliasedTarget)
+      {
+      cmOStringStream e;
+      e << "cannot create ALIAS target \"" << exename
+        << "\" because target \"" << aliasedName << "\" does not already "
+        "exist.";
+      this->SetError(e.str().c_str());
+      return false;
+      }
+    cmTarget::TargetType type = aliasedTarget->GetType();
+    if(type != cmTarget::EXECUTABLE)
+      {
+      cmOStringStream e;
+      e << "cannot create ALIAS target \"" << exename
+        << "\" because target \"" << aliasedName << "\" is not an "
+        "executable.";
+      this->SetError(e.str().c_str());
+      return false;
+      }
+    if(aliasedTarget->IsImported())
+      {
+      cmOStringStream e;
+      e << "cannot create ALIAS target \"" << exename
+        << "\" because target \"" << aliasedName << "\" is IMPORTED.";
+      this->SetError(e.str().c_str());
+      return false;
+      }
+    this->Makefile->AddAlias(exename.c_str(), aliasedTarget);
+    return true;
+    }
 
   // Handle imported target creation.
   if(importTarget)

+ 13 - 0
Source/cmAddExecutableCommand.h

@@ -107,6 +107,19 @@ public:
       "(and its per-configuration version IMPORTED_LOCATION_<CONFIG>) "
       "which specifies the location of the main executable file on disk.  "
       "See documentation of the IMPORTED_* properties for more information."
+      "\n"
+      "The signature\n"
+      "  add_executable(<name> ALIAS <target>)\n"
+      "creates an alias, such that <name> can be used to refer to <target> "
+      "in subsequent commands.  The <name> does not appear in the generated "
+      "buildsystem as a make target.  The <target> may not be an IMPORTED "
+      "target or an ALIAS.  Alias targets can be used as linkable targets, "
+      "targets to read properties from, executables for custom commands and "
+      "custom targets.  They can also be tested for existance with the "
+      "regular if(TARGET) subcommand.  The <name> may not be used to modify "
+      "properties of <target>, that is, it may not be used as the operand of "
+      "set_property, set_target_properties, target_link_libraries etc.  An "
+      "ALIAS target may not be installed of exported."
       ;
     }
 

+ 80 - 0
Source/cmAddLibraryCommand.cxx

@@ -43,6 +43,7 @@ bool cmAddLibraryCommand
   // the type of library.  Otherwise, it is treated as a source or
   // source list name. There may be two keyword arguments, check for them
   bool haveSpecifiedType = false;
+  bool isAlias = false;
   while ( s != args.end() )
     {
     std::string libType = *s;
@@ -76,6 +77,11 @@ bool cmAddLibraryCommand
       type = cmTarget::UNKNOWN_LIBRARY;
       haveSpecifiedType = true;
       }
+    else if(libType == "ALIAS")
+      {
+      ++s;
+      isAlias = true;
+      }
     else if(*s == "EXCLUDE_FROM_ALL")
       {
       ++s;
@@ -96,6 +102,80 @@ bool cmAddLibraryCommand
       break;
       }
     }
+  if (isAlias)
+    {
+    if(!cmGeneratorExpression::IsValidTargetName(libName.c_str()))
+      {
+      this->SetError(("Invalid name for ALIAS: " + libName).c_str());
+      return false;
+      }
+    if(excludeFromAll)
+      {
+      this->SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
+      return false;
+      }
+    if(importTarget || importGlobal)
+      {
+      this->SetError("IMPORTED with ALIAS is not allowed.");
+      return false;
+      }
+    if(args.size() != 3)
+      {
+      cmOStringStream e;
+      e << "ALIAS requires exactly one target argument.";
+      this->SetError(e.str().c_str());
+      return false;
+      }
+
+    const char *aliasedName = s->c_str();
+    if(this->Makefile->IsAlias(aliasedName))
+      {
+      cmOStringStream e;
+      e << "cannot create ALIAS target \"" << libName
+        << "\" because target \"" << aliasedName << "\" is itself an ALIAS.";
+      this->SetError(e.str().c_str());
+      return false;
+      }
+    cmTarget *aliasedTarget =
+                    this->Makefile->FindTargetToUse(aliasedName, true);
+    if(!aliasedTarget)
+      {
+      cmOStringStream e;
+      e << "cannot create ALIAS target \"" << libName
+        << "\" because target \"" << aliasedName << "\" does not already "
+        "exist.";
+      this->SetError(e.str().c_str());
+      return false;
+      }
+    cmTarget::TargetType aliasedType = aliasedTarget->GetType();
+    if(aliasedType != cmTarget::SHARED_LIBRARY
+        && aliasedType != cmTarget::STATIC_LIBRARY
+        && aliasedType != cmTarget::MODULE_LIBRARY
+        && aliasedType != cmTarget::OBJECT_LIBRARY)
+      {
+      cmOStringStream e;
+      e << "cannot create ALIAS target \"" << libName
+        << "\" because target \"" << aliasedName << "\" is not a library.";
+      this->SetError(e.str().c_str());
+      return false;
+      }
+    if(aliasedTarget->IsImported())
+      {
+      cmOStringStream e;
+      e << "cannot create ALIAS target \"" << libName
+        << "\" because target \"" << aliasedName << "\" is IMPORTED.";
+      this->SetError(e.str().c_str());
+      return false;
+      }
+    this->Makefile->AddAlias(libName.c_str(), aliasedTarget);
+    return true;
+    }
+
+  if(importTarget && excludeFromAll)
+    {
+    this->SetError("excludeFromAll with IMPORTED target makes no sense.");
+    return false;
+    }
 
   /* ideally we should check whether for the linker language of the target
     CMAKE_${LANG}_CREATE_SHARED_LIBRARY is defined and if not default to

+ 13 - 0
Source/cmAddLibraryCommand.h

@@ -138,6 +138,19 @@ public:
       "Some native build systems may not like targets that have only "
       "object files, so consider adding at least one real source file "
       "to any target that references $<TARGET_OBJECTS:objlib>."
+      "\n"
+      "The signature\n"
+      "  add_library(<name> ALIAS <target>)\n"
+      "creates an alias, such that <name> can be used to refer to <target> "
+      "in subsequent commands.  The <name> does not appear in the generated "
+      "buildsystem as a make target.  The <target> may not be an IMPORTED "
+      "target or an ALIAS.  Alias targets can be used as linkable targets, "
+      "targets to read properties from.  They can also be tested for "
+      "existance with the "
+      "regular if(TARGET) subcommand.  The <name> may not be used to modify "
+      "properties of <target>, that is, it may not be used as the operand of "
+      "set_property, set_target_properties, target_link_libraries etc.  An "
+      "ALIAS target may not be installed of exported."
       ;
     }
 

+ 9 - 0
Source/cmExportCommand.cxx

@@ -114,6 +114,15 @@ bool cmExportCommand
       currentTarget != this->Targets.GetVector().end();
       ++currentTarget)
     {
+    if (this->Makefile->IsAlias(currentTarget->c_str()))
+      {
+      cmOStringStream e;
+      e << "given ALIAS target \"" << *currentTarget
+        << "\" which may not be exported.";
+      this->SetError(e.str().c_str());
+      return false;
+      }
+
     if(cmTarget* target =
        this->Makefile->GetLocalGenerator()->
        GetGlobalGenerator()->FindTarget(0, currentTarget->c_str()))

+ 12 - 0
Source/cmGeneratorExpressionEvaluator.cxx

@@ -747,6 +747,18 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
                       "Target name not supported.");
         return std::string();
         }
+      if(propertyName == "ALIASED_TARGET")
+        {
+        if(context->Makefile->IsAlias(targetName.c_str()))
+          {
+          if(cmTarget* tgt =
+                      context->Makefile->FindTargetToUse(targetName.c_str()))
+            {
+            return tgt->GetName();
+            }
+          }
+        return "";
+        }
       target = context->Makefile->FindTargetToUse(
                                                 targetName.c_str());
 

+ 12 - 0
Source/cmGetPropertyCommand.cxx

@@ -288,6 +288,18 @@ bool cmGetPropertyCommand::HandleTargetMode()
     return false;
     }
 
+  if(this->PropertyName == "ALIASED_TARGET")
+    {
+    if(this->Makefile->IsAlias(this->Name.c_str()))
+      {
+      if(cmTarget* target =
+                          this->Makefile->FindTargetToUse(this->Name.c_str()))
+        {
+        return this->StoreResult(target->GetName());
+        }
+      }
+    return false;
+    }
   if(cmTarget* target = this->Makefile->FindTargetToUse(this->Name.c_str()))
     {
     return this->StoreResult(target->GetProperty(this->PropertyName.c_str()));

+ 19 - 6
Source/cmGetTargetPropertyCommand.cxx

@@ -22,17 +22,30 @@ bool cmGetTargetPropertyCommand
     }
   std::string var = args[0].c_str();
   const char* targetName = args[1].c_str();
+  const char *prop = 0;
 
-  if(cmTarget* tgt = this->Makefile->FindTargetToUse(targetName))
+  if(args[2] == "ALIASED_TARGET")
     {
-    cmTarget& target = *tgt;
-    const char *prop = target.GetProperty(args[2].c_str());
-    if (prop)
+    if(this->Makefile->IsAlias(targetName))
       {
-      this->Makefile->AddDefinition(var.c_str(), prop);
-      return true;
+      if(cmTarget* target =
+                          this->Makefile->FindTargetToUse(targetName))
+        {
+        prop = target->GetName();
+        }
       }
     }
+  else if(cmTarget* tgt = this->Makefile->FindTargetToUse(targetName))
+    {
+    cmTarget& target = *tgt;
+    prop = target.GetProperty(args[2].c_str());
+    }
+
+  if (prop)
+    {
+    this->Makefile->AddDefinition(var.c_str(), prop);
+    return true;
+    }
   this->Makefile->AddDefinition(var.c_str(), (var+"-NOTFOUND").c_str());
   return true;
 }

+ 24 - 2
Source/cmGlobalGenerator.cxx

@@ -1769,10 +1769,22 @@ cmLocalGenerator* cmGlobalGenerator::FindLocalGenerator(const char* start_dir)
   return 0;
 }
 
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::AddAlias(const char *name, cmTarget *tgt)
+{
+  this->AliasTargets[name] = tgt;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalGenerator::IsAlias(const char *name)
+{
+  return this->AliasTargets.find(name) != this->AliasTargets.end();
+}
 
 //----------------------------------------------------------------------------
 cmTarget*
-cmGlobalGenerator::FindTarget(const char* project, const char* name)
+cmGlobalGenerator::FindTarget(const char* project, const char* name,
+                              bool excludeAliases)
 {
   // if project specific
   if(project)
@@ -1780,7 +1792,8 @@ cmGlobalGenerator::FindTarget(const char* project, const char* name)
     std::vector<cmLocalGenerator*>* gens = &this->ProjectMap[project];
     for(unsigned int i = 0; i < gens->size(); ++i)
       {
-      cmTarget* ret = (*gens)[i]->GetMakefile()->FindTarget(name);
+      cmTarget* ret = (*gens)[i]->GetMakefile()->FindTarget(name,
+                                                            excludeAliases);
       if(ret)
         {
         return ret;
@@ -1790,6 +1803,15 @@ cmGlobalGenerator::FindTarget(const char* project, const char* name)
   // if all projects/directories
   else
     {
+    if (!excludeAliases)
+      {
+      std::map<cmStdString, cmTarget*>::iterator ai
+                                              = this->AliasTargets.find(name);
+      if (ai != this->AliasTargets.end())
+        {
+        return ai->second;
+        }
+      }
     std::map<cmStdString,cmTarget *>::iterator i =
       this->TotalTargets.find ( name );
     if ( i != this->TotalTargets.end() )

+ 6 - 1
Source/cmGlobalGenerator.h

@@ -196,7 +196,11 @@ public:
   void FindMakeProgram(cmMakefile*);
 
   ///! Find a target by name by searching the local generators.
-  cmTarget* FindTarget(const char* project, const char* name);
+  cmTarget* FindTarget(const char* project, const char* name,
+                       bool excludeAliases = false);
+
+  void AddAlias(const char *name, cmTarget *tgt);
+  bool IsAlias(const char *name);
 
   /** Determine if a name resolves to a framework on disk or a built target
       that is a framework. */
@@ -347,6 +351,7 @@ protected:
 
   // All targets in the entire project.
   std::map<cmStdString,cmTarget *> TotalTargets;
+  std::map<cmStdString,cmTarget *> AliasTargets;
   std::map<cmStdString,cmTarget *> ImportedTargets;
   std::vector<cmGeneratorExpressionEvaluationFile*> EvaluationFiles;
 

+ 9 - 0
Source/cmInstallCommand.cxx

@@ -362,6 +362,15 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
       targetIt!=targetList.GetVector().end();
       ++targetIt)
     {
+
+    if (this->Makefile->IsAlias(targetIt->c_str()))
+      {
+      cmOStringStream e;
+      e << "TARGETS given target \"" << (*targetIt)
+        << "\" which is an alias.";
+      this->SetError(e.str().c_str());
+      return false;
+      }
     // Lookup this target in the current directory.
     if(cmTarget* target=this->Makefile->FindTarget(targetIt->c_str()))
       {

+ 46 - 4
Source/cmMakefile.cxx

@@ -41,6 +41,7 @@
 
 #include <stack>
 #include <ctype.h> // for isspace
+#include <assert.h>
 
 class cmMakefile::Internals
 {
@@ -1437,6 +1438,14 @@ void cmMakefile::AddLinkDirectoryForTarget(const char *target,
   cmTargets::iterator i = this->Targets.find(target);
   if ( i != this->Targets.end())
     {
+    if(this->IsAlias(target))
+      {
+      cmOStringStream e;
+      e << "ALIAS target \"" << target << "\" "
+        << "may not be linked into another target.";
+      this->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+      return;
+      }
     i->second.AddLinkDirectory( d );
     }
   else
@@ -1923,6 +1932,12 @@ void cmMakefile::AddGlobalLinkInformation(const char* name, cmTarget& target)
 }
 
 
+void cmMakefile::AddAlias(const char* lname, cmTarget *tgt)
+{
+  this->AliasTargets[lname] = tgt;
+  this->LocalGenerator->GetGlobalGenerator()->AddAlias(lname, tgt);
+}
+
 cmTarget* cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
                             const std::vector<std::string> &srcs,
                             bool excludeFromAll)
@@ -3758,8 +3773,17 @@ const char* cmMakefile::GetFeature(const char* feature, const char* config)
   return 0;
 }
 
-cmTarget* cmMakefile::FindTarget(const char* name)
+cmTarget* cmMakefile::FindTarget(const char* name, bool excludeAliases)
 {
+  if (!excludeAliases)
+    {
+    std::map<std::string, cmTarget*>::iterator i
+                                              = this->AliasTargets.find(name);
+    if (i != this->AliasTargets.end())
+      {
+      return i->second;
+      }
+    }
   cmTargets& tgts = this->GetTargets();
 
   cmTargets::iterator i = tgts.find ( name );
@@ -4184,7 +4208,7 @@ cmMakefile::AddImportedTarget(const char* name, cmTarget::TargetType type,
 }
 
 //----------------------------------------------------------------------------
-cmTarget* cmMakefile::FindTargetToUse(const char* name)
+cmTarget* cmMakefile::FindTargetToUse(const char* name, bool excludeAliases)
 {
   // Look for an imported target.  These take priority because they
   // are more local in scope and do not have to be globally unique.
@@ -4196,15 +4220,25 @@ cmTarget* cmMakefile::FindTargetToUse(const char* name)
     }
 
   // Look for a target built in this directory.
-  if(cmTarget* t = this->FindTarget(name))
+  if(cmTarget* t = this->FindTarget(name, excludeAliases))
     {
     return t;
     }
 
   // Look for a target built in this project.
-  return this->LocalGenerator->GetGlobalGenerator()->FindTarget(0, name);
+  return this->LocalGenerator->GetGlobalGenerator()->FindTarget(0, name,
+                                                              excludeAliases);
 }
 
+//----------------------------------------------------------------------------
+bool cmMakefile::IsAlias(const char *name)
+{
+  if (this->AliasTargets.find(name) != this->AliasTargets.end())
+    return true;
+  return this->GetLocalGenerator()->GetGlobalGenerator()->IsAlias(name);
+}
+
+//----------------------------------------------------------------------------
 cmGeneratorTarget* cmMakefile::FindGeneratorTargetToUse(const char* name)
 {
   cmTarget *t = this->FindTargetToUse(name);
@@ -4215,6 +4249,14 @@ cmGeneratorTarget* cmMakefile::FindGeneratorTargetToUse(const char* name)
 bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
                                    bool isCustom)
 {
+  if(this->IsAlias(name.c_str()))
+    {
+    cmOStringStream e;
+    e << "cannot create target \"" << name
+      << "\" because an alias with the same name already exists.";
+    msg = e.str();
+    return false;
+    }
   if(cmTarget* existing = this->FindTargetToUse(name.c_str()))
     {
     // The name given conflicts with an existing target.  Produce an

+ 5 - 2
Source/cmMakefile.h

@@ -337,6 +337,7 @@ public:
   cmTarget* AddLibrary(const char *libname, cmTarget::TargetType type,
                   const std::vector<std::string> &srcs,
                   bool excludeFromAll = false);
+  void AddAlias(const char *libname, cmTarget *tgt);
 
 #if defined(CMAKE_BUILD_WITH_CMAKE)
   /**
@@ -536,11 +537,12 @@ public:
       this->GeneratorTargets = targets;
     }
 
-  cmTarget* FindTarget(const char* name);
+  cmTarget* FindTarget(const char* name, bool excludeAliases = false);
 
   /** Find a target to use in place of the given name.  The target
       returned may be imported or built within the project.  */
-  cmTarget* FindTargetToUse(const char* name);
+  cmTarget* FindTargetToUse(const char* name, bool excludeAliases = false);
+  bool IsAlias(const char *name);
   cmGeneratorTarget* FindGeneratorTargetToUse(const char* name);
 
   /**
@@ -902,6 +904,7 @@ protected:
 
   // libraries, classes, and executables
   cmTargets Targets;
+  std::map<std::string, cmTarget*> AliasTargets;
   cmGeneratorTargetsType GeneratorTargets;
   std::vector<cmSourceFile*> SourceFiles;
 

+ 5 - 0
Source/cmSetPropertyCommand.cxx

@@ -244,6 +244,11 @@ bool cmSetPropertyCommand::HandleTargetMode()
   for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
       ni != this->Names.end(); ++ni)
     {
+    if (this->Makefile->IsAlias(ni->c_str()))
+      {
+      this->SetError("can not be used on an ALIAS target.");
+      return false;
+      }
     if(cmTarget* target = this->Makefile->FindTargetToUse(ni->c_str()))
       {
       // Handle the current target.

+ 5 - 0
Source/cmSetTargetPropertiesCommand.cxx

@@ -72,6 +72,11 @@ bool cmSetTargetPropertiesCommand
   int i;
   for(i = 0; i < numFiles; ++i)
     {
+    if (this->Makefile->IsAlias(args[i].c_str()))
+      {
+      this->SetError("can not be used on an ALIAS target.");
+      return false;
+      }
     bool ret = cmSetTargetPropertiesCommand::SetOneTarget
       (args[i].c_str(),propertyPairs,this->Makefile);
     if (!ret)

+ 6 - 0
Source/cmTarget.cxx

@@ -968,6 +968,12 @@ void cmTarget::DefineProperties(cmake *cm)
      "Per-configuration target file base name.",
      "This is the configuration-specific version of OUTPUT_NAME.");
 
+  cm->DefineProperty
+    ("ALIASED_TARGET", cmProperty::TARGET,
+     "Name of target aliased by this target.",
+     "If this is an ALIAS target, this property contains the name of the "
+     "target aliased.");
+
   cm->DefineProperty
     ("<CONFIG>_OUTPUT_NAME", cmProperty::TARGET,
      "Old per-configuration target file base name.",

+ 5 - 0
Source/cmTargetLinkLibrariesCommand.cxx

@@ -31,6 +31,11 @@ bool cmTargetLinkLibrariesCommand
     return false;
     }
 
+  if (this->Makefile->IsAlias(args[0].c_str()))
+    {
+    this->SetError("can not be used on an ALIAS target.");
+    return false;
+    }
   // Lookup the target for which libraries are specified.
   this->Target =
     this->Makefile->GetCMakeInstance()

+ 5 - 0
Source/cmTargetPropCommandBase.cxx

@@ -26,6 +26,11 @@ bool cmTargetPropCommandBase
     }
 
   // Lookup the target for which libraries are specified.
+  if (this->Makefile->IsAlias(args[0].c_str()))
+    {
+    this->SetError("can not be used on an ALIAS target.");
+    return false;
+    }
   this->Target =
     this->Makefile->GetCMakeInstance()
     ->GetGlobalGenerator()->FindTarget(0, args[0].c_str());

+ 47 - 0
Tests/AliasTarget/CMakeLists.txt

@@ -0,0 +1,47 @@
+
+cmake_minimum_required(VERSION 2.8.11)
+project(AliasTarget)
+
+add_library(foo SHARED empty.cpp)
+add_library(PREFIX::Foo ALIAS foo)
+add_library(Another::Alias ALIAS foo)
+
+add_library(objects OBJECT object.cpp)
+add_library(Alias::Objects ALIAS objects)
+
+target_compile_definitions(foo PUBLIC FOO_DEFINE)
+
+add_library(bar SHARED empty.cpp)
+target_compile_definitions(bar PUBLIC BAR_DEFINE)
+
+target_link_libraries(foo LINK_PUBLIC $<$<STREQUAL:$<TARGET_PROPERTY:PREFIX::Foo,ALIASED_TARGET>,foo>:bar>)
+
+add_executable(AliasTarget commandgenerator.cpp $<TARGET_OBJECTS:Alias::Objects>)
+add_executable(PREFIX::AliasTarget ALIAS AliasTarget)
+add_executable(Generator::Command ALIAS AliasTarget)
+
+add_custom_command(OUTPUT commandoutput.h COMMAND Generator::Command)
+
+add_library(bat SHARED bat.cpp "${CMAKE_CURRENT_BINARY_DIR}/commandoutput.h")
+target_link_libraries(bat PREFIX::Foo)
+target_include_directories(bat PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
+
+add_executable(targetgenerator targetgenerator.cpp)
+add_executable(Generator::Target ALIAS targetgenerator)
+
+add_custom_target(usealias Generator::Target)
+add_dependencies(bat usealias)
+
+if (NOT TARGET Another::Alias)
+  message(SEND_ERROR "Another::Alias is not considered a target.")
+endif()
+
+get_target_property(_alt PREFIX::Foo ALIASED_TARGET)
+if (NOT ${_alt} STREQUAL foo)
+  message(SEND_ERROR "ALIASED_TARGET is not foo: ${_alt}")
+endif()
+
+get_property(_alt2 TARGET PREFIX::Foo PROPERTY ALIASED_TARGET)
+if (NOT ${_alt2} STREQUAL foo)
+  message(SEND_ERROR "ALIASED_TARGET is not foo.")
+endif()

+ 28 - 0
Tests/AliasTarget/bat.cpp

@@ -0,0 +1,28 @@
+
+#ifndef FOO_DEFINE
+#error Expected FOO_DEFINE
+#endif
+
+#ifndef BAR_DEFINE
+#error Expected Bar_DEFINE
+#endif
+
+#include "commandoutput.h"
+
+#ifndef COMMANDOUTPUT_DEFINE
+#error Expected COMMANDOUTPUT_DEFINE
+#endif
+
+#include "targetoutput.h"
+
+#ifndef TARGETOUTPUT_DEFINE
+#error Expected TARGETOUTPUT_DEFINE
+#endif
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int bar()
+{
+  return 0;
+}

+ 15 - 0
Tests/AliasTarget/commandgenerator.cpp

@@ -0,0 +1,15 @@
+
+#include <fstream>
+
+#include "object.h"
+
+int main(int argc, char **argv)
+{
+  std::fstream fout;
+  fout.open("commandoutput.h", std::ios::out);
+  if (!fout)
+    return 1;
+  fout << "#define COMMANDOUTPUT_DEFINE\n";
+  fout.close();
+  return object();
+}

+ 7 - 0
Tests/AliasTarget/empty.cpp

@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int main(void)
+{
+  return 0;
+}

+ 5 - 0
Tests/AliasTarget/object.cpp

@@ -0,0 +1,5 @@
+
+int object(void)
+{
+  return 0;
+}

+ 4 - 0
Tests/AliasTarget/object.h

@@ -0,0 +1,4 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int object(void);

+ 13 - 0
Tests/AliasTarget/targetgenerator.cpp

@@ -0,0 +1,13 @@
+
+#include <fstream>
+
+int main(int argc, char **argv)
+{
+  std::fstream fout;
+  fout.open("targetoutput.h", std::ios::out);
+  if (!fout)
+    return 1;
+  fout << "#define TARGETOUTPUT_DEFINE\n";
+  fout.close();
+  return 0;
+}

+ 1 - 0
Tests/CMakeLists.txt

@@ -245,6 +245,7 @@ if(BUILD_TESTING)
   ADD_TEST_MACRO(CompileDefinitions CompileDefinitions)
   ADD_TEST_MACRO(CompileOptions CompileOptions)
   ADD_TEST_MACRO(CompatibleInterface CompatibleInterface)
+  ADD_TEST_MACRO(AliasTarget AliasTarget)
   set_tests_properties(EmptyLibrary PROPERTIES
     PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target: test")
   ADD_TEST_MACRO(CrossCompile CrossCompile)

+ 2 - 1
Tests/CTestTestDepends/CMakeLists.txt

@@ -3,7 +3,8 @@ project(CTestTestDepends)
 include(CTest)
 
 add_executable (simple simple.cxx)
-add_test (one simple)
+add_executable (TestExe::Simple ALIAS simple)
+add_test (NAME one COMMAND TestExe::Simple)
 add_test (two simple)
 add_test (three simple)
 

+ 8 - 0
Tests/GeneratorExpression/CMakeLists.txt

@@ -163,6 +163,11 @@ add_library(imported4 SHARED IMPORTED)
 set_property(TARGET imported4 APPEND PROPERTY
   INCLUDE_DIRECTORIES $<TARGET_PROPERTY:imported3,INTERFACE_INCLUDE_DIRECTORIES>)
 
+add_executable(someexe empty.cpp)
+add_executable(Alias::SomeExe ALIAS someexe)
+
+add_library(Alias::SomeLib ALIAS empty1)
+
 add_custom_target(check-part3 ALL
   COMMAND ${CMAKE_COMMAND}
     -Dtest_version_greater_1=$<VERSION_GREATER:1.0,1.1.1>
@@ -176,6 +181,9 @@ add_custom_target(check-part3 ALL
     -Dtest_imported_release=$<TARGET_PROPERTY:imported4,INCLUDE_DIRECTORIES>
     -Dtest_imported_relwithdebinfo=$<TARGET_PROPERTY:imported4,INCLUDE_DIRECTORIES>
     -Dtest_imported_minsizerel=$<TARGET_PROPERTY:imported4,INCLUDE_DIRECTORIES>
+    -Dtest_alias_file_exe=$<STREQUAL:$<TARGET_FILE:Alias::SomeExe>,$<TARGET_FILE:someexe>>
+    -Dtest_alias_file_lib=$<STREQUAL:$<TARGET_FILE:Alias::SomeLib>,$<TARGET_FILE:empty1>>
+    -Dtest_alias_target_name=$<STREQUAL:$<TARGET_PROPERTY:Alias::SomeLib,NAME>,$<TARGET_PROPERTY:empty1,NAME>>
     -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part3.cmake
   COMMAND ${CMAKE_COMMAND} -E echo "check done (part 3 of 3)"
   VERBATIM

+ 4 - 0
Tests/GeneratorExpression/check-part3.cmake

@@ -20,3 +20,7 @@ foreach(c debug release relwithdebinfo minsizerel)
     endif()
   endif()
 endforeach()
+
+check(test_alias_file_exe "1")
+check(test_alias_file_lib "1")
+check(test_alias_target_name "1")

+ 4 - 2
Tests/GeneratorExpression/empty.cpp

@@ -1,2 +1,4 @@
-
-// empty
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int main() { return 0; }

+ 1 - 0
Tests/RunCMake/CMakeLists.txt

@@ -98,6 +98,7 @@ add_RunCMake_test(try_compile)
 add_RunCMake_test(variable_watch)
 add_RunCMake_test(CMP0004)
 add_RunCMake_test(TargetPolicies)
+add_RunCMake_test(alias_targets)
 
 find_package(Qt4 QUIET)
 find_package(Qt5Core QUIET)

+ 3 - 0
Tests/RunCMake/alias_targets/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 20 - 0
Tests/RunCMake/alias_targets/RunCMakeTest.cmake

@@ -0,0 +1,20 @@
+include(RunCMake)
+
+run_cmake(no-targets)
+run_cmake(multiple-targets)
+run_cmake(exclude-from-all)
+run_cmake(imported)
+run_cmake(invalid-name)
+run_cmake(invalid-target)
+run_cmake(imported-target)
+run_cmake(alias-target)
+run_cmake(set_property)
+run_cmake(set_target_properties)
+run_cmake(target_link_libraries)
+run_cmake(target_include_directories)
+run_cmake(export)
+run_cmake(install-export)
+run_cmake(name-conflict)
+run_cmake(add_dependencies)
+run_cmake(add_executable-library)
+run_cmake(add_library-executable)

+ 1 - 0
Tests/RunCMake/alias_targets/add_dependencies-result.txt

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

+ 5 - 0
Tests/RunCMake/alias_targets/add_dependencies-stderr.txt

@@ -0,0 +1,5 @@
+CMake Error at add_dependencies.cmake:9 \(add_dependencies\):
+  Cannot add target-level dependencies to alias target "alias".
+
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 9 - 0
Tests/RunCMake/alias_targets/add_dependencies.cmake

@@ -0,0 +1,9 @@
+
+enable_language(CXX)
+
+add_library(foo empty.cpp)
+add_library(bar empty.cpp)
+
+add_library(alias ALIAS foo)
+
+add_dependencies(alias bar)

+ 1 - 0
Tests/RunCMake/alias_targets/add_executable-library-result.txt

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

+ 5 - 0
Tests/RunCMake/alias_targets/add_executable-library-stderr.txt

@@ -0,0 +1,5 @@
+CMake Error at add_executable-library.cmake:6 \(add_executable\):
+  add_executable cannot create ALIAS target "alias" because target "foo" is
+  not an executable.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 6 - 0
Tests/RunCMake/alias_targets/add_executable-library.cmake

@@ -0,0 +1,6 @@
+
+enable_language(CXX)
+
+add_library(foo empty.cpp)
+
+add_executable(alias ALIAS foo)

+ 1 - 0
Tests/RunCMake/alias_targets/add_library-executable-result.txt

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

+ 5 - 0
Tests/RunCMake/alias_targets/add_library-executable-stderr.txt

@@ -0,0 +1,5 @@
+CMake Error at add_library-executable.cmake:6 \(add_library\):
+  add_library cannot create ALIAS target "alias" because target "foo" is not
+  a library.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 6 - 0
Tests/RunCMake/alias_targets/add_library-executable.cmake

@@ -0,0 +1,6 @@
+
+enable_language(CXX)
+
+add_executable(foo empty.cpp)
+
+add_library(alias ALIAS foo)

+ 1 - 0
Tests/RunCMake/alias_targets/alias-target-result.txt

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

+ 5 - 0
Tests/RunCMake/alias_targets/alias-target-stderr.txt

@@ -0,0 +1,5 @@
+CMake Error at alias-target.cmake:8 \(add_library\):
+  add_library cannot create ALIAS target "next_alias" because target "alias"
+  is itself an ALIAS.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 8 - 0
Tests/RunCMake/alias_targets/alias-target.cmake

@@ -0,0 +1,8 @@
+
+enable_language(CXX)
+
+add_library(foo empty.cpp)
+
+add_library(alias ALIAS foo)
+
+add_library(next_alias ALIAS alias)

+ 7 - 0
Tests/RunCMake/alias_targets/empty.cpp

@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+  return 0;
+}

+ 1 - 0
Tests/RunCMake/alias_targets/exclude-from-all-result.txt

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

+ 4 - 0
Tests/RunCMake/alias_targets/exclude-from-all-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at exclude-from-all.cmake:6 \(add_library\):
+  add_library EXCLUDE_FROM_ALL with ALIAS makes no sense.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 6 - 0
Tests/RunCMake/alias_targets/exclude-from-all.cmake

@@ -0,0 +1,6 @@
+
+enable_language(CXX)
+
+add_library(foo empty.cpp)
+
+add_library(alias ALIAS EXCLUDE_FROM_ALL foo)

+ 1 - 0
Tests/RunCMake/alias_targets/export-result.txt

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

+ 4 - 0
Tests/RunCMake/alias_targets/export-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at export.cmake:8 \(export\):
+  export given ALIAS target "alias" which may not be exported.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 8 - 0
Tests/RunCMake/alias_targets/export.cmake

@@ -0,0 +1,8 @@
+
+enable_language(CXX)
+
+add_library(foo empty.cpp)
+
+add_library(alias ALIAS foo)
+
+export(TARGETS alias FILE someFile.cmake)

+ 1 - 0
Tests/RunCMake/alias_targets/imported-result.txt

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

+ 4 - 0
Tests/RunCMake/alias_targets/imported-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at imported.cmake:2 \(add_library\):
+  add_library IMPORTED with ALIAS is not allowed.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 1 - 0
Tests/RunCMake/alias_targets/imported-target-result.txt

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

+ 5 - 0
Tests/RunCMake/alias_targets/imported-target-stderr.txt

@@ -0,0 +1,5 @@
+CMake Error at imported-target.cmake:6 \(add_library\):
+  add_library cannot create ALIAS target "alias" because target "foo" is
+  IMPORTED.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 6 - 0
Tests/RunCMake/alias_targets/imported-target.cmake

@@ -0,0 +1,6 @@
+
+enable_language(CXX)
+
+add_library(foo SHARED IMPORTED)
+
+add_library(alias ALIAS foo)

+ 2 - 0
Tests/RunCMake/alias_targets/imported.cmake

@@ -0,0 +1,2 @@
+
+add_library(alias IMPORTED ALIAS)

+ 1 - 0
Tests/RunCMake/alias_targets/install-export-result.txt

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

+ 4 - 0
Tests/RunCMake/alias_targets/install-export-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at install-export.cmake:8 \(install\):
+  install TARGETS given target "alias" which is an alias.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 9 - 0
Tests/RunCMake/alias_targets/install-export.cmake

@@ -0,0 +1,9 @@
+
+enable_language(CXX)
+
+add_library(foo empty.cpp)
+
+add_library(alias ALIAS foo)
+
+install(TARGETS alias EXPORT theTargets DESTINATION prefix)
+install(EXPORT theTargets DESTINATION lib/cmake)

+ 1 - 0
Tests/RunCMake/alias_targets/invalid-name-result.txt

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

+ 4 - 0
Tests/RunCMake/alias_targets/invalid-name-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at invalid-name.cmake:6 \(add_library\):
+  add_library Invalid name for ALIAS: invalid\$name
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 6 - 0
Tests/RunCMake/alias_targets/invalid-name.cmake

@@ -0,0 +1,6 @@
+
+enable_language(CXX)
+
+add_library(foo empty.cpp)
+
+add_library(invalid$name ALIAS foo)

+ 1 - 0
Tests/RunCMake/alias_targets/invalid-target-result.txt

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

+ 5 - 0
Tests/RunCMake/alias_targets/invalid-target-stderr.txt

@@ -0,0 +1,5 @@
+CMake Error at invalid-target.cmake:2 \(add_library\):
+  add_library cannot create ALIAS target "alias" because target "foo" does
+  not already exist.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 2 - 0
Tests/RunCMake/alias_targets/invalid-target.cmake

@@ -0,0 +1,2 @@
+
+add_library(alias ALIAS foo)

+ 1 - 0
Tests/RunCMake/alias_targets/multiple-targets-result.txt

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

+ 4 - 0
Tests/RunCMake/alias_targets/multiple-targets-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at multiple-targets.cmake:7 \(add_library\):
+  add_library ALIAS requires exactly one target argument.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 7 - 0
Tests/RunCMake/alias_targets/multiple-targets.cmake

@@ -0,0 +1,7 @@
+
+enable_language(CXX)
+
+add_library(foo empty.cpp)
+add_library(bar empty.cpp)
+
+add_library(alias ALIAS foo bar)

+ 1 - 0
Tests/RunCMake/alias_targets/name-conflict-result.txt

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

+ 5 - 0
Tests/RunCMake/alias_targets/name-conflict-stderr.txt

@@ -0,0 +1,5 @@
+CMake Error at name-conflict.cmake:8 \(add_library\):
+  add_library cannot create target "bar" because an alias with the same name
+  already exists.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 8 - 0
Tests/RunCMake/alias_targets/name-conflict.cmake

@@ -0,0 +1,8 @@
+
+enable_language(CXX)
+
+add_library(foo empty.cpp)
+
+add_library(bar ALIAS foo)
+
+add_library(bar empty.cpp)

+ 1 - 0
Tests/RunCMake/alias_targets/no-targets-result.txt

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

+ 4 - 0
Tests/RunCMake/alias_targets/no-targets-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at no-targets.cmake:4 \(add_library\):
+  add_library ALIAS requires exactly one target argument.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 4 - 0
Tests/RunCMake/alias_targets/no-targets.cmake

@@ -0,0 +1,4 @@
+
+enable_language(CXX)
+
+add_library(alias ALIAS)

+ 1 - 0
Tests/RunCMake/alias_targets/set_property-result.txt

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

+ 4 - 0
Tests/RunCMake/alias_targets/set_property-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at set_property.cmake:8 \(set_property\):
+  set_property can not be used on an ALIAS target.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 8 - 0
Tests/RunCMake/alias_targets/set_property.cmake

@@ -0,0 +1,8 @@
+
+enable_language(CXX)
+
+add_library(foo empty.cpp)
+
+add_library(alias ALIAS foo)
+
+set_property(TARGET alias PROPERTY ANYTHING 1)

+ 1 - 0
Tests/RunCMake/alias_targets/set_target_properties-result.txt

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

+ 4 - 0
Tests/RunCMake/alias_targets/set_target_properties-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at set_target_properties.cmake:8 \(set_target_properties\):
+  set_target_properties can not be used on an ALIAS target.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 8 - 0
Tests/RunCMake/alias_targets/set_target_properties.cmake

@@ -0,0 +1,8 @@
+
+enable_language(CXX)
+
+add_library(foo empty.cpp)
+
+add_library(alias ALIAS foo)
+
+set_target_properties(alias PROPERTIES ANYTHING 1)

+ 1 - 0
Tests/RunCMake/alias_targets/target_include_directories-result.txt

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

+ 4 - 0
Tests/RunCMake/alias_targets/target_include_directories-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at target_include_directories.cmake:8 \(target_include_directories\):
+  target_include_directories can not be used on an ALIAS target.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 8 - 0
Tests/RunCMake/alias_targets/target_include_directories.cmake

@@ -0,0 +1,8 @@
+
+enable_language(CXX)
+
+add_library(foo empty.cpp)
+
+add_library(alias ALIAS foo)
+
+target_include_directories(alias PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)

+ 1 - 0
Tests/RunCMake/alias_targets/target_link_libraries-result.txt

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

+ 4 - 0
Tests/RunCMake/alias_targets/target_link_libraries-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at target_link_libraries.cmake:9 \(target_link_libraries\):
+  target_link_libraries can not be used on an ALIAS target.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 9 - 0
Tests/RunCMake/alias_targets/target_link_libraries.cmake

@@ -0,0 +1,9 @@
+
+enable_language(CXX)
+
+add_library(foo empty.cpp)
+add_library(bar empty.cpp)
+
+add_library(alias ALIAS foo)
+
+target_link_libraries(alias bar)