Преглед изворни кода

Merge topic 'use-generator-target'

1c1c2a12 cmGeneratorTarget: Port ExpandLinkItems away from cmTarget.
c66084f5 cmGeneratorTarget: Port GetImportLinkInterface away from cmTarget.
83c29e39 cmGeneratorTarget: Port ComputeLinkImplementationLibraries away from cmTarget.
19882554 cmGeneratorTarget: Port handleSystemIncludesDep away from cmTarget.
c1f687b1 cmGeneratorTarget: Port GetLinkImplementationLibrariesInternal.
a6e1f05c cmGeneratorTarget: Port ComputeLinkInterface away from cmTarget.
654002fe cmGeneratorTarget: Port ComputeLinkInterfaceLibraries away from cmTarget.
922c8901 cmGeneratorTarget: Port GetLinkInterface away from cmTarget.
eaa5b9cb cmGeneratorTarget: Port cmTargetCollectLinkLanguages away from cmTarget.
f539da12 cmGeneratorTarget: Port GetLinkInterfaceLibraries away from cmTarget.
1c5d70f9 cmGeneratorTarget: Port processILibs away from cmTarget.
064c2488 cmComputeLinkDepends: Port some API to cmGeneratorTarget.
3e428fdc cmGeneratorTarget: Move IsImportedSharedLibWithoutSOName from cmTarget.
110fd2fb cmGeneratorTarget: Move GetOutputTargetType from cmTarget.
e7391699 cmGeneratorTarget: Move HasMacOSXRpathInstallNameDir from cmTarget.
c5718217 cmGeneratorTarget: Move HaveInstallTreeRPATH from cmTarget.
...
Brad King пре 10 година
родитељ
комит
aad0e62060

+ 14 - 16
Source/cmComputeLinkDepends.cxx

@@ -268,7 +268,7 @@ cmComputeLinkDepends::Compute()
     {
     {
     int i = *li;
     int i = *li;
     LinkEntry const& e = this->EntryList[i];
     LinkEntry const& e = this->EntryList[i];
-    cmTarget const* t = e.Target;
+    cmGeneratorTarget const* t = e.Target;
     // Entries that we know the linker will re-use do not need to be repeated.
     // Entries that we know the linker will re-use do not need to be repeated.
     bool uniquify = t && t->GetType() == cmTarget::SHARED_LIBRARY;
     bool uniquify = t && t->GetType() == cmTarget::SHARED_LIBRARY;
     if(!uniquify || emmitted.insert(i).second)
     if(!uniquify || emmitted.insert(i).second)
@@ -320,7 +320,8 @@ int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item)
   int index = lei->second;
   int index = lei->second;
   LinkEntry& entry = this->EntryList[index];
   LinkEntry& entry = this->EntryList[index];
   entry.Item = item;
   entry.Item = item;
-  entry.Target = item.Target;
+  entry.Target =
+      item.Target ? this->GlobalGenerator->GetGeneratorTarget(item.Target) : 0;
   entry.IsFlag = (!entry.Target && item[0] == '-' && item[1] != 'l' &&
   entry.IsFlag = (!entry.Target && item[0] == '-' && item[1] != 'l' &&
                   item.substr(0, 10) != "-framework");
                   item.substr(0, 10) != "-framework");
 
 
@@ -362,11 +363,9 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
   // Follow the item's dependencies.
   // Follow the item's dependencies.
   if(entry.Target)
   if(entry.Target)
     {
     {
-    cmGeneratorTarget* gtgt =
-        this->GlobalGenerator->GetGeneratorTarget(entry.Target);
     // Follow the target dependencies.
     // Follow the target dependencies.
     if(cmLinkInterface const* iface =
     if(cmLinkInterface const* iface =
-       gtgt->GetLinkInterface(this->Config, this->Target->Target))
+       entry.Target->GetLinkInterface(this->Config, this->Target))
       {
       {
       const bool isIface =
       const bool isIface =
                       entry.Target->GetType() == cmTarget::INTERFACE_LIBRARY;
                       entry.Target->GetType() == cmTarget::INTERFACE_LIBRARY;
@@ -444,7 +443,9 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
     // Initialize the item entry.
     // Initialize the item entry.
     LinkEntry& entry = this->EntryList[lei->second];
     LinkEntry& entry = this->EntryList[lei->second];
     entry.Item = dep.Item;
     entry.Item = dep.Item;
-    entry.Target = dep.Item.Target;
+    entry.Target =
+        dep.Item.Target ?
+          this->GlobalGenerator->GetGeneratorTarget(dep.Item.Target) : 0;
 
 
     // This item was added specifically because it is a dependent
     // This item was added specifically because it is a dependent
     // shared library.  It may get special treatment
     // shared library.  It may get special treatment
@@ -463,10 +464,8 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
   // Target items may have their own dependencies.
   // Target items may have their own dependencies.
   if(entry.Target)
   if(entry.Target)
     {
     {
-    cmGeneratorTarget* gtgt =
-        this->GlobalGenerator->GetGeneratorTarget(entry.Target);
     if(cmLinkInterface const* iface =
     if(cmLinkInterface const* iface =
-       gtgt->GetLinkInterface(this->Config, this->Target->Target))
+       entry.Target->GetLinkInterface(this->Config, this->Target))
       {
       {
       // Follow public and private dependencies transitively.
       // Follow public and private dependencies transitively.
       this->FollowSharedDeps(index, iface, true);
       this->FollowSharedDeps(index, iface, true);
@@ -639,15 +638,16 @@ cmTarget const* cmComputeLinkDepends::FindTargetToLink(int depender_index,
                                                  const std::string& name)
                                                  const std::string& name)
 {
 {
   // Look for a target in the scope of the depender.
   // Look for a target in the scope of the depender.
-  cmTarget const* from = this->Target->Target;
+  cmGeneratorTarget const* from = this->Target;
   if(depender_index >= 0)
   if(depender_index >= 0)
     {
     {
-    if(cmTarget const* depender = this->EntryList[depender_index].Target)
+    if(cmGeneratorTarget const* depender =
+       this->EntryList[depender_index].Target)
       {
       {
       from = depender;
       from = depender;
       }
       }
     }
     }
-  return from->FindTargetToLink(name);
+  return from->Target->FindTargetToLink(name);
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
@@ -934,12 +934,10 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
   int count = 2;
   int count = 2;
   for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
   for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
     {
     {
-    if(cmTarget const* target = this->EntryList[*ni].Target)
+    if(cmGeneratorTarget const* target = this->EntryList[*ni].Target)
       {
       {
-      cmGeneratorTarget* gtgt =
-          this->GlobalGenerator->GetGeneratorTarget(target);
       if(cmLinkInterface const* iface =
       if(cmLinkInterface const* iface =
-         gtgt->GetLinkInterface(this->Config, this->Target->Target))
+         target->GetLinkInterface(this->Config, this->Target))
         {
         {
         if(iface->Multiplicity > count)
         if(iface->Multiplicity > count)
           {
           {

+ 1 - 2
Source/cmComputeLinkDepends.h

@@ -23,7 +23,6 @@ class cmComputeComponentGraph;
 class cmGlobalGenerator;
 class cmGlobalGenerator;
 class cmMakefile;
 class cmMakefile;
 class cmGeneratorTarget;
 class cmGeneratorTarget;
-class cmTarget;
 class cmake;
 class cmake;
 
 
 /** \class cmComputeLinkDepends
 /** \class cmComputeLinkDepends
@@ -40,7 +39,7 @@ public:
   struct LinkEntry
   struct LinkEntry
   {
   {
     std::string Item;
     std::string Item;
-    cmTarget const* Target;
+    cmGeneratorTarget const* Target;
     bool IsSharedDep;
     bool IsSharedDep;
     bool IsFlag;
     bool IsFlag;
     LinkEntry(): Item(), Target(0), IsSharedDep(false), IsFlag(false) {}
     LinkEntry(): Item(), Target(0), IsSharedDep(false), IsFlag(false) {}

+ 19 - 23
Source/cmComputeLinkInformation.cxx

@@ -632,11 +632,11 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void cmComputeLinkInformation::AddItem(std::string const& item,
 void cmComputeLinkInformation::AddItem(std::string const& item,
-                                       cmTarget const* tgt)
+                                       cmGeneratorTarget const* tgt)
 {
 {
   // Compute the proper name to use to link this library.
   // Compute the proper name to use to link this library.
   const std::string& config = this->Config;
   const std::string& config = this->Config;
-  bool impexe = (tgt && tgt->IsExecutableWithExports());
+  bool impexe = (tgt && tgt->Target->IsExecutableWithExports());
   if(impexe && !this->UseImportLibrary && !this->LoaderFlag)
   if(impexe && !this->UseImportLibrary && !this->LoaderFlag)
     {
     {
     // Skip linking to executables on platforms with no import
     // Skip linking to executables on platforms with no import
@@ -644,9 +644,8 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
     return;
     return;
     }
     }
 
 
-  if(tgt && tgt->IsLinkable())
+  if(tgt && tgt->Target->IsLinkable())
     {
     {
-    cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(tgt);
     // This is a CMake target.  Ask the target for its real name.
     // This is a CMake target.  Ask the target for its real name.
     if(impexe && this->LoaderFlag)
     if(impexe && this->LoaderFlag)
       {
       {
@@ -656,10 +655,10 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
       std::string linkItem;
       std::string linkItem;
       linkItem = this->LoaderFlag;
       linkItem = this->LoaderFlag;
 
 
-      std::string exe = gtgt->GetFullPath(config, this->UseImportLibrary,
+      std::string exe = tgt->GetFullPath(config, this->UseImportLibrary,
                                          true);
                                          true);
       linkItem += exe;
       linkItem += exe;
-      this->Items.push_back(Item(linkItem, true, tgt));
+      this->Items.push_back(Item(linkItem, true, tgt->Target));
       this->Depends.push_back(exe);
       this->Depends.push_back(exe);
       }
       }
     else if(tgt->GetType() == cmTarget::INTERFACE_LIBRARY)
     else if(tgt->GetType() == cmTarget::INTERFACE_LIBRARY)
@@ -667,7 +666,7 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
       // Add the interface library as an item so it can be considered as part
       // Add the interface library as an item so it can be considered as part
       // of COMPATIBLE_INTERFACE_ enforcement.  The generators will ignore
       // of COMPATIBLE_INTERFACE_ enforcement.  The generators will ignore
       // this for the actual link line.
       // this for the actual link line.
-      this->Items.push_back(Item(std::string(), true, tgt));
+      this->Items.push_back(Item(std::string(), true, tgt->Target));
       }
       }
     else
     else
       {
       {
@@ -677,15 +676,15 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
          (impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY));
          (impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY));
 
 
       // Pass the full path to the target file.
       // Pass the full path to the target file.
-      std::string lib = gtgt->GetFullPath(config, implib, true);
+      std::string lib = tgt->GetFullPath(config, implib, true);
       if(!this->LinkDependsNoShared ||
       if(!this->LinkDependsNoShared ||
          tgt->GetType() != cmTarget::SHARED_LIBRARY)
          tgt->GetType() != cmTarget::SHARED_LIBRARY)
         {
         {
         this->Depends.push_back(lib);
         this->Depends.push_back(lib);
         }
         }
 
 
-      this->AddTargetItem(lib, tgt);
-      this->AddLibraryRuntimeInfo(lib, tgt);
+      this->AddTargetItem(lib, tgt->Target);
+      this->AddLibraryRuntimeInfo(lib, tgt->Target);
       }
       }
     }
     }
   else
   else
@@ -716,7 +715,7 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
 void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
-                                                cmTarget const* tgt)
+                                                const cmGeneratorTarget* tgt)
 {
 {
   // If dropping shared library dependencies, ignore them.
   // If dropping shared library dependencies, ignore them.
   if(this->SharedDependencyMode == SharedDepModeNone)
   if(this->SharedDependencyMode == SharedDepModeNone)
@@ -760,18 +759,14 @@ void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
     return;
     return;
     }
     }
 
 
-  cmGeneratorTarget *gtgt = 0;
-
   // Get a full path to the dependent shared library.
   // Get a full path to the dependent shared library.
   // Add it to the runtime path computation so that the target being
   // Add it to the runtime path computation so that the target being
   // linked will be able to find it.
   // linked will be able to find it.
   std::string lib;
   std::string lib;
   if(tgt)
   if(tgt)
     {
     {
-    gtgt = this->GlobalGenerator->GetGeneratorTarget(tgt);
-
-    lib = gtgt->GetFullPath(this->Config, this->UseImportLibrary);
-    this->AddLibraryRuntimeInfo(lib, tgt);
+    lib = tgt->GetFullPath(this->Config, this->UseImportLibrary);
+    this->AddLibraryRuntimeInfo(lib, tgt->Target);
     }
     }
   else
   else
     {
     {
@@ -795,9 +790,9 @@ void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
     }
     }
   if(order)
   if(order)
     {
     {
-    if(gtgt)
+    if(tgt)
       {
       {
-      std::string soName = gtgt->GetSOName(this->Config);
+      std::string soName = tgt->GetSOName(this->Config);
       const char* soname = soName.empty()? 0 : soName.c_str();
       const char* soname = soName.empty()? 0 : soName.c_str();
       order->AddRuntimeLibrary(lib, soname);
       order->AddRuntimeLibrary(lib, soname);
       }
       }
@@ -1101,9 +1096,10 @@ void cmComputeLinkInformation::AddTargetItem(std::string const& item,
     this->SharedLibrariesLinked.insert(target);
     this->SharedLibrariesLinked.insert(target);
     }
     }
 
 
+  cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(target);
   // Handle case of an imported shared library with no soname.
   // Handle case of an imported shared library with no soname.
   if(this->NoSONameUsesPath &&
   if(this->NoSONameUsesPath &&
-     target->IsImportedSharedLibWithoutSOName(this->Config))
+     gtgt->IsImportedSharedLibWithoutSOName(this->Config))
     {
     {
     this->AddSharedLibNoSOName(item);
     this->AddSharedLibNoSOName(item);
     return;
     return;
@@ -1783,12 +1779,13 @@ void
 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
                                                 cmTarget const* target)
                                                 cmTarget const* target)
 {
 {
+  cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(target);
   // Ignore targets on Apple where install_name is not @rpath.
   // Ignore targets on Apple where install_name is not @rpath.
   // The dependenty library can be found with other means such as
   // The dependenty library can be found with other means such as
   // @loader_path or full paths.
   // @loader_path or full paths.
   if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
   if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
     {
     {
-    if(!target->HasMacOSXRpathInstallNameDir(this->Config))
+    if(!gtgt->HasMacOSXRpathInstallNameDir(this->Config))
       {
       {
       return;
       return;
       }
       }
@@ -1810,7 +1807,6 @@ cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
 
 
   // Try to get the soname of the library.  Only files with this name
   // Try to get the soname of the library.  Only files with this name
   // could possibly conflict.
   // could possibly conflict.
-  cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(target);
   std::string soName = gtgt->GetSOName(this->Config);
   std::string soName = gtgt->GetSOName(this->Config);
   const char* soname = soName.empty()? 0 : soName.c_str();
   const char* soname = soName.empty()? 0 : soName.c_str();
 
 
@@ -1920,7 +1916,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
     (for_install ||
     (for_install ||
      this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
      this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
   bool use_install_rpath =
   bool use_install_rpath =
-    (outputRuntime && this->Target->Target->HaveInstallTreeRPATH() &&
+    (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
      linking_for_install);
      linking_for_install);
   bool use_build_rpath =
   bool use_build_rpath =
     (outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) &&
     (outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) &&

+ 2 - 2
Source/cmComputeLinkInformation.h

@@ -62,8 +62,8 @@ public:
   std::string const& GetRPathLinkFlag() const { return this->RPathLinkFlag; }
   std::string const& GetRPathLinkFlag() const { return this->RPathLinkFlag; }
   std::string GetRPathLinkString();
   std::string GetRPathLinkString();
 private:
 private:
-  void AddItem(std::string const& item, cmTarget const* tgt);
-  void AddSharedDepItem(std::string const& item, cmTarget const* tgt);
+  void AddItem(std::string const& item, const cmGeneratorTarget* tgt);
+  void AddSharedDepItem(std::string const& item, cmGeneratorTarget const* tgt);
 
 
   // Output information.
   // Output information.
   ItemVector Items;
   ItemVector Items;

+ 1 - 1
Source/cmComputeTargetDepends.cxx

@@ -297,7 +297,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
   cmGeneratorTarget const* depender = this->Targets[depender_index];
   cmGeneratorTarget const* depender = this->Targets[depender_index];
   if(cmLinkInterface const* iface =
   if(cmLinkInterface const* iface =
                                 dependee->GetLinkInterface(config,
                                 dependee->GetLinkInterface(config,
-                                                           depender->Target))
+                                                           depender))
     {
     {
     for(std::vector<cmLinkItem>::const_iterator
     for(std::vector<cmLinkItem>::const_iterator
         lib = iface->Libraries.begin();
         lib = iface->Libraries.begin();

+ 2 - 2
Source/cmExportFileGenerator.cxx

@@ -803,7 +803,7 @@ cmExportFileGenerator
 {
 {
   // Add the transitive link dependencies for this configuration.
   // Add the transitive link dependencies for this configuration.
   cmLinkInterface const* iface = target->GetLinkInterface(config,
   cmLinkInterface const* iface = target->GetLinkInterface(config,
-                                                          target->Target);
+                                                          target);
   if (!iface)
   if (!iface)
     {
     {
     return;
     return;
@@ -915,7 +915,7 @@ cmExportFileGenerator
 
 
   // Add the transitive link dependencies for this configuration.
   // Add the transitive link dependencies for this configuration.
   if(cmLinkInterface const* iface =
   if(cmLinkInterface const* iface =
-                            target->GetLinkInterface(config, target->Target))
+                            target->GetLinkInterface(config, target))
     {
     {
     this->SetImportLinkProperty(suffix, target,
     this->SetImportLinkProperty(suffix, target,
                                 "IMPORTED_LINK_INTERFACE_LANGUAGES",
                                 "IMPORTED_LINK_INTERFACE_LANGUAGES",

+ 7 - 4
Source/cmGeneratorExpressionNode.cxx

@@ -1109,8 +1109,11 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
 
 
     if(isInterfaceProperty)
     if(isInterfaceProperty)
       {
       {
+      cmGeneratorTarget* gHeadTarget =
+          context->Makefile->GetGlobalGenerator()
+          ->GetGeneratorTarget(headTarget);
       if(cmLinkInterfaceLibraries const* iface =
       if(cmLinkInterfaceLibraries const* iface =
-         gtgt->GetLinkInterfaceLibraries(context->Config, headTarget, true))
+         gtgt->GetLinkInterfaceLibraries(context->Config, gHeadTarget, true))
         {
         {
         linkedTargetsContent =
         linkedTargetsContent =
           getLinkedTargetsContent(iface->Libraries, target,
           getLinkedTargetsContent(iface->Libraries, target,
@@ -1122,7 +1125,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
     else if(!interfacePropertyName.empty())
     else if(!interfacePropertyName.empty())
       {
       {
       if(cmLinkImplementationLibraries const* impl =
       if(cmLinkImplementationLibraries const* impl =
-         target->GetLinkImplementationLibraries(context->Config))
+         gtgt->GetLinkImplementationLibraries(context->Config))
         {
         {
         linkedTargetsContent =
         linkedTargetsContent =
           getLinkedTargetsContent(impl->Libraries, target,
           getLinkedTargetsContent(impl->Libraries, target,
@@ -1586,7 +1589,7 @@ struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
                     "SHARED libraries.");
                     "SHARED libraries.");
       return std::string();
       return std::string();
       }
       }
-    std::string result = target->Target->GetDirectory(context->Config);
+    std::string result = target->GetDirectory(context->Config);
     result += "/";
     result += "/";
     result += target->GetSOName(context->Config);
     result += target->GetSOName(context->Config);
     return result;
     return result;
@@ -1631,7 +1634,7 @@ struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
       return std::string();
       return std::string();
       }
       }
 
 
-    std::string result = target->Target->GetPDBDirectory(context->Config);
+    std::string result = target->GetPDBDirectory(context->Config);
     result += "/";
     result += "/";
     result += target->GetPDBName(context->Config);
     result += target->GetPDBName(context->Config);
     return result;
     return result;

+ 657 - 52
Source/cmGeneratorTarget.cxx

@@ -339,6 +339,62 @@ const char *cmGeneratorTarget::GetProperty(const std::string& prop) const
   return this->Target->GetProperty(prop);
   return this->Target->GetProperty(prop);
 }
 }
 
 
+//----------------------------------------------------------------------------
+const char* cmGeneratorTarget::GetOutputTargetType(bool implib) const
+{
+  switch(this->GetType())
+    {
+    case cmTarget::SHARED_LIBRARY:
+      if(this->Target->IsDLLPlatform())
+        {
+        if(implib)
+          {
+          // A DLL import library is treated as an archive target.
+          return "ARCHIVE";
+          }
+        else
+          {
+          // A DLL shared library is treated as a runtime target.
+          return "RUNTIME";
+          }
+        }
+      else
+        {
+        // For non-DLL platforms shared libraries are treated as
+        // library targets.
+        return "LIBRARY";
+        }
+    case cmTarget::STATIC_LIBRARY:
+      // Static libraries are always treated as archive targets.
+      return "ARCHIVE";
+    case cmTarget::MODULE_LIBRARY:
+      if(implib)
+        {
+        // Module libraries are always treated as library targets.
+        return "ARCHIVE";
+        }
+      else
+        {
+        // Module import libraries are treated as archive targets.
+        return "LIBRARY";
+        }
+    case cmTarget::EXECUTABLE:
+      if(implib)
+        {
+        // Executable import libraries are treated as archive targets.
+        return "ARCHIVE";
+        }
+      else
+        {
+        // Executables are always treated as runtime targets.
+        return "RUNTIME";
+        }
+    default:
+      break;
+    }
+  return "";
+}
+
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 std::string cmGeneratorTarget::GetOutputName(const std::string& config,
 std::string cmGeneratorTarget::GetOutputName(const std::string& config,
                                              bool implib) const
                                              bool implib) const
@@ -355,7 +411,7 @@ std::string cmGeneratorTarget::GetOutputName(const std::string& config,
 
 
     // Compute output name.
     // Compute output name.
     std::vector<std::string> props;
     std::vector<std::string> props;
-    std::string type = this->Target->GetOutputTargetType(implib);
+    std::string type = this->GetOutputTargetType(implib);
     std::string configUpper = cmSystemTools::UpperCase(config);
     std::string configUpper = cmSystemTools::UpperCase(config);
     if(!type.empty() && !configUpper.empty())
     if(!type.empty() && !configUpper.empty())
       {
       {
@@ -402,7 +458,8 @@ std::string cmGeneratorTarget::GetOutputName(const std::string& config,
     {
     {
     // An empty map entry indicates we have been called recursively
     // An empty map entry indicates we have been called recursively
     // from the above block.
     // from the above block.
-    this->Makefile->GetCMakeInstance()->IssueMessage(
+    this->LocalGenerator->GetCMakeInstance()
+          ->IssueMessage(
       cmake::FATAL_ERROR,
       cmake::FATAL_ERROR,
       "Target '" + this->GetName() + "' OUTPUT_NAME depends on itself.",
       "Target '" + this->GetName() + "' OUTPUT_NAME depends on itself.",
       this->Target->GetBacktrace());
       this->Target->GetBacktrace());
@@ -454,7 +511,7 @@ cmGeneratorTarget::GetSourceDepends(cmSourceFile const* sf) const
 
 
 static void handleSystemIncludesDep(cmMakefile *mf, cmTarget const* depTgt,
 static void handleSystemIncludesDep(cmMakefile *mf, cmTarget const* depTgt,
                                   const std::string& config,
                                   const std::string& config,
-                                  cmTarget *headTarget,
+                                  cmGeneratorTarget const* headTarget,
                                   cmGeneratorExpressionDAGChecker *dagChecker,
                                   cmGeneratorExpressionDAGChecker *dagChecker,
                                   std::vector<std::string>& result,
                                   std::vector<std::string>& result,
                                   bool excludeImported)
                                   bool excludeImported)
@@ -465,7 +522,7 @@ static void handleSystemIncludesDep(cmMakefile *mf, cmTarget const* depTgt,
     cmGeneratorExpression ge;
     cmGeneratorExpression ge;
     cmSystemTools::ExpandListArgument(ge.Parse(dirs)
     cmSystemTools::ExpandListArgument(ge.Parse(dirs)
                                       ->Evaluate(mf,
                                       ->Evaluate(mf,
-                                      config, false, headTarget,
+                                      config, false, headTarget->Target,
                                       depTgt, dagChecker), result);
                                       depTgt, dagChecker), result);
     }
     }
   if (!depTgt->IsImported() || excludeImported)
   if (!depTgt->IsImported() || excludeImported)
@@ -479,7 +536,7 @@ static void handleSystemIncludesDep(cmMakefile *mf, cmTarget const* depTgt,
     cmGeneratorExpression ge;
     cmGeneratorExpression ge;
     cmSystemTools::ExpandListArgument(ge.Parse(dirs)
     cmSystemTools::ExpandListArgument(ge.Parse(dirs)
                                       ->Evaluate(mf,
                                       ->Evaluate(mf,
-                                      config, false, headTarget,
+                                      config, false, headTarget->Target,
                                       depTgt, dagChecker), result);
                                       depTgt, dagChecker), result);
     }
     }
 }
 }
@@ -747,7 +804,7 @@ const char* cmGeneratorTarget::GetLocationForBuild() const
     }
     }
 
 
   // Now handle the deprecated build-time configuration location.
   // Now handle the deprecated build-time configuration location.
-  location = this->Target->GetDirectory();
+  location = this->GetDirectory();
   const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
   const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
   if(cfgid && strcmp(cfgid, ".") != 0)
   if(cfgid && strcmp(cfgid, ".") != 0)
     {
     {
@@ -812,7 +869,7 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
     for(std::vector<cmTarget const*>::const_iterator
     for(std::vector<cmTarget const*>::const_iterator
           li = deps.begin(), le = deps.end(); li != le; ++li)
           li = deps.begin(), le = deps.end(); li != le; ++li)
       {
       {
-      handleSystemIncludesDep(this->Makefile, *li, config, this->Target,
+      handleSystemIncludesDep(this->Makefile, *li, config, this,
                               &dagChecker, result, excludeImported);
                               &dagChecker, result, excludeImported);
       }
       }
 
 
@@ -846,7 +903,7 @@ static void AddInterfaceEntries(
   std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
   std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
 {
 {
   if(cmLinkImplementationLibraries const* impl =
   if(cmLinkImplementationLibraries const* impl =
-     thisTarget->Target->GetLinkImplementationLibraries(config))
+     thisTarget->GetLinkImplementationLibraries(config))
     {
     {
     for (std::vector<cmLinkImplItem>::const_iterator
     for (std::vector<cmLinkImplItem>::const_iterator
            it = impl->Libraries.begin(), end = impl->Libraries.end();
            it = impl->Libraries.begin(), end = impl->Libraries.end();
@@ -951,7 +1008,7 @@ static bool processSources(cmGeneratorTarget const* tgt,
       }
       }
     if (!usedSources.empty())
     if (!usedSources.empty())
       {
       {
-      mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
+      tgt->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(cmake::LOG,
                             std::string("Used sources for target ")
                             std::string("Used sources for target ")
                             + tgt->GetName() + ":\n"
                             + tgt->GetName() + ":\n"
                             + usedSources, (*it)->ge->GetBacktrace());
                             + usedSources, (*it)->ge->GetBacktrace());
@@ -1129,7 +1186,7 @@ cmGeneratorTarget::GetCompilePDBPath(const std::string& config) const
   std::string name = this->GetCompilePDBName(config);
   std::string name = this->GetCompilePDBName(config);
   if(dir.empty() && !name.empty())
   if(dir.empty() && !name.empty())
     {
     {
-    dir = this->Target->GetPDBDirectory(config);
+    dir = this->GetPDBDirectory(config);
     }
     }
   if(!dir.empty())
   if(!dir.empty())
     {
     {
@@ -1211,7 +1268,7 @@ cmGeneratorTarget::NeedRelinkBeforeInstall(const std::string& config) const
   // will likely change between the build tree and install tree and
   // will likely change between the build tree and install tree and
   // this target must be relinked.
   // this target must be relinked.
   return this->HaveBuildTreeRPATH(config)
   return this->HaveBuildTreeRPATH(config)
-      || this->Target->HaveInstallTreeRPATH();
+      || this->HaveInstallTreeRPATH();
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
@@ -1281,6 +1338,133 @@ bool cmGeneratorTarget::IsChrpathUsed(const std::string& config) const
   return false;
   return false;
 }
 }
 
 
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsImportedSharedLibWithoutSOName(
+                                          const std::string& config) const
+{
+  if(this->IsImported() && this->GetType() == cmTarget::SHARED_LIBRARY)
+    {
+    if(cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config))
+      {
+      return info->NoSOName;
+      }
+    }
+  return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HasMacOSXRpathInstallNameDir(
+    const std::string& config) const
+{
+  bool install_name_is_rpath = false;
+  bool macosx_rpath = false;
+
+  if(!this->IsImported())
+    {
+    if(this->GetType() != cmTarget::SHARED_LIBRARY)
+      {
+      return false;
+      }
+    const char* install_name = this->GetProperty("INSTALL_NAME_DIR");
+    bool use_install_name =
+      this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH");
+    if(install_name && use_install_name &&
+       std::string(install_name) == "@rpath")
+      {
+      install_name_is_rpath = true;
+      }
+    else if(install_name && use_install_name)
+      {
+      return false;
+      }
+    if(!install_name_is_rpath)
+      {
+      macosx_rpath = this->MacOSXRpathInstallNameDirDefault();
+      }
+    }
+  else
+    {
+    // Lookup the imported soname.
+    if(cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config))
+      {
+      if(!info->NoSOName && !info->SOName.empty())
+        {
+        if(info->SOName.find("@rpath/") == 0)
+          {
+          install_name_is_rpath = true;
+          }
+        }
+      else
+        {
+        std::string install_name;
+        cmSystemTools::GuessLibraryInstallName(info->Location, install_name);
+        if(install_name.find("@rpath") != std::string::npos)
+          {
+          install_name_is_rpath = true;
+          }
+        }
+      }
+    }
+
+  if(!install_name_is_rpath && !macosx_rpath)
+    {
+    return false;
+    }
+
+  if(!this->Makefile->IsSet("CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG"))
+    {
+    std::ostringstream w;
+    w << "Attempting to use";
+    if(macosx_rpath)
+      {
+      w << " MACOSX_RPATH";
+      }
+    else
+      {
+      w << " @rpath";
+      }
+    w << " without CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG being set.";
+    w << "  This could be because you are using a Mac OS X version";
+    w << " less than 10.5 or because CMake's platform configuration is";
+    w << " corrupt.";
+    cmake* cm = this->Makefile->GetCMakeInstance();
+    cm->IssueMessage(cmake::FATAL_ERROR, w.str(),
+                     this->Target->GetBacktrace());
+    }
+
+  return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::MacOSXRpathInstallNameDirDefault() const
+{
+  // we can't do rpaths when unsupported
+  if(!this->Makefile->IsSet("CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG"))
+    {
+    return false;
+    }
+
+  const char* macosx_rpath_str = this->GetProperty("MACOSX_RPATH");
+  if(macosx_rpath_str)
+    {
+    return this->GetPropertyAsBool("MACOSX_RPATH");
+    }
+
+  cmPolicies::PolicyStatus cmp0042 = this->Target->GetPolicyStatusCMP0042();
+
+  if(cmp0042 == cmPolicies::WARN)
+    {
+    this->Makefile->GetGlobalGenerator()->
+      AddCMP0042WarnTarget(this->GetName());
+    }
+
+  if(cmp0042 == cmPolicies::NEW)
+    {
+    return true;
+    }
+
+  return false;
+}
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 std::string cmGeneratorTarget::GetSOName(const std::string& config) const
 std::string cmGeneratorTarget::GetSOName(const std::string& config) const
@@ -1427,13 +1611,13 @@ cmGeneratorTarget::GetInstallNameDirForBuildTree(
      !this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
      !this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
     {
     {
     std::string dir;
     std::string dir;
-    if(this->Target->MacOSXRpathInstallNameDirDefault())
+    if(this->MacOSXRpathInstallNameDirDefault())
       {
       {
       dir = "@rpath";
       dir = "@rpath";
       }
       }
     else
     else
       {
       {
-      dir = this->Target->GetDirectory(config);
+      dir = this->GetDirectory(config);
       }
       }
     dir += "/";
     dir += "/";
     return dir;
     return dir;
@@ -1463,7 +1647,7 @@ std::string cmGeneratorTarget::GetInstallNameDirForInstallTree() const
       }
       }
     if(!install_name_dir)
     if(!install_name_dir)
       {
       {
-      if(this->Target->MacOSXRpathInstallNameDirDefault())
+      if(this->MacOSXRpathInstallNameDirDefault())
         {
         {
         dir = "@rpath/";
         dir = "@rpath/";
         }
         }
@@ -1483,7 +1667,7 @@ public:
   cmTargetCollectLinkLanguages(cmGeneratorTarget const* target,
   cmTargetCollectLinkLanguages(cmGeneratorTarget const* target,
                                const std::string& config,
                                const std::string& config,
                                UNORDERED_SET<std::string>& languages,
                                UNORDERED_SET<std::string>& languages,
-                               cmTarget const* head):
+                               cmGeneratorTarget const* head):
     Config(config), Languages(languages), HeadTarget(head),
     Config(config), Languages(languages), HeadTarget(head),
     Makefile(target->Target->GetMakefile()), Target(target)
     Makefile(target->Target->GetMakefile()), Target(target)
   { this->Visited.insert(target->Target); }
   { this->Visited.insert(target->Target); }
@@ -1521,7 +1705,7 @@ public:
             << "\" but the target was not found.  Perhaps a find_package() "
             << "\" but the target was not found.  Perhaps a find_package() "
             "call is missing for an IMPORTED target, or an ALIAS target is "
             "call is missing for an IMPORTED target, or an ALIAS target is "
             "missing?";
             "missing?";
-          this->Makefile->GetCMakeInstance()->IssueMessage(
+          this->Target->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(
             messageType, e.str(), this->Target->Target->GetBacktrace());
             messageType, e.str(), this->Target->Target->GetBacktrace());
           }
           }
         }
         }
@@ -1553,7 +1737,7 @@ public:
 private:
 private:
   std::string Config;
   std::string Config;
   UNORDERED_SET<std::string>& Languages;
   UNORDERED_SET<std::string>& Languages;
-  cmTarget const* HeadTarget;
+  cmGeneratorTarget const* HeadTarget;
   cmMakefile* Makefile;
   cmMakefile* Makefile;
   const cmGeneratorTarget* Target;
   const cmGeneratorTarget* Target;
   std::set<cmTarget const*> Visited;
   std::set<cmTarget const*> Visited;
@@ -1646,7 +1830,7 @@ void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
     }
     }
 
 
   // Add interface languages from linked targets.
   // Add interface languages from linked targets.
-  cmTargetCollectLinkLanguages cll(this, config, languages, this->Target);
+  cmTargetCollectLinkLanguages cll(this, config, languages, this);
   for(std::vector<cmLinkImplItem>::const_iterator li = impl->Libraries.begin();
   for(std::vector<cmLinkImplItem>::const_iterator li = impl->Libraries.begin();
       li != impl->Libraries.end(); ++li)
       li != impl->Libraries.end(); ++li)
     {
     {
@@ -1734,7 +1918,7 @@ cmGeneratorTarget::GetMacContentDirectory(const std::string& config,
                                           bool implib) const
                                           bool implib) const
 {
 {
   // Start with the output directory for the target.
   // Start with the output directory for the target.
-  std::string fpath = this->Target->GetDirectory(config, implib);
+  std::string fpath = this->GetDirectory(config, implib);
   fpath += "/";
   fpath += "/";
   bool contentOnly = true;
   bool contentOnly = true;
   if(this->Target->IsFrameworkOnApple())
   if(this->Target->IsFrameworkOnApple())
@@ -1779,8 +1963,7 @@ cmGeneratorTarget::CompileInfo const* cmGeneratorTarget::GetCompileInfo(
   if(i == this->CompileInfoMap.end())
   if(i == this->CompileInfoMap.end())
     {
     {
     CompileInfo info;
     CompileInfo info;
-    this->Target
-        ->ComputePDBOutputDir("COMPILE_PDB", config, info.CompilePdbDir);
+    this->ComputePDBOutputDir("COMPILE_PDB", config, info.CompilePdbDir);
     CompileInfoMapType::value_type entry(config_upper, info);
     CompileInfoMapType::value_type entry(config_upper, info);
     i = this->CompileInfoMap.insert(entry).first;
     i = this->CompileInfoMap.insert(entry).first;
     }
     }
@@ -1864,7 +2047,7 @@ void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string> &result,
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void processILibs(const std::string& config,
 void processILibs(const std::string& config,
-                  cmTarget const* headTarget,
+                  cmGeneratorTarget const* headTarget,
                   cmLinkItem const& item,
                   cmLinkItem const& item,
                   cmGlobalGenerator* gg,
                   cmGlobalGenerator* gg,
                   std::vector<cmTarget const*>& tgts,
                   std::vector<cmTarget const*>& tgts,
@@ -1900,13 +2083,13 @@ cmGeneratorTarget::GetLinkImplementationClosure(
     std::set<cmTarget const*> emitted;
     std::set<cmTarget const*> emitted;
 
 
     cmLinkImplementationLibraries const* impl
     cmLinkImplementationLibraries const* impl
-      = this->Target->GetLinkImplementationLibraries(config);
+      = this->GetLinkImplementationLibraries(config);
 
 
     for(std::vector<cmLinkImplItem>::const_iterator
     for(std::vector<cmLinkImplItem>::const_iterator
           it = impl->Libraries.begin();
           it = impl->Libraries.begin();
         it != impl->Libraries.end(); ++it)
         it != impl->Libraries.end(); ++it)
       {
       {
-      processILibs(config, this->Target, *it,
+      processILibs(config, this, *it,
                    this->LocalGenerator->GetGlobalGenerator(),
                    this->LocalGenerator->GetGlobalGenerator(),
                    tgts , emitted);
                    tgts , emitted);
       }
       }
@@ -2444,7 +2627,7 @@ static void processIncludeDirectories(cmGeneratorTarget const* tgt,
       }
       }
     if (!usedIncludes.empty())
     if (!usedIncludes.empty())
       {
       {
-      mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
+      tgt->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(cmake::LOG,
                             std::string("Used includes for target ")
                             std::string("Used includes for target ")
                             + tgt->GetName() + ":\n"
                             + tgt->GetName() + ":\n"
                             + usedIncludes, (*it)->ge->GetBacktrace());
                             + usedIncludes, (*it)->ge->GetBacktrace());
@@ -2500,7 +2683,7 @@ cmGeneratorTarget::GetIncludeDirectories(const std::string& config,
   if(this->Makefile->IsOn("APPLE"))
   if(this->Makefile->IsOn("APPLE"))
     {
     {
     cmLinkImplementationLibraries const* impl =
     cmLinkImplementationLibraries const* impl =
-        this->Target->GetLinkImplementationLibraries(config);
+        this->GetLinkImplementationLibraries(config);
     for(std::vector<cmLinkImplItem>::const_iterator
     for(std::vector<cmLinkImplItem>::const_iterator
         it = impl->Libraries.begin();
         it = impl->Libraries.begin();
         it != impl->Libraries.end(); ++it)
         it != impl->Libraries.end(); ++it)
@@ -2577,7 +2760,7 @@ static void processCompileOptionsInternal(cmGeneratorTarget const* tgt,
       }
       }
     if (!usedOptions.empty())
     if (!usedOptions.empty())
       {
       {
-      mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
+      tgt->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(cmake::LOG,
                             std::string("Used compile ") + logName
                             std::string("Used compile ") + logName
                             + std::string(" for target ")
                             + std::string(" for target ")
                             + tgt->GetName() + ":\n"
                             + tgt->GetName() + ":\n"
@@ -2859,7 +3042,7 @@ void cmGeneratorTarget::ComputeTargetManifest(
     }
     }
 
 
   // Get the directory.
   // Get the directory.
-  std::string dir = this->Target->GetDirectory(config, false);
+  std::string dir = this->GetDirectory(config, false);
 
 
   // Add each name.
   // Add each name.
   std::string f;
   std::string f;
@@ -2893,7 +3076,7 @@ void cmGeneratorTarget::ComputeTargetManifest(
     }
     }
   if(!impName.empty())
   if(!impName.empty())
     {
     {
-    f = this->Target->GetDirectory(config, true);
+    f = this->GetDirectory(config, true);
     f += "/";
     f += "/";
     f += impName;
     f += impName;
     gg->AddToManifest(f);
     gg->AddToManifest(f);
@@ -2918,7 +3101,7 @@ std::string cmGeneratorTarget::NormalGetFullPath(const std::string& config,
                                                  bool implib,
                                                  bool implib,
                                                  bool realname) const
                                                  bool realname) const
 {
 {
-  std::string fpath = this->Target->GetDirectory(config, implib);
+  std::string fpath = this->GetDirectory(config, implib);
   fpath += "/";
   fpath += "/";
   if(this->Target->IsAppBundleOnApple())
   if(this->Target->IsAppBundleOnApple())
     {
     {
@@ -3927,7 +4110,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
                                   .find(p)
                                   .find(p)
                                   != tgt->Target->GetProperties().end();
                                   != tgt->Target->GetProperties().end();
   const bool impliedByUse =
   const bool impliedByUse =
-          tgt->Target->IsNullImpliedByLinkLibraries(p);
+          tgt->IsNullImpliedByLinkLibraries(p);
   assert((impliedByUse ^ explicitlySet)
   assert((impliedByUse ^ explicitlySet)
       || (!impliedByUse && !explicitlySet));
       || (!impliedByUse && !explicitlySet));
 
 
@@ -4212,7 +4395,7 @@ cmGeneratorTarget::ReportPropertyOrigin(const std::string &p,
   areport += result;
   areport += result;
   areport += "\"):\n" + report;
   areport += "\"):\n" + report;
 
 
-  this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG, areport);
+  this->LocalGenerator->GetCMakeInstance()->IssueMessage(cmake::LOG, areport);
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
@@ -4235,7 +4418,7 @@ void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names,
 void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
 void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
                                std::string const& value,
                                std::string const& value,
                                std::string const& config,
                                std::string const& config,
-                               cmTarget const* headTarget,
+                               cmGeneratorTarget const* headTarget,
                                bool usage_requirements_only,
                                bool usage_requirements_only,
                                std::vector<cmLinkItem>& items,
                                std::vector<cmLinkItem>& items,
                                bool& hadHeadSensitiveCondition) const
                                bool& hadHeadSensitiveCondition) const
@@ -4254,7 +4437,7 @@ void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
                                       this->Makefile,
                                       this->Makefile,
                                       config,
                                       config,
                                       false,
                                       false,
-                                      headTarget,
+                                      headTarget->Target,
                                       this->Target, &dagChecker), libs);
                                       this->Target, &dagChecker), libs);
   this->LookupLinkItems(libs, items);
   this->LookupLinkItems(libs, items);
   hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
   hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
@@ -4263,7 +4446,7 @@ void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 cmLinkInterface const*
 cmLinkInterface const*
 cmGeneratorTarget::GetLinkInterface(const std::string& config,
 cmGeneratorTarget::GetLinkInterface(const std::string& config,
-                                    cmTarget const* head) const
+                                    cmGeneratorTarget const* head) const
 {
 {
   // Imported targets have their own link interface.
   // Imported targets have their own link interface.
   if(this->IsImported())
   if(this->IsImported())
@@ -4290,7 +4473,7 @@ cmGeneratorTarget::GetLinkInterface(const std::string& config,
     return &hm.begin()->second;
     return &hm.begin()->second;
     }
     }
 
 
-  cmOptionalLinkInterface& iface = hm[head];
+  cmOptionalLinkInterface& iface = hm[head->Target];
   if(!iface.LibrariesDone)
   if(!iface.LibrariesDone)
     {
     {
     iface.LibrariesDone = true;
     iface.LibrariesDone = true;
@@ -4312,7 +4495,7 @@ cmGeneratorTarget::GetLinkInterface(const std::string& config,
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
 void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
                                     cmOptionalLinkInterface &iface,
                                     cmOptionalLinkInterface &iface,
-                                    cmTarget const* headTarget) const
+                                    cmGeneratorTarget const* headTarget) const
 {
 {
   if(iface.ExplicitLibraries)
   if(iface.ExplicitLibraries)
     {
     {
@@ -4362,8 +4545,8 @@ void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
     {
     {
     // The link implementation is the default link interface.
     // The link implementation is the default link interface.
     cmLinkImplementationLibraries const*
     cmLinkImplementationLibraries const*
-      impl = this->Target->GetLinkImplementationLibrariesInternal(config,
-                                                                headTarget);
+      impl = this->GetLinkImplementationLibrariesInternal(config,
+                                                          headTarget);
     iface.ImplementationIsInterface = true;
     iface.ImplementationIsInterface = true;
     iface.WrongConfigLibraries = impl->WrongConfigLibraries;
     iface.WrongConfigLibraries = impl->WrongConfigLibraries;
     }
     }
@@ -4410,7 +4593,7 @@ void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 const cmLinkInterfaceLibraries *
 const cmLinkInterfaceLibraries *
 cmGeneratorTarget::GetLinkInterfaceLibraries(const std::string& config,
 cmGeneratorTarget::GetLinkInterfaceLibraries(const std::string& config,
-                                    cmTarget const* head,
+                                    cmGeneratorTarget const* head,
                                     bool usage_requirements_only) const
                                     bool usage_requirements_only) const
 {
 {
   // Imported targets have their own link interface.
   // Imported targets have their own link interface.
@@ -4442,7 +4625,7 @@ cmGeneratorTarget::GetLinkInterfaceLibraries(const std::string& config,
     return &hm.begin()->second;
     return &hm.begin()->second;
     }
     }
 
 
-  cmOptionalLinkInterface& iface = hm[head];
+  cmOptionalLinkInterface& iface = hm[head->Target];
   if(!iface.LibrariesDone)
   if(!iface.LibrariesDone)
     {
     {
     iface.LibrariesDone = true;
     iface.LibrariesDone = true;
@@ -4453,12 +4636,262 @@ cmGeneratorTarget::GetLinkInterfaceLibraries(const std::string& config,
   return iface.Exists? &iface : 0;
   return iface.Exists? &iface : 0;
 }
 }
 
 
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetDirectory(const std::string& config,
+                                   bool implib) const
+{
+  if (this->Target->IsImported())
+    {
+    // Return the directory from which the target is imported.
+    return
+      cmSystemTools::GetFilenamePath(
+      this->Target->ImportedGetFullPath(config, implib));
+    }
+  else if(OutputInfo const* info = this->GetOutputInfo(config))
+    {
+    // Return the directory in which the target will be built.
+    return implib? info->ImpDir : info->OutDir;
+    }
+  return "";
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::UsesDefaultOutputDir(const std::string& config,
+                                    bool implib) const
+{
+  std::string dir;
+  return this->ComputeOutputDir(config, implib, dir);
+}
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget::OutputInfo const* cmGeneratorTarget::GetOutputInfo(
+    const std::string& config) const
+{
+  // There is no output information for imported targets.
+  if(this->IsImported())
+    {
+    return 0;
+    }
+
+  // Only libraries and executables have well-defined output files.
+  if(!this->Target->HaveWellDefinedOutputFiles())
+    {
+    std::string msg = "cmGeneratorTarget::GetOutputInfo called for ";
+    msg += this->GetName();
+    msg += " which has type ";
+    msg += cmTarget::GetTargetTypeName(cmTarget::TargetType(this->GetType()));
+    this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR, msg);
+    return 0;
+    }
+
+  // Lookup/compute/cache the output information for this configuration.
+  std::string config_upper;
+  if(!config.empty())
+    {
+    config_upper = cmSystemTools::UpperCase(config);
+    }
+  OutputInfoMapType::iterator i =
+    this->OutputInfoMap.find(config_upper);
+  if(i == this->OutputInfoMap.end())
+    {
+    // Add empty info in map to detect potential recursion.
+    OutputInfo info;
+    OutputInfoMapType::value_type entry(config_upper, info);
+    i = this->OutputInfoMap.insert(entry).first;
+
+    // Compute output directories.
+    this->ComputeOutputDir(config, false, info.OutDir);
+    this->ComputeOutputDir(config, true, info.ImpDir);
+    if(!this->ComputePDBOutputDir("PDB", config, info.PdbDir))
+      {
+      info.PdbDir = info.OutDir;
+      }
+
+    // Now update the previously-prepared map entry.
+    i->second = info;
+    }
+  else if(i->second.empty())
+    {
+    // An empty map entry indicates we have been called recursively
+    // from the above block.
+    this->LocalGenerator->GetCMakeInstance()->IssueMessage(
+      cmake::FATAL_ERROR,
+      "Target '" + this->GetName() + "' OUTPUT_DIRECTORY depends on itself.",
+      this->Target->GetBacktrace());
+    return 0;
+    }
+  return &i->second;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::ComputeOutputDir(const std::string& config,
+                                bool implib, std::string& out) const
+{
+  bool usesDefaultOutputDir = false;
+  std::string conf = config;
+
+  // Look for a target property defining the target output directory
+  // based on the target type.
+  std::string targetTypeName = this->GetOutputTargetType(implib);
+  const char* propertyName = 0;
+  std::string propertyNameStr = targetTypeName;
+  if(!propertyNameStr.empty())
+    {
+    propertyNameStr += "_OUTPUT_DIRECTORY";
+    propertyName = propertyNameStr.c_str();
+    }
+
+  // Check for a per-configuration output directory target property.
+  std::string configUpper = cmSystemTools::UpperCase(conf);
+  const char* configProp = 0;
+  std::string configPropStr = targetTypeName;
+  if(!configPropStr.empty())
+    {
+    configPropStr += "_OUTPUT_DIRECTORY_";
+    configPropStr += configUpper;
+    configProp = configPropStr.c_str();
+    }
+
+  // Select an output directory.
+  if(const char* config_outdir = this->GetProperty(configProp))
+    {
+    // Use the user-specified per-configuration output directory.
+    cmGeneratorExpression ge;
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+      ge.Parse(config_outdir);
+    out = cge->Evaluate(this->Makefile, config);
+
+    // Skip per-configuration subdirectory.
+    conf = "";
+    }
+  else if(const char* outdir = this->Target->GetProperty(propertyName))
+    {
+    // Use the user-specified output directory.
+    cmGeneratorExpression ge;
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+      ge.Parse(outdir);
+    out = cge->Evaluate(this->Makefile, config);
+
+    // Skip per-configuration subdirectory if the value contained a
+    // generator expression.
+    if (out != outdir)
+      {
+      conf = "";
+      }
+    }
+  else if(this->GetType() == cmTarget::EXECUTABLE)
+    {
+    // Lookup the output path for executables.
+    out = this->Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
+    }
+  else if(this->GetType() == cmTarget::STATIC_LIBRARY ||
+          this->GetType() == cmTarget::SHARED_LIBRARY ||
+          this->GetType() == cmTarget::MODULE_LIBRARY)
+    {
+    // Lookup the output path for libraries.
+    out = this->Makefile->GetSafeDefinition("LIBRARY_OUTPUT_PATH");
+    }
+  if(out.empty())
+    {
+    // Default to the current output directory.
+    usesDefaultOutputDir = true;
+    out = ".";
+    }
+
+  // Convert the output path to a full path in case it is
+  // specified as a relative path.  Treat a relative path as
+  // relative to the current output directory for this makefile.
+  out = (cmSystemTools::CollapseFullPath
+         (out, this->Makefile->GetCurrentBinaryDirectory()));
+
+  // The generator may add the configuration's subdirectory.
+  if(!conf.empty())
+    {
+    bool iosPlatform = this->Makefile->PlatformIsAppleIos();
+    std::string suffix =
+      usesDefaultOutputDir && iosPlatform ? "${EFFECTIVE_PLATFORM_NAME}" : "";
+    this->LocalGenerator->GetGlobalGenerator()->
+      AppendDirectoryForConfig("/", conf, suffix, out);
+    }
+
+  return usesDefaultOutputDir;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::ComputePDBOutputDir(const std::string& kind,
+                                   const std::string& config,
+                                   std::string& out) const
+{
+  // Look for a target property defining the target output directory
+  // based on the target type.
+  const char* propertyName = 0;
+  std::string propertyNameStr = kind;
+  if(!propertyNameStr.empty())
+    {
+    propertyNameStr += "_OUTPUT_DIRECTORY";
+    propertyName = propertyNameStr.c_str();
+    }
+  std::string conf = config;
+
+  // Check for a per-configuration output directory target property.
+  std::string configUpper = cmSystemTools::UpperCase(conf);
+  const char* configProp = 0;
+  std::string configPropStr = kind;
+  if(!configPropStr.empty())
+    {
+    configPropStr += "_OUTPUT_DIRECTORY_";
+    configPropStr += configUpper;
+    configProp = configPropStr.c_str();
+    }
+
+  // Select an output directory.
+  if(const char* config_outdir = this->GetProperty(configProp))
+    {
+    // Use the user-specified per-configuration output directory.
+    out = config_outdir;
+
+    // Skip per-configuration subdirectory.
+    conf = "";
+    }
+  else if(const char* outdir = this->GetProperty(propertyName))
+    {
+    // Use the user-specified output directory.
+    out = outdir;
+    }
+  if(out.empty())
+    {
+    return false;
+    }
+
+  // Convert the output path to a full path in case it is
+  // specified as a relative path.  Treat a relative path as
+  // relative to the current output directory for this makefile.
+  out = (cmSystemTools::CollapseFullPath
+         (out, this->Makefile->GetCurrentBinaryDirectory()));
+
+  // The generator may add the configuration's subdirectory.
+  if(!conf.empty())
+    {
+    this->LocalGenerator->GetGlobalGenerator()->
+      AppendDirectoryForConfig("/", conf, "", out);
+    }
+  return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HaveInstallTreeRPATH() const
+{
+  const char* install_rpath = this->GetProperty("INSTALL_RPATH");
+  return (install_rpath && *install_rpath) &&
+          !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH");
+}
+
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void
 void
 cmGeneratorTarget::ComputeLinkInterfaceLibraries(
 cmGeneratorTarget::ComputeLinkInterfaceLibraries(
   const std::string& config,
   const std::string& config,
   cmOptionalLinkInterface& iface,
   cmOptionalLinkInterface& iface,
-  cmTarget const* headTarget,
+  cmGeneratorTarget const* headTarget,
   bool usage_requirements_only) const
   bool usage_requirements_only) const
 {
 {
   // Construct the property name suffix for this configuration.
   // Construct the property name suffix for this configuration.
@@ -4557,8 +4990,7 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
     {
     {
     // The link implementation is the default link interface.
     // The link implementation is the default link interface.
     cmLinkImplementationLibraries const* impl =
     cmLinkImplementationLibraries const* impl =
-      this->Target->GetLinkImplementationLibrariesInternal(config,
-                                                           headTarget);
+      this->GetLinkImplementationLibrariesInternal(config, headTarget);
     iface.Libraries.insert(iface.Libraries.end(),
     iface.Libraries.insert(iface.Libraries.end(),
                            impl->Libraries.begin(), impl->Libraries.end());
                            impl->Libraries.begin(), impl->Libraries.end());
     if(this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
     if(this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
@@ -4572,8 +5004,9 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
         {
         {
         bool hadHeadSensitiveConditionDummy = false;
         bool hadHeadSensitiveConditionDummy = false;
         this->ExpandLinkItems(newProp, newExplicitLibraries, config,
         this->ExpandLinkItems(newProp, newExplicitLibraries, config,
-                                    headTarget, usage_requirements_only,
-                                ifaceLibs, hadHeadSensitiveConditionDummy);
+                              headTarget,
+                              usage_requirements_only,
+                              ifaceLibs, hadHeadSensitiveConditionDummy);
         }
         }
       if (ifaceLibs != iface.Libraries)
       if (ifaceLibs != iface.Libraries)
         {
         {
@@ -4607,7 +5040,7 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 const cmLinkInterface *
 const cmLinkInterface *
 cmGeneratorTarget::GetImportLinkInterface(const std::string& config,
 cmGeneratorTarget::GetImportLinkInterface(const std::string& config,
-                                 cmTarget const* headTarget,
+                                 cmGeneratorTarget const* headTarget,
                                  bool usage_requirements_only) const
                                  bool usage_requirements_only) const
 {
 {
   cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config);
   cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config);
@@ -4629,7 +5062,7 @@ cmGeneratorTarget::GetImportLinkInterface(const std::string& config,
     return &hm.begin()->second;
     return &hm.begin()->second;
     }
     }
 
 
-  cmOptionalLinkInterface& iface = hm[headTarget];
+  cmOptionalLinkInterface& iface = hm[headTarget->Target];
   if(!iface.AllDone)
   if(!iface.AllDone)
     {
     {
     iface.AllDone = true;
     iface.AllDone = true;
@@ -4673,12 +5106,12 @@ cmGeneratorTarget::GetLinkImplementation(const std::string& config) const
     return 0;
     return 0;
     }
     }
 
 
-  cmOptionalLinkImplementation& impl = this->Target->GetLinkImplMap(config);
+  std::string CONFIG = cmSystemTools::UpperCase(config);
+  cmOptionalLinkImplementation& impl = this->LinkImplMap[CONFIG][this->Target];
   if(!impl.LibrariesDone)
   if(!impl.LibrariesDone)
     {
     {
     impl.LibrariesDone = true;
     impl.LibrariesDone = true;
-    this->Target->ComputeLinkImplementationLibraries(config, impl,
-                                                     this->Target);
+    this->ComputeLinkImplementationLibraries(config, impl, this);
     }
     }
   if(!impl.LanguagesDone)
   if(!impl.LanguagesDone)
     {
     {
@@ -4818,9 +5251,181 @@ bool cmGeneratorTarget::HaveBuildTreeRPATH(const std::string& config) const
     return false;
     return false;
     }
     }
   if(cmLinkImplementationLibraries const* impl =
   if(cmLinkImplementationLibraries const* impl =
-     this->Target->GetLinkImplementationLibraries(config))
+     this->GetLinkImplementationLibraries(config))
     {
     {
     return !impl->Libraries.empty();
     return !impl->Libraries.empty();
     }
     }
   return false;
   return false;
 }
 }
+
+//----------------------------------------------------------------------------
+cmLinkImplementationLibraries const*
+cmGeneratorTarget::GetLinkImplementationLibraries(
+    const std::string& config) const
+{
+  return this->GetLinkImplementationLibrariesInternal(config, this);
+}
+
+//----------------------------------------------------------------------------
+cmLinkImplementationLibraries const*
+cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
+    const std::string& config, cmGeneratorTarget const* head) const
+{
+  // There is no link implementation for imported targets.
+  if(this->IsImported())
+    {
+    return 0;
+    }
+
+  // Populate the link implementation libraries for this configuration.
+  std::string CONFIG = cmSystemTools::UpperCase(config);
+  HeadToLinkImplementationMap& hm =
+    this->LinkImplMap[CONFIG];
+
+  // If the link implementation does not depend on the head target
+  // then return the one we computed first.
+  if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
+    {
+    return &hm.begin()->second;
+    }
+
+  cmOptionalLinkImplementation& impl = hm[head->Target];
+  if(!impl.LibrariesDone)
+    {
+    impl.LibrariesDone = true;
+    this->ComputeLinkImplementationLibraries(config, impl, head);
+    }
+  return &impl;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGeneratorTarget::IsNullImpliedByLinkLibraries(const std::string &p) const
+{
+  return this->LinkImplicitNullProperties.find(p)
+      != this->LinkImplicitNullProperties.end();
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeLinkImplementationLibraries(
+  const std::string& config,
+  cmOptionalLinkImplementation& impl,
+  cmGeneratorTarget const* head) const
+{
+  cmStringRange entryRange =
+      this->Target->GetLinkImplementationEntries();
+  cmBacktraceRange btRange =
+      this->Target->GetLinkImplementationBacktraces();
+  cmBacktraceRange::const_iterator btIt = btRange.begin();
+  // Collect libraries directly linked in this configuration.
+  for (cmStringRange::const_iterator le = entryRange.begin(),
+      end = entryRange.end(); le != end; ++le, ++btIt)
+    {
+    std::vector<std::string> llibs;
+    cmGeneratorExpressionDAGChecker dagChecker(
+                                        this->GetName(),
+                                        "LINK_LIBRARIES", 0, 0);
+    cmGeneratorExpression ge(*btIt);
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge =
+      ge.Parse(*le);
+    std::string const evaluated =
+      cge->Evaluate(this->Makefile, config, false, head->Target, &dagChecker);
+    cmSystemTools::ExpandListArgument(evaluated, llibs);
+    if(cge->GetHadHeadSensitiveCondition())
+      {
+      impl.HadHeadSensitiveCondition = true;
+      }
+
+    for(std::vector<std::string>::const_iterator li = llibs.begin();
+        li != llibs.end(); ++li)
+      {
+      // Skip entries that resolve to the target itself or are empty.
+      std::string name = this->Target->CheckCMP0004(*li);
+      if(name == this->GetName() || name.empty())
+        {
+        if(name == this->GetName())
+          {
+          bool noMessage = false;
+          cmake::MessageType messageType = cmake::FATAL_ERROR;
+          std::ostringstream e;
+          switch(this->Target->GetPolicyStatusCMP0038())
+            {
+            case cmPolicies::WARN:
+              {
+              e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0038) << "\n";
+              messageType = cmake::AUTHOR_WARNING;
+              }
+              break;
+            case cmPolicies::OLD:
+              noMessage = true;
+            case cmPolicies::REQUIRED_IF_USED:
+            case cmPolicies::REQUIRED_ALWAYS:
+            case cmPolicies::NEW:
+              // Issue the fatal message.
+              break;
+            }
+
+          if(!noMessage)
+            {
+            e << "Target \"" << this->GetName() << "\" links to itself.";
+            this->LocalGenerator->GetCMakeInstance()->IssueMessage(
+              messageType, e.str(), this->Target->GetBacktrace());
+            if (messageType == cmake::FATAL_ERROR)
+              {
+              return;
+              }
+            }
+          }
+        continue;
+        }
+
+      // The entry is meant for this configuration.
+      impl.Libraries.push_back(
+        cmLinkImplItem(name, this->Target->FindTargetToLink(name),
+                       *btIt, evaluated != *le));
+      }
+
+    std::set<std::string> const& seenProps = cge->GetSeenTargetProperties();
+    for (std::set<std::string>::const_iterator it = seenProps.begin();
+        it != seenProps.end(); ++it)
+      {
+      if (!this->GetProperty(*it))
+        {
+        this->LinkImplicitNullProperties.insert(*it);
+        }
+      }
+    cge->GetMaxLanguageStandard(this->Target,
+                                this->MaxLanguageStandards);
+    }
+
+  cmTarget::LinkLibraryType linkType = this->Target->ComputeLinkType(config);
+  cmTarget::LinkLibraryVectorType const& oldllibs =
+    this->Target->GetOriginalLinkLibraries();
+  for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin();
+      li != oldllibs.end(); ++li)
+    {
+    if(li->second != cmTarget::GENERAL && li->second != linkType)
+      {
+      std::string name = this->Target->CheckCMP0004(li->first);
+      if(name == this->GetName() || name.empty())
+        {
+        continue;
+        }
+      // Support OLD behavior for CMP0003.
+      impl.WrongConfigLibraries.push_back(
+        cmLinkItem(name, this->Target->FindTargetToLink(name)));
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetPDBDirectory(const std::string& config) const
+{
+  if(OutputInfo const* info = this->GetOutputInfo(config))
+    {
+    // Return the directory in which the target will be built.
+    return info->PdbDir;
+    }
+  return "";
+}

+ 87 - 6
Source/cmGeneratorTarget.h

@@ -109,19 +109,19 @@ public:
                          const std::string& config) const;
                          const std::string& config) const;
 
 
   cmLinkInterface const* GetLinkInterface(const std::string& config,
   cmLinkInterface const* GetLinkInterface(const std::string& config,
-                                        cmTarget const* headTarget) const;
+                                    const cmGeneratorTarget* headTarget) const;
   void ComputeLinkInterface(const std::string& config,
   void ComputeLinkInterface(const std::string& config,
                             cmOptionalLinkInterface& iface,
                             cmOptionalLinkInterface& iface,
-                            cmTarget const* head) const;
+                            const cmGeneratorTarget* head) const;
 
 
   cmLinkInterfaceLibraries const*
   cmLinkInterfaceLibraries const*
     GetLinkInterfaceLibraries(const std::string& config,
     GetLinkInterfaceLibraries(const std::string& config,
-                              cmTarget const* headTarget,
+                              const cmGeneratorTarget* headTarget,
                               bool usage_requirements_only) const;
                               bool usage_requirements_only) const;
 
 
   void ComputeLinkInterfaceLibraries(const std::string& config,
   void ComputeLinkInterfaceLibraries(const std::string& config,
                                      cmOptionalLinkInterface &iface,
                                      cmOptionalLinkInterface &iface,
-                                     cmTarget const* head,
+                                     const cmGeneratorTarget* head,
                                      bool usage_requirements_only) const;
                                      bool usage_requirements_only) const;
 
 
   /** Get the full path to the target according to the settings in its
   /** Get the full path to the target according to the settings in its
@@ -207,6 +207,13 @@ public:
                                           cmOptionalLinkImplementation& impl
                                           cmOptionalLinkImplementation& impl
                                           ) const;
                                           ) const;
 
 
+  cmLinkImplementationLibraries const*
+    GetLinkImplementationLibraries(const std::string& config) const;
+
+  void ComputeLinkImplementationLibraries(const std::string& config,
+                                          cmOptionalLinkImplementation& impl,
+                                          const cmGeneratorTarget* head) const;
+
   // Compute the set of languages compiled by the target.  This is
   // Compute the set of languages compiled by the target.  This is
   // computed every time it is called because the languages can change
   // computed every time it is called because the languages can change
   // when source file properties are changed and we do not have enough
   // when source file properties are changed and we do not have enough
@@ -261,6 +268,13 @@ public:
    */
    */
   void TraceDependencies();
   void TraceDependencies();
 
 
+  /** Get the directory in which this target will be built.  If the
+      configuration name is given then the generator will add its
+      subdirectory for that configuration.  Otherwise just the canonical
+      output directory is given.  */
+  std::string GetDirectory(const std::string& config = "",
+                           bool implib = false) const;
+
   /** Get the directory in which to place the target compiler .pdb file.
   /** Get the directory in which to place the target compiler .pdb file.
       If the configuration name is given then the generator will add its
       If the configuration name is given then the generator will add its
       subdirectory for that configuration.  Otherwise just the canonical
       subdirectory for that configuration.  Otherwise just the canonical
@@ -271,6 +285,22 @@ public:
   std::vector<cmSourceFile*> const*
   std::vector<cmSourceFile*> const*
   GetSourceDepends(cmSourceFile const* sf) const;
   GetSourceDepends(cmSourceFile const* sf) const;
 
 
+  /** Return whether this target uses the default value for its output
+      directory.  */
+  bool UsesDefaultOutputDir(const std::string& config, bool implib) const;
+
+  // Cache target output paths for each configuration.
+  struct OutputInfo
+  {
+    std::string OutDir;
+    std::string ImpDir;
+    std::string PdbDir;
+    bool empty() const
+      { return OutDir.empty() && ImpDir.empty() && PdbDir.empty(); }
+  };
+
+  OutputInfo const* GetOutputInfo(const std::string& config) const;
+
   /** Get the name of the pdb file for the target.  */
   /** Get the name of the pdb file for the target.  */
   std::string GetPDBName(const std::string& config="") const;
   std::string GetPDBName(const std::string& config="") const;
 
 
@@ -287,6 +317,8 @@ public:
   typedef std::map<std::string, CompileInfo> CompileInfoMapType;
   typedef std::map<std::string, CompileInfo> CompileInfoMapType;
   mutable CompileInfoMapType CompileInfoMap;
   mutable CompileInfoMapType CompileInfoMap;
 
 
+  bool IsNullImpliedByLinkLibraries(const std::string &p) const;
+
   /** Get the name of the compiler pdb file for the target.  */
   /** Get the name of the compiler pdb file for the target.  */
   std::string GetCompilePDBName(const std::string& config="") const;
   std::string GetCompilePDBName(const std::string& config="") const;
 
 
@@ -345,6 +377,12 @@ public:
   /** Return true if builtin chrpath will work for this target */
   /** Return true if builtin chrpath will work for this target */
   bool IsChrpathUsed(const std::string& config) const;
   bool IsChrpathUsed(const std::string& config) const;
 
 
+  /** Get the directory in which this targets .pdb files will be placed.
+      If the configuration name is given then the generator will add its
+      subdirectory for that configuration.  Otherwise just the canonical
+      pdb output directory is given.  */
+  std::string GetPDBDirectory(const std::string& config) const;
+
   ///! Return the preferred linker language for this target
   ///! Return the preferred linker language for this target
   std::string GetLinkerLanguage(const std::string& config = "") const;
   std::string GetLinkerLanguage(const std::string& config = "") const;
 
 
@@ -369,6 +407,18 @@ public:
 
 
   class TargetPropertyEntry;
   class TargetPropertyEntry;
 
 
+  bool HaveInstallTreeRPATH() const;
+
+  /** Whether this library has \@rpath and platform supports it.  */
+  bool HasMacOSXRpathInstallNameDir(const std::string& config) const;
+
+  /** Whether this library defaults to \@rpath.  */
+  bool MacOSXRpathInstallNameDirDefault() const;
+
+  /** Test for special case of a third-party shared library that has
+      no soname at all.  */
+  bool IsImportedSharedLibWithoutSOName(const std::string& config) const;
+
 private:
 private:
   friend class cmTargetTraceDependencies;
   friend class cmTargetTraceDependencies;
   struct SourceEntry { std::vector<cmSourceFile*> Depends; };
   struct SourceEntry { std::vector<cmSourceFile*> Depends; };
@@ -393,6 +443,9 @@ private:
   typedef std::map<std::string, LinkClosure> LinkClosureMapType;
   typedef std::map<std::string, LinkClosure> LinkClosureMapType;
   mutable LinkClosureMapType LinkClosureMap;
   mutable LinkClosureMapType LinkClosureMap;
 
 
+  // Returns ARCHIVE, LIBRARY, or RUNTIME based on platform and type.
+  const char* GetOutputTargetType(bool implib) const;
+
   struct CompatibleInterfacesBase
   struct CompatibleInterfacesBase
   {
   {
     std::set<std::string> PropsBool;
     std::set<std::string> PropsBool;
@@ -438,7 +491,8 @@ private:
       std::string const& config) const;
       std::string const& config) const;
 
 
   cmLinkInterface const*
   cmLinkInterface const*
-    GetImportLinkInterface(const std::string& config, cmTarget const* head,
+    GetImportLinkInterface(const std::string& config,
+                           const cmGeneratorTarget* head,
                            bool usage_requirements_only) const;
                            bool usage_requirements_only) const;
 
 
   typedef std::map<std::string, std::vector<cmSourceFile*> >
   typedef std::map<std::string, std::vector<cmSourceFile*> >
@@ -450,9 +504,11 @@ private:
   std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
   std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
   std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
   std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
   std::vector<TargetPropertyEntry*> SourceEntries;
   std::vector<TargetPropertyEntry*> SourceEntries;
+  mutable std::set<std::string> LinkImplicitNullProperties;
 
 
   void ExpandLinkItems(std::string const& prop, std::string const& value,
   void ExpandLinkItems(std::string const& prop, std::string const& value,
-                       std::string const& config, cmTarget const* headTarget,
+                       std::string const& config,
+                       const cmGeneratorTarget* headTarget,
                        bool usage_requirements_only,
                        bool usage_requirements_only,
                        std::vector<cmLinkItem>& items,
                        std::vector<cmLinkItem>& items,
                        bool& hadHeadSensitiveCondition) const;
                        bool& hadHeadSensitiveCondition) const;
@@ -462,6 +518,22 @@ private:
   void GetSourceFiles(std::vector<std::string>& files,
   void GetSourceFiles(std::vector<std::string>& files,
                       const std::string& config) const;
                       const std::string& config) const;
 
 
+  struct HeadToLinkImplementationMap:
+    public std::map<cmTarget const*, cmOptionalLinkImplementation> {};
+  typedef std::map<std::string,
+                   HeadToLinkImplementationMap> LinkImplMapType;
+  mutable LinkImplMapType LinkImplMap;
+
+  cmLinkImplementationLibraries const*
+    GetLinkImplementationLibrariesInternal(const std::string& config,
+                                          const cmGeneratorTarget* head) const;
+  bool
+  ComputeOutputDir(const std::string& config,
+                   bool implib, std::string& out) const;
+
+  typedef std::map<std::string, OutputInfo> OutputInfoMapType;
+  mutable OutputInfoMapType OutputInfoMap;
+
   typedef std::pair<std::string, bool> OutputNameKey;
   typedef std::pair<std::string, bool> OutputNameKey;
   typedef std::map<OutputNameKey, std::string> OutputNameMapType;
   typedef std::map<OutputNameKey, std::string> OutputNameMapType;
   mutable OutputNameMapType OutputNameMap;
   mutable OutputNameMapType OutputNameMap;
@@ -473,10 +545,19 @@ private:
   mutable bool DebugSourcesDone;
   mutable bool DebugSourcesDone;
   mutable bool LinkImplementationLanguageIsContextDependent;
   mutable bool LinkImplementationLanguageIsContextDependent;
 
 
+  bool ComputePDBOutputDir(const std::string& kind, const std::string& config,
+                           std::string& out) const;
+
 public:
 public:
   std::vector<cmTarget const*> const&
   std::vector<cmTarget const*> const&
     GetLinkImplementationClosure(const std::string& config) const;
     GetLinkImplementationClosure(const std::string& config) const;
 
 
+  mutable std::map<std::string, std::string> MaxLanguageStandards;
+  std::map<std::string, std::string> const&
+  GetMaxLanguageStandards() const
+  {
+    return this->MaxLanguageStandards;
+  }
 };
 };
 
 
 struct cmStrictTargetComparison {
 struct cmStrictTargetComparison {

+ 3 - 3
Source/cmGlobalXCodeGenerator.cxx

@@ -1976,9 +1976,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
     {
     {
     if(this->XcodeVersion >= 21)
     if(this->XcodeVersion >= 21)
       {
       {
-      if(!target.UsesDefaultOutputDir(configName, false))
+      if(!gtgt->UsesDefaultOutputDir(configName, false))
         {
         {
-        std::string pncdir = target.GetDirectory(configName);
+        std::string pncdir = gtgt->GetDirectory(configName);
         buildSettings->AddAttribute("CONFIGURATION_BUILD_DIR",
         buildSettings->AddAttribute("CONFIGURATION_BUILD_DIR",
                                     this->CreateString(pncdir.c_str()));
                                     this->CreateString(pncdir.c_str()));
         }
         }
@@ -1987,7 +1987,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
       {
       {
       buildSettings->AddAttribute("OBJROOT",
       buildSettings->AddAttribute("OBJROOT",
                                   this->CreateString(pndir.c_str()));
                                   this->CreateString(pndir.c_str()));
-      pndir = target.GetDirectory(configName);
+      pndir = gtgt->GetDirectory(configName);
       }
       }
 
 
     if(target.IsFrameworkOnApple() || target.IsCFBundleOnApple())
     if(target.IsFrameworkOnApple() || target.IsCFBundleOnApple())

+ 1 - 1
Source/cmInstallTargetGenerator.cxx

@@ -83,7 +83,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
   else
   else
     {
     {
     fromDirConfig =
     fromDirConfig =
-        this->Target->Target->GetDirectory(config, this->ImportLibrary);
+        this->Target->GetDirectory(config, this->ImportLibrary);
     fromDirConfig += "/";
     fromDirConfig += "/";
     }
     }
   std::string toDir =
   std::string toDir =

+ 0 - 9
Source/cmListFileCache.h

@@ -111,13 +111,4 @@ struct cmListFile
   std::vector<cmListFileFunction> Functions;
   std::vector<cmListFileFunction> Functions;
 };
 };
 
 
-struct cmValueWithOrigin {
-  cmValueWithOrigin(const std::string &value,
-                          const cmListFileBacktrace &bt)
-    : Value(value), Backtrace(bt)
-  {}
-  std::string Value;
-  cmListFileBacktrace Backtrace;
-};
-
 #endif
 #endif

+ 2 - 2
Source/cmLocalGenerator.cxx

@@ -1152,8 +1152,8 @@ void cmLocalGenerator::AddCompileOptions(
     }
     }
 
 
   for(std::map<std::string, std::string>::const_iterator it
   for(std::map<std::string, std::string>::const_iterator it
-      = target->GetMaxLanguageStandards().begin();
-      it != target->GetMaxLanguageStandards().end(); ++it)
+      = gtgt->GetMaxLanguageStandards().begin();
+      it != gtgt->GetMaxLanguageStandards().end(); ++it)
     {
     {
     const char* standard = target->GetProperty(it->first + "_STANDARD");
     const char* standard = target->GetProperty(it->first + "_STANDARD");
     if(!standard)
     if(!standard)

+ 14 - 10
Source/cmLocalVisualStudio6Generator.cxx

@@ -805,7 +805,11 @@ cmLocalVisualStudio6Generator::MaybeCreateOutputDir(cmTarget& target,
   // VS6 forgets to create the output directory for archives if it
   // VS6 forgets to create the output directory for archives if it
   // differs from the intermediate directory.
   // differs from the intermediate directory.
   if(target.GetType() != cmTarget::STATIC_LIBRARY) { return pcc; }
   if(target.GetType() != cmTarget::STATIC_LIBRARY) { return pcc; }
-  std::string outDir = target.GetDirectory(config, false);
+
+  cmGeneratorTarget* gt =
+    this->GlobalGenerator->GetGeneratorTarget(&target);
+
+  std::string outDir = gt->GetDirectory(config, false);
 
 
   // Add a pre-link event to create the directory.
   // Add a pre-link event to create the directory.
   cmCustomCommandLine command;
   cmCustomCommandLine command;
@@ -1363,20 +1367,20 @@ void cmLocalVisualStudio6Generator
 #ifdef CM_USE_OLD_VS6
 #ifdef CM_USE_OLD_VS6
     outputDirOld =
     outputDirOld =
       removeQuotes(this->ConvertToOutputFormat
       removeQuotes(this->ConvertToOutputFormat
-                   (target.GetDirectory().c_str(), SHELL));
+                   (gt->GetDirectory().c_str(), SHELL));
 #endif
 #endif
     outputDirDebug =
     outputDirDebug =
         removeQuotes(this->ConvertToOutputFormat(
         removeQuotes(this->ConvertToOutputFormat(
-                       target.GetDirectory("Debug").c_str(), SHELL));
+                       gt->GetDirectory("Debug").c_str(), SHELL));
     outputDirRelease =
     outputDirRelease =
         removeQuotes(this->ConvertToOutputFormat(
         removeQuotes(this->ConvertToOutputFormat(
-                 target.GetDirectory("Release").c_str(), SHELL));
+                 gt->GetDirectory("Release").c_str(), SHELL));
     outputDirMinSizeRel =
     outputDirMinSizeRel =
         removeQuotes(this->ConvertToOutputFormat(
         removeQuotes(this->ConvertToOutputFormat(
-                 target.GetDirectory("MinSizeRel").c_str(), SHELL));
+                 gt->GetDirectory("MinSizeRel").c_str(), SHELL));
     outputDirRelWithDebInfo =
     outputDirRelWithDebInfo =
         removeQuotes(this->ConvertToOutputFormat(
         removeQuotes(this->ConvertToOutputFormat(
-                 target.GetDirectory("RelWithDebInfo").c_str(), SHELL));
+                 gt->GetDirectory("RelWithDebInfo").c_str(), SHELL));
     }
     }
   else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
   else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
     {
     {
@@ -1424,12 +1428,12 @@ void cmLocalVisualStudio6Generator
      target.GetType() == cmTarget::MODULE_LIBRARY ||
      target.GetType() == cmTarget::MODULE_LIBRARY ||
      target.GetType() == cmTarget::EXECUTABLE)
      target.GetType() == cmTarget::EXECUTABLE)
     {
     {
-    std::string fullPathImpDebug = target.GetDirectory("Debug", true);
-    std::string fullPathImpRelease = target.GetDirectory("Release", true);
+    std::string fullPathImpDebug = gt->GetDirectory("Debug", true);
+    std::string fullPathImpRelease = gt->GetDirectory("Release", true);
     std::string fullPathImpMinSizeRel =
     std::string fullPathImpMinSizeRel =
-      target.GetDirectory("MinSizeRel", true);
+      gt->GetDirectory("MinSizeRel", true);
     std::string fullPathImpRelWithDebInfo =
     std::string fullPathImpRelWithDebInfo =
-      target.GetDirectory("RelWithDebInfo", true);
+      gt->GetDirectory("RelWithDebInfo", true);
     fullPathImpDebug += "/";
     fullPathImpDebug += "/";
     fullPathImpRelease += "/";
     fullPathImpRelease += "/";
     fullPathImpMinSizeRel += "/";
     fullPathImpMinSizeRel += "/";

+ 9 - 9
Source/cmLocalVisualStudio7Generator.cxx

@@ -792,7 +792,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
     {
     {
     std::string const& outDir =
     std::string const& outDir =
       target.GetType() == cmTarget::OBJECT_LIBRARY?
       target.GetType() == cmTarget::OBJECT_LIBRARY?
-      intermediateDir : target.GetDirectory(configName);
+      intermediateDir : gt->GetDirectory(configName);
     fout << "\t\t\tOutputDirectory=\""
     fout << "\t\t\tOutputDirectory=\""
          << this->ConvertToXMLOutputPathSingle(outDir.c_str()) << "\"\n";
          << this->ConvertToXMLOutputPathSingle(outDir.c_str()) << "\"\n";
     }
     }
@@ -1004,7 +1004,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
 
 
     // Check if we need the FAT32 workaround.
     // Check if we need the FAT32 workaround.
     // Check the filesystem type where the target will be written.
     // Check the filesystem type where the target will be written.
-    if (cmLVS6G_IsFAT(target.GetDirectory(configName).c_str()))
+    if (cmLVS6G_IsFAT(gt->GetDirectory(configName).c_str()))
       {
       {
       // Add a flag telling the manifest tool to use a workaround
       // Add a flag telling the manifest tool to use a workaround
       // for FAT32 file systems, which can cause an empty manifest
       // for FAT32 file systems, which can cause an empty manifest
@@ -1130,7 +1130,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
     case cmTarget::STATIC_LIBRARY:
     case cmTarget::STATIC_LIBRARY:
     {
     {
     std::string targetNameFull = gt->GetFullName(configName);
     std::string targetNameFull = gt->GetFullName(configName);
-    std::string libpath = target.GetDirectory(configName);
+    std::string libpath = gt->GetDirectory(configName);
     libpath += "/";
     libpath += "/";
     libpath += targetNameFull;
     libpath += targetNameFull;
     const char* tool = "VCLibrarianTool";
     const char* tool = "VCLibrarianTool";
@@ -1210,7 +1210,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
     fout << " ";
     fout << " ";
     this->Internal->OutputLibraries(fout, cli.GetItems());
     this->Internal->OutputLibraries(fout, cli.GetItems());
     fout << "\"\n";
     fout << "\"\n";
-    temp = target.GetDirectory(configName);
+    temp = gt->GetDirectory(configName);
     temp += "/";
     temp += "/";
     temp += targetNameFull;
     temp += targetNameFull;
     fout << "\t\t\t\tOutputFile=\""
     fout << "\t\t\t\tOutputFile=\""
@@ -1220,7 +1220,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
     fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
     fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
     this->OutputLibraryDirectories(fout, cli.GetDirectories());
     this->OutputLibraryDirectories(fout, cli.GetDirectories());
     fout << "\"\n";
     fout << "\"\n";
-    temp = target.GetPDBDirectory(configName);
+    temp = gt->GetPDBDirectory(configName);
     temp += "/";
     temp += "/";
     temp += targetNamePDB;
     temp += targetNamePDB;
     fout << "\t\t\t\tProgramDatabaseFile=\"" <<
     fout << "\t\t\t\tProgramDatabaseFile=\"" <<
@@ -1248,7 +1248,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
       {
       {
       fout << "\t\t\t\tStackReserveSize=\"" << stackVal  << "\"\n";
       fout << "\t\t\t\tStackReserveSize=\"" << stackVal  << "\"\n";
       }
       }
-    temp = target.GetDirectory(configName, true);
+    temp = gt->GetDirectory(configName, true);
     temp += "/";
     temp += "/";
     temp += targetNameImport;
     temp += targetNameImport;
     fout << "\t\t\t\tImportLibrary=\""
     fout << "\t\t\t\tImportLibrary=\""
@@ -1309,7 +1309,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
     fout << " ";
     fout << " ";
     this->Internal->OutputLibraries(fout, cli.GetItems());
     this->Internal->OutputLibraries(fout, cli.GetItems());
     fout << "\"\n";
     fout << "\"\n";
-    temp = target.GetDirectory(configName);
+    temp = gt->GetDirectory(configName);
     temp += "/";
     temp += "/";
     temp += targetNameFull;
     temp += targetNameFull;
     fout << "\t\t\t\tOutputFile=\""
     fout << "\t\t\t\tOutputFile=\""
@@ -1320,7 +1320,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
     this->OutputLibraryDirectories(fout, cli.GetDirectories());
     this->OutputLibraryDirectories(fout, cli.GetDirectories());
     fout << "\"\n";
     fout << "\"\n";
     std::string path = this->ConvertToXMLOutputPathSingle(
     std::string path = this->ConvertToXMLOutputPathSingle(
-      target.GetPDBDirectory(configName).c_str());
+      gt->GetPDBDirectory(configName).c_str());
     fout << "\t\t\t\tProgramDatabaseFile=\""
     fout << "\t\t\t\tProgramDatabaseFile=\""
          << path << "/" << targetNamePDB
          << path << "/" << targetNamePDB
          << "\"\n";
          << "\"\n";
@@ -1367,7 +1367,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
       {
       {
       fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"";
       fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"";
       }
       }
-    temp = target.GetDirectory(configName, true);
+    temp = gt->GetDirectory(configName, true);
     temp += "/";
     temp += "/";
     temp += targetNameImport;
     temp += targetNameImport;
     fout << "\t\t\t\tImportLibrary=\""
     fout << "\t\t\t\tImportLibrary=\""

+ 4 - 2
Source/cmLocalVisualStudioGenerator.cxx

@@ -92,8 +92,10 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmTarget& target,
   if(target.GetType() != cmTarget::EXECUTABLE &&
   if(target.GetType() != cmTarget::EXECUTABLE &&
      !(isFortran && target.GetType() == cmTarget::SHARED_LIBRARY))
      !(isFortran && target.GetType() == cmTarget::SHARED_LIBRARY))
     { return pcc; }
     { return pcc; }
-  std::string outDir = target.GetDirectory(config, false);
-  std::string impDir = target.GetDirectory(config, true);
+  cmGeneratorTarget* gt =
+      this->GetGlobalGenerator()->GetGeneratorTarget(&target);
+  std::string outDir = gt->GetDirectory(config, false);
+  std::string impDir = gt->GetDirectory(config, true);
   if(impDir == outDir) { return pcc; }
   if(impDir == outDir) { return pcc; }
 
 
   // Add a pre-build event to create the directory.
   // Add a pre-build event to create the directory.

+ 4 - 2
Source/cmLocalXCodeGenerator.cxx

@@ -56,7 +56,8 @@ void cmLocalXCodeGenerator::Generate()
       iter != targets.end(); ++iter)
       iter != targets.end(); ++iter)
     {
     {
     cmTarget* t = &iter->second;
     cmTarget* t = &iter->second;
-    t->HasMacOSXRpathInstallNameDir("");
+    cmGeneratorTarget* gt = this->GlobalGenerator->GetGeneratorTarget(t);
+    gt->HasMacOSXRpathInstallNameDir("");
     }
     }
 }
 }
 
 
@@ -70,7 +71,8 @@ void cmLocalXCodeGenerator::GenerateInstallRules()
       iter != targets.end(); ++iter)
       iter != targets.end(); ++iter)
     {
     {
     cmTarget* t = &iter->second;
     cmTarget* t = &iter->second;
-    t->HasMacOSXRpathInstallNameDir("");
+    cmGeneratorTarget* gt = this->GlobalGenerator->GetGeneratorTarget(t);
+    gt->HasMacOSXRpathInstallNameDir("");
     }
     }
 }
 }
 
 

+ 4 - 3
Source/cmMakefileExecutableTargetGenerator.cxx

@@ -99,7 +99,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
      this->ConfigName);
      this->ConfigName);
 
 
   // Construct the full path version of the names.
   // Construct the full path version of the names.
-  std::string outpath = this->Target->GetDirectory(this->ConfigName);
+  std::string outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
   if(this->Target->IsAppBundleOnApple())
   if(this->Target->IsAppBundleOnApple())
     {
     {
     this->OSXBundleGenerator->CreateAppBundle(targetName, outpath);
     this->OSXBundleGenerator->CreateAppBundle(targetName, outpath);
@@ -123,7 +123,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
     cmSystemTools::MakeDirectory(outpath.c_str());
     cmSystemTools::MakeDirectory(outpath.c_str());
     if(!targetNameImport.empty())
     if(!targetNameImport.empty())
       {
       {
-      outpathImp = this->Target->GetDirectory(this->ConfigName, true);
+      outpathImp = this->GeneratorTarget->GetDirectory(this->ConfigName, true);
       cmSystemTools::MakeDirectory(outpathImp.c_str());
       cmSystemTools::MakeDirectory(outpathImp.c_str());
       outpathImp += "/";
       outpathImp += "/";
       }
       }
@@ -133,7 +133,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
     this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
     this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
   cmSystemTools::MakeDirectory(compilePdbOutputPath.c_str());
   cmSystemTools::MakeDirectory(compilePdbOutputPath.c_str());
 
 
-  std::string pdbOutputPath = this->Target->GetPDBDirectory(this->ConfigName);
+  std::string pdbOutputPath =
+      this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
   cmSystemTools::MakeDirectory(pdbOutputPath.c_str());
   cmSystemTools::MakeDirectory(pdbOutputPath.c_str());
   pdbOutputPath += "/";
   pdbOutputPath += "/";
 
 

+ 6 - 5
Source/cmMakefileLibraryTargetGenerator.cxx

@@ -275,13 +275,13 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
   std::string outpathImp;
   std::string outpathImp;
   if(this->Target->IsFrameworkOnApple())
   if(this->Target->IsFrameworkOnApple())
     {
     {
-    outpath = this->Target->GetDirectory(this->ConfigName);
+    outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
     this->OSXBundleGenerator->CreateFramework(targetName, outpath);
     this->OSXBundleGenerator->CreateFramework(targetName, outpath);
     outpath += "/";
     outpath += "/";
     }
     }
   else if(this->Target->IsCFBundleOnApple())
   else if(this->Target->IsCFBundleOnApple())
     {
     {
-    outpath = this->Target->GetDirectory(this->ConfigName);
+    outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
     this->OSXBundleGenerator->CreateCFBundle(targetName, outpath);
     this->OSXBundleGenerator->CreateCFBundle(targetName, outpath);
     outpath += "/";
     outpath += "/";
     }
     }
@@ -299,12 +299,12 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
     }
     }
   else
   else
     {
     {
-    outpath = this->Target->GetDirectory(this->ConfigName);
+    outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
     cmSystemTools::MakeDirectory(outpath.c_str());
     cmSystemTools::MakeDirectory(outpath.c_str());
     outpath += "/";
     outpath += "/";
     if(!targetNameImport.empty())
     if(!targetNameImport.empty())
       {
       {
-      outpathImp = this->Target->GetDirectory(this->ConfigName, true);
+      outpathImp = this->GeneratorTarget->GetDirectory(this->ConfigName, true);
       cmSystemTools::MakeDirectory(outpathImp.c_str());
       cmSystemTools::MakeDirectory(outpathImp.c_str());
       outpathImp += "/";
       outpathImp += "/";
       }
       }
@@ -314,7 +314,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
     this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
     this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
   cmSystemTools::MakeDirectory(compilePdbOutputPath.c_str());
   cmSystemTools::MakeDirectory(compilePdbOutputPath.c_str());
 
 
-  std::string pdbOutputPath = this->Target->GetPDBDirectory(this->ConfigName);
+  std::string pdbOutputPath =
+      this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
   cmSystemTools::MakeDirectory(pdbOutputPath.c_str());
   cmSystemTools::MakeDirectory(pdbOutputPath.c_str());
   pdbOutputPath += "/";
   pdbOutputPath += "/";
 
 

+ 2 - 1
Source/cmMakefileTargetGenerator.cxx

@@ -546,7 +546,8 @@ cmMakefileTargetGenerator
     {
     {
     targetFullPathReal =
     targetFullPathReal =
       this->GeneratorTarget->GetFullPath(this->ConfigName, false, true);
       this->GeneratorTarget->GetFullPath(this->ConfigName, false, true);
-    targetFullPathPDB = this->Target->GetPDBDirectory(this->ConfigName);
+    targetFullPathPDB =
+        this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
     targetFullPathPDB += "/";
     targetFullPathPDB += "/";
     targetFullPathPDB += this->GeneratorTarget->GetPDBName(this->ConfigName);
     targetFullPathPDB += this->GeneratorTarget->GetPDBName(this->ConfigName);
     }
     }

+ 4 - 4
Source/cmNinjaNormalTargetGenerator.cxx

@@ -59,7 +59,7 @@ cmNinjaNormalTargetGenerator(cmGeneratorTarget* target)
     {
     {
     // on Windows the output dir is already needed at compile time
     // on Windows the output dir is already needed at compile time
     // ensure the directory exists (OutDir test)
     // ensure the directory exists (OutDir test)
-    EnsureDirectoryExists(target->Target->GetDirectory(this->GetConfigName()));
+    EnsureDirectoryExists(target->GetDirectory(this->GetConfigName()));
     }
     }
 
 
   this->OSXBundleGenerator = new cmOSXBundleGenerator(target,
   this->OSXBundleGenerator = new cmOSXBundleGenerator(target,
@@ -413,7 +413,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
   if (target.IsAppBundleOnApple())
   if (target.IsAppBundleOnApple())
     {
     {
     // Create the app bundle
     // Create the app bundle
-    std::string outpath = target.GetDirectory(cfgName);
+    std::string outpath = gt.GetDirectory(cfgName);
     this->OSXBundleGenerator->CreateAppBundle(this->TargetNameOut, outpath);
     this->OSXBundleGenerator->CreateAppBundle(this->TargetNameOut, outpath);
 
 
     // Calculate the output path
     // Calculate the output path
@@ -430,13 +430,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
     {
     {
     // Create the library framework.
     // Create the library framework.
     this->OSXBundleGenerator->CreateFramework(this->TargetNameOut,
     this->OSXBundleGenerator->CreateFramework(this->TargetNameOut,
-                                              target.GetDirectory(cfgName));
+                                              gt.GetDirectory(cfgName));
     }
     }
   else if(target.IsCFBundleOnApple())
   else if(target.IsCFBundleOnApple())
     {
     {
     // Create the core foundation bundle.
     // Create the core foundation bundle.
     this->OSXBundleGenerator->CreateCFBundle(this->TargetNameOut,
     this->OSXBundleGenerator->CreateCFBundle(this->TargetNameOut,
-                                             target.GetDirectory(cfgName));
+                                             gt.GetDirectory(cfgName));
     }
     }
 
 
   // Write comments.
   // Write comments.

+ 2 - 2
Source/cmNinjaTargetGenerator.cxx

@@ -253,7 +253,7 @@ cmNinjaTargetGenerator
 
 
 std::string cmNinjaTargetGenerator::GetTargetOutputDir() const
 std::string cmNinjaTargetGenerator::GetTargetOutputDir() const
 {
 {
-  std::string dir = this->Target->GetDirectory(this->GetConfigName());
+  std::string dir = this->GeneratorTarget->GetDirectory(this->GetConfigName());
   return ConvertToNinjaPath(dir);
   return ConvertToNinjaPath(dir);
 }
 }
 
 
@@ -288,7 +288,7 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const
        this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
        this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
        this->Target->GetType() == cmTarget::MODULE_LIBRARY)
        this->Target->GetType() == cmTarget::MODULE_LIBRARY)
       {
       {
-      pdbPath = this->Target->GetPDBDirectory(this->GetConfigName());
+      pdbPath = this->GeneratorTarget->GetPDBDirectory(this->GetConfigName());
       pdbPath += "/";
       pdbPath += "/";
       pdbPath += this->GeneratorTarget->GetPDBName(this->GetConfigName());
       pdbPath += this->GeneratorTarget->GetPDBName(this->GetConfigName());
       }
       }

+ 18 - 653
Source/cmTarget.cxx

@@ -60,16 +60,6 @@ const char* cmTarget::GetTargetTypeName(TargetType targetType)
   return 0;
   return 0;
 }
 }
 
 
-//----------------------------------------------------------------------------
-struct cmTarget::OutputInfo
-{
-  std::string OutDir;
-  std::string ImpDir;
-  std::string PdbDir;
-  bool empty() const
-    { return OutDir.empty() && ImpDir.empty() && PdbDir.empty(); }
-};
-
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 class cmTargetInternals
 class cmTargetInternals
 {
 {
@@ -89,18 +79,9 @@ public:
   // The backtrace when the target was created.
   // The backtrace when the target was created.
   cmListFileBacktrace Backtrace;
   cmListFileBacktrace Backtrace;
 
 
-  typedef std::map<std::string, cmTarget::OutputInfo> OutputInfoMapType;
-  OutputInfoMapType OutputInfoMap;
-
   typedef std::map<std::string, cmTarget::ImportInfo> ImportInfoMapType;
   typedef std::map<std::string, cmTarget::ImportInfo> ImportInfoMapType;
   ImportInfoMapType ImportInfoMap;
   ImportInfoMapType ImportInfoMap;
 
 
-  struct HeadToLinkImplementationMap:
-    public std::map<cmTarget const*, cmOptionalLinkImplementation> {};
-  typedef std::map<std::string,
-                   HeadToLinkImplementationMap> LinkImplMapType;
-  LinkImplMapType LinkImplMap;
-
   std::set<cmLinkItem> UtilityItems;
   std::set<cmLinkItem> UtilityItems;
   bool UtilityItemsDone;
   bool UtilityItemsDone;
 
 
@@ -114,7 +95,8 @@ public:
   std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
   std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
   std::vector<std::string> SourceEntries;
   std::vector<std::string> SourceEntries;
   std::vector<cmListFileBacktrace> SourceBacktraces;
   std::vector<cmListFileBacktrace> SourceBacktraces;
-  std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries;
+  std::vector<std::string> LinkImplementationPropertyEntries;
+  std::vector<cmListFileBacktrace> LinkImplementationPropertyBacktraces;
 };
 };
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
@@ -404,7 +386,6 @@ void cmTarget::FinishConfigure()
   // on-demand during the configuration.  This ensures that build
   // on-demand during the configuration.  This ensures that build
   // system generation uses up-to-date information even if other cache
   // system generation uses up-to-date information even if other cache
   // invalidation code in this source file is buggy.
   // invalidation code in this source file is buggy.
-  this->ClearLinkMaps();
 
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
 #if defined(_WIN32) && !defined(__CYGWIN__)
   // Do old-style link dependency analysis only for CM_USE_OLD_VS6.
   // Do old-style link dependency analysis only for CM_USE_OLD_VS6.
@@ -415,12 +396,6 @@ void cmTarget::FinishConfigure()
 #endif
 #endif
 }
 }
 
 
-//----------------------------------------------------------------------------
-void cmTarget::ClearLinkMaps()
-{
-  this->Internal->LinkImplMap.clear();
-}
-
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 cmListFileBacktrace const& cmTarget::GetBacktrace() const
 cmListFileBacktrace const& cmTarget::GetBacktrace() const
 {
 {
@@ -883,7 +858,6 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
   this->LinkLibrariesForVS6.push_back( tmp );
   this->LinkLibrariesForVS6.push_back( tmp );
 #endif
 #endif
   this->OriginalLinkLibraries.push_back(tmp);
   this->OriginalLinkLibraries.push_back(tmp);
-  this->ClearLinkMaps();
 
 
   // Add the explicit dependency information for this target. This is
   // Add the explicit dependency information for this target. This is
   // simply a set of libraries separated by ";". There should always
   // simply a set of libraries separated by ";". There should always
@@ -982,6 +956,16 @@ cmBacktraceRange cmTarget::GetSourceBacktraces() const
   return cmMakeRange(this->Internal->SourceBacktraces);
   return cmMakeRange(this->Internal->SourceBacktraces);
 }
 }
 
 
+cmStringRange cmTarget::GetLinkImplementationEntries() const
+{
+  return cmMakeRange(this->Internal->LinkImplementationPropertyEntries);
+}
+
+cmBacktraceRange cmTarget::GetLinkImplementationBacktraces() const
+{
+  return cmMakeRange(this->Internal->LinkImplementationPropertyBacktraces);
+}
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
 #if defined(_WIN32) && !defined(__CYGWIN__)
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void
 void
@@ -1380,11 +1364,12 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
   else if (prop == "LINK_LIBRARIES")
   else if (prop == "LINK_LIBRARIES")
     {
     {
     this->Internal->LinkImplementationPropertyEntries.clear();
     this->Internal->LinkImplementationPropertyEntries.clear();
+    this->Internal->LinkImplementationPropertyBacktraces.clear();
     if (value)
     if (value)
       {
       {
       cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
       cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-      cmValueWithOrigin entry(value, lfbt);
-      this->Internal->LinkImplementationPropertyEntries.push_back(entry);
+      this->Internal->LinkImplementationPropertyEntries.push_back(value);
+      this->Internal->LinkImplementationPropertyBacktraces.push_back(lfbt);
       }
       }
     }
     }
   else if (prop == "SOURCES")
   else if (prop == "SOURCES")
@@ -1482,8 +1467,8 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
     if (value && *value)
     if (value && *value)
       {
       {
       cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
       cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
-      cmValueWithOrigin entry(value, lfbt);
-      this->Internal->LinkImplementationPropertyEntries.push_back(entry);
+      this->Internal->LinkImplementationPropertyEntries.push_back(value);
+      this->Internal->LinkImplementationPropertyBacktraces.push_back(lfbt);
       }
       }
     }
     }
   else if (prop == "SOURCES")
   else if (prop == "SOURCES")
@@ -1609,10 +1594,6 @@ void cmTarget::MaybeInvalidatePropertyCache(const std::string& prop)
     {
     {
     this->Internal->ImportInfoMap.clear();
     this->Internal->ImportInfoMap.clear();
     }
     }
-  if(!this->IsImported() && cmHasLiteralPrefix(prop, "LINK_INTERFACE_"))
-    {
-    this->ClearLinkMaps();
-    }
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
@@ -1725,97 +1706,6 @@ bool cmTarget::HaveWellDefinedOutputFiles() const
     this->GetType() == cmTarget::EXECUTABLE;
     this->GetType() == cmTarget::EXECUTABLE;
 }
 }
 
 
-//----------------------------------------------------------------------------
-cmTarget::OutputInfo const* cmTarget::GetOutputInfo(
-    const std::string& config) const
-{
-  // There is no output information for imported targets.
-  if(this->IsImported())
-    {
-    return 0;
-    }
-
-  // Only libraries and executables have well-defined output files.
-  if(!this->HaveWellDefinedOutputFiles())
-    {
-    std::string msg = "cmTarget::GetOutputInfo called for ";
-    msg += this->GetName();
-    msg += " which has type ";
-    msg += cmTarget::GetTargetTypeName(this->GetType());
-    this->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR, msg);
-    return 0;
-    }
-
-  // Lookup/compute/cache the output information for this configuration.
-  std::string config_upper;
-  if(!config.empty())
-    {
-    config_upper = cmSystemTools::UpperCase(config);
-    }
-  typedef cmTargetInternals::OutputInfoMapType OutputInfoMapType;
-  OutputInfoMapType::iterator i =
-    this->Internal->OutputInfoMap.find(config_upper);
-  if(i == this->Internal->OutputInfoMap.end())
-    {
-    // Add empty info in map to detect potential recursion.
-    OutputInfo info;
-    OutputInfoMapType::value_type entry(config_upper, info);
-    i = this->Internal->OutputInfoMap.insert(entry).first;
-
-    // Compute output directories.
-    this->ComputeOutputDir(config, false, info.OutDir);
-    this->ComputeOutputDir(config, true, info.ImpDir);
-    if(!this->ComputePDBOutputDir("PDB", config, info.PdbDir))
-      {
-      info.PdbDir = info.OutDir;
-      }
-
-    // Now update the previously-prepared map entry.
-    i->second = info;
-    }
-  else if(i->second.empty())
-    {
-    // An empty map entry indicates we have been called recursively
-    // from the above block.
-    this->Makefile->GetCMakeInstance()->IssueMessage(
-      cmake::FATAL_ERROR,
-      "Target '" + this->GetName() + "' OUTPUT_DIRECTORY depends on itself.",
-      this->GetBacktrace());
-    return 0;
-    }
-  return &i->second;
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetDirectory(const std::string& config,
-                                   bool implib) const
-{
-  if (this->IsImported())
-    {
-    // Return the directory from which the target is imported.
-    return
-      cmSystemTools::GetFilenamePath(
-      this->ImportedGetFullPath(config, implib));
-    }
-  else if(OutputInfo const* info = this->GetOutputInfo(config))
-    {
-    // Return the directory in which the target will be built.
-    return implib? info->ImpDir : info->OutDir;
-    }
-  return "";
-}
-
-//----------------------------------------------------------------------------
-std::string cmTarget::GetPDBDirectory(const std::string& config) const
-{
-  if(OutputInfo const* info = this->GetOutputInfo(config))
-    {
-    // Return the directory in which the target will be built.
-    return info->PdbDir;
-    }
-  return "";
-}
-
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 const char* cmTarget::ImportedGetLocation(const std::string& config) const
 const char* cmTarget::ImportedGetLocation(const std::string& config) const
 {
 {
@@ -2048,17 +1938,7 @@ const char *cmTarget::GetProperty(const std::string& prop,
         }
         }
 
 
       static std::string output;
       static std::string output;
-      output = "";
-      std::string sep;
-      for (std::vector<cmValueWithOrigin>::const_iterator
-          it = this->Internal->LinkImplementationPropertyEntries.begin(),
-          end = this->Internal->LinkImplementationPropertyEntries.end();
-          it != end; ++it)
-        {
-        output += sep;
-        output += it->Value;
-        sep = ";";
-        }
+      output = cmJoin(this->Internal->LinkImplementationPropertyEntries, ";");
       return output.c_str();
       return output.c_str();
       }
       }
     // the type property returns what type the target is
     // the type property returns what type the target is
@@ -2297,132 +2177,6 @@ const char* cmTarget::GetPrefixVariableInternal(bool implib) const
   return "";
   return "";
 }
 }
 
 
-//----------------------------------------------------------------------------
-bool cmTarget::HasMacOSXRpathInstallNameDir(const std::string& config) const
-{
-  bool install_name_is_rpath = false;
-  bool macosx_rpath = false;
-
-  if(!this->IsImportedTarget)
-    {
-    if(this->GetType() != cmTarget::SHARED_LIBRARY)
-      {
-      return false;
-      }
-    const char* install_name = this->GetProperty("INSTALL_NAME_DIR");
-    bool use_install_name =
-      this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH");
-    if(install_name && use_install_name &&
-       std::string(install_name) == "@rpath")
-      {
-      install_name_is_rpath = true;
-      }
-    else if(install_name && use_install_name)
-      {
-      return false;
-      }
-    if(!install_name_is_rpath)
-      {
-      macosx_rpath = this->MacOSXRpathInstallNameDirDefault();
-      }
-    }
-  else
-    {
-    // Lookup the imported soname.
-    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
-      {
-      if(!info->NoSOName && !info->SOName.empty())
-        {
-        if(info->SOName.find("@rpath/") == 0)
-          {
-          install_name_is_rpath = true;
-          }
-        }
-      else
-        {
-        std::string install_name;
-        cmSystemTools::GuessLibraryInstallName(info->Location, install_name);
-        if(install_name.find("@rpath") != std::string::npos)
-          {
-          install_name_is_rpath = true;
-          }
-        }
-      }
-    }
-
-  if(!install_name_is_rpath && !macosx_rpath)
-    {
-    return false;
-    }
-
-  if(!this->Makefile->IsSet("CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG"))
-    {
-    std::ostringstream w;
-    w << "Attempting to use";
-    if(macosx_rpath)
-      {
-      w << " MACOSX_RPATH";
-      }
-    else
-      {
-      w << " @rpath";
-      }
-    w << " without CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG being set.";
-    w << "  This could be because you are using a Mac OS X version";
-    w << " less than 10.5 or because CMake's platform configuration is";
-    w << " corrupt.";
-    cmake* cm = this->Makefile->GetCMakeInstance();
-    cm->IssueMessage(cmake::FATAL_ERROR, w.str(), this->GetBacktrace());
-    }
-
-  return true;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::MacOSXRpathInstallNameDirDefault() const
-{
-  // we can't do rpaths when unsupported
-  if(!this->Makefile->IsSet("CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG"))
-    {
-    return false;
-    }
-
-  const char* macosx_rpath_str = this->GetProperty("MACOSX_RPATH");
-  if(macosx_rpath_str)
-    {
-    return this->GetPropertyAsBool("MACOSX_RPATH");
-    }
-
-  cmPolicies::PolicyStatus cmp0042 = this->GetPolicyStatusCMP0042();
-
-  if(cmp0042 == cmPolicies::WARN)
-    {
-    this->Makefile->GetGlobalGenerator()->
-      AddCMP0042WarnTarget(this->GetName());
-    }
-
-  if(cmp0042 == cmPolicies::NEW)
-    {
-    return true;
-    }
-
-  return false;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::IsImportedSharedLibWithoutSOName(
-                                          const std::string& config) const
-{
-  if(this->IsImported() && this->GetType() == cmTarget::SHARED_LIBRARY)
-    {
-    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
-      {
-      return info->NoSOName;
-      }
-    }
-  return false;
-}
-
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 std::string
 std::string
 cmTarget::GetFullNameImported(const std::string& config, bool implib) const
 cmTarget::GetFullNameImported(const std::string& config, bool implib) const
@@ -2503,233 +2257,6 @@ void cmTarget::SetPropertyDefault(const std::string& property,
     }
     }
 }
 }
 
 
-//----------------------------------------------------------------------------
-bool cmTarget::HaveInstallTreeRPATH() const
-{
-  const char* install_rpath = this->GetProperty("INSTALL_RPATH");
-  return (install_rpath && *install_rpath) &&
-          !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH");
-}
-
-//----------------------------------------------------------------------------
-const char* cmTarget::GetOutputTargetType(bool implib) const
-{
-  switch(this->GetType())
-    {
-    case cmTarget::SHARED_LIBRARY:
-      if(this->DLLPlatform)
-        {
-        if(implib)
-          {
-          // A DLL import library is treated as an archive target.
-          return "ARCHIVE";
-          }
-        else
-          {
-          // A DLL shared library is treated as a runtime target.
-          return "RUNTIME";
-          }
-        }
-      else
-        {
-        // For non-DLL platforms shared libraries are treated as
-        // library targets.
-        return "LIBRARY";
-        }
-    case cmTarget::STATIC_LIBRARY:
-      // Static libraries are always treated as archive targets.
-      return "ARCHIVE";
-    case cmTarget::MODULE_LIBRARY:
-      if(implib)
-        {
-        // Module libraries are always treated as library targets.
-        return "ARCHIVE";
-        }
-      else
-        {
-        // Module import libraries are treated as archive targets.
-        return "LIBRARY";
-        }
-    case cmTarget::EXECUTABLE:
-      if(implib)
-        {
-        // Executable import libraries are treated as archive targets.
-        return "ARCHIVE";
-        }
-      else
-        {
-        // Executables are always treated as runtime targets.
-        return "RUNTIME";
-        }
-    default:
-      break;
-    }
-  return "";
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::ComputeOutputDir(const std::string& config,
-                                bool implib, std::string& out) const
-{
-  bool usesDefaultOutputDir = false;
-  std::string conf = config;
-
-  // Look for a target property defining the target output directory
-  // based on the target type.
-  std::string targetTypeName = this->GetOutputTargetType(implib);
-  const char* propertyName = 0;
-  std::string propertyNameStr = targetTypeName;
-  if(!propertyNameStr.empty())
-    {
-    propertyNameStr += "_OUTPUT_DIRECTORY";
-    propertyName = propertyNameStr.c_str();
-    }
-
-  // Check for a per-configuration output directory target property.
-  std::string configUpper = cmSystemTools::UpperCase(conf);
-  const char* configProp = 0;
-  std::string configPropStr = targetTypeName;
-  if(!configPropStr.empty())
-    {
-    configPropStr += "_OUTPUT_DIRECTORY_";
-    configPropStr += configUpper;
-    configProp = configPropStr.c_str();
-    }
-
-  // Select an output directory.
-  if(const char* config_outdir = this->GetProperty(configProp))
-    {
-    // Use the user-specified per-configuration output directory.
-    cmGeneratorExpression ge;
-    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
-      ge.Parse(config_outdir);
-    out = cge->Evaluate(this->Makefile, config);
-
-    // Skip per-configuration subdirectory.
-    conf = "";
-    }
-  else if(const char* outdir = this->GetProperty(propertyName))
-    {
-    // Use the user-specified output directory.
-    cmGeneratorExpression ge;
-    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
-      ge.Parse(outdir);
-    out = cge->Evaluate(this->Makefile, config);
-
-    // Skip per-configuration subdirectory if the value contained a
-    // generator expression.
-    if (out != outdir)
-      {
-      conf = "";
-      }
-    }
-  else if(this->GetType() == cmTarget::EXECUTABLE)
-    {
-    // Lookup the output path for executables.
-    out = this->Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
-    }
-  else if(this->GetType() == cmTarget::STATIC_LIBRARY ||
-          this->GetType() == cmTarget::SHARED_LIBRARY ||
-          this->GetType() == cmTarget::MODULE_LIBRARY)
-    {
-    // Lookup the output path for libraries.
-    out = this->Makefile->GetSafeDefinition("LIBRARY_OUTPUT_PATH");
-    }
-  if(out.empty())
-    {
-    // Default to the current output directory.
-    usesDefaultOutputDir = true;
-    out = ".";
-    }
-
-  // Convert the output path to a full path in case it is
-  // specified as a relative path.  Treat a relative path as
-  // relative to the current output directory for this makefile.
-  out = (cmSystemTools::CollapseFullPath
-         (out, this->Makefile->GetCurrentBinaryDirectory()));
-
-  // The generator may add the configuration's subdirectory.
-  if(!conf.empty())
-    {
-    bool iosPlatform = this->Makefile->PlatformIsAppleIos();
-    std::string suffix =
-      usesDefaultOutputDir && iosPlatform ? "${EFFECTIVE_PLATFORM_NAME}" : "";
-    this->Makefile->GetGlobalGenerator()->
-      AppendDirectoryForConfig("/", conf, suffix, out);
-    }
-
-  return usesDefaultOutputDir;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::ComputePDBOutputDir(const std::string& kind,
-                                   const std::string& config,
-                                   std::string& out) const
-{
-  // Look for a target property defining the target output directory
-  // based on the target type.
-  const char* propertyName = 0;
-  std::string propertyNameStr = kind;
-  if(!propertyNameStr.empty())
-    {
-    propertyNameStr += "_OUTPUT_DIRECTORY";
-    propertyName = propertyNameStr.c_str();
-    }
-  std::string conf = config;
-
-  // Check for a per-configuration output directory target property.
-  std::string configUpper = cmSystemTools::UpperCase(conf);
-  const char* configProp = 0;
-  std::string configPropStr = kind;
-  if(!configPropStr.empty())
-    {
-    configPropStr += "_OUTPUT_DIRECTORY_";
-    configPropStr += configUpper;
-    configProp = configPropStr.c_str();
-    }
-
-  // Select an output directory.
-  if(const char* config_outdir = this->GetProperty(configProp))
-    {
-    // Use the user-specified per-configuration output directory.
-    out = config_outdir;
-
-    // Skip per-configuration subdirectory.
-    conf = "";
-    }
-  else if(const char* outdir = this->GetProperty(propertyName))
-    {
-    // Use the user-specified output directory.
-    out = outdir;
-    }
-  if(out.empty())
-    {
-    return false;
-    }
-
-  // Convert the output path to a full path in case it is
-  // specified as a relative path.  Treat a relative path as
-  // relative to the current output directory for this makefile.
-  out = (cmSystemTools::CollapseFullPath
-         (out, this->Makefile->GetCurrentBinaryDirectory()));
-
-  // The generator may add the configuration's subdirectory.
-  if(!conf.empty())
-    {
-    this->Makefile->GetGlobalGenerator()->
-      AppendDirectoryForConfig("/", conf, "", out);
-    }
-  return true;
-}
-
-//----------------------------------------------------------------------------
-bool cmTarget::UsesDefaultOutputDir(const std::string& config,
-                                    bool implib) const
-{
-  std::string dir;
-  return this->ComputeOutputDir(config, implib, dir);
-}
-
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 std::string cmTarget::GetFrameworkVersion() const
 std::string cmTarget::GetFrameworkVersion() const
 {
 {
@@ -2775,13 +2302,6 @@ const char* cmTarget::GetExportMacro() const
     }
     }
 }
 }
 
 
-//----------------------------------------------------------------------------
-bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p) const
-{
-  return this->LinkImplicitNullProperties.find(p)
-      != this->LinkImplicitNullProperties.end();
-}
-
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void
 void
 cmTarget::GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const
 cmTarget::GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const
@@ -3170,161 +2690,6 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
     }
     }
 }
 }
 
 
-cmOptionalLinkImplementation&
-cmTarget::GetLinkImplMap(std::string const& config) const
-{
-  // Populate the link implementation for this configuration.
-  std::string CONFIG = cmSystemTools::UpperCase(config);
-  return Internal->LinkImplMap[CONFIG][this];
-}
-
-//----------------------------------------------------------------------------
-cmLinkImplementationLibraries const*
-cmTarget::GetLinkImplementationLibraries(const std::string& config) const
-{
-  return this->GetLinkImplementationLibrariesInternal(config, this);
-}
-
-//----------------------------------------------------------------------------
-cmLinkImplementationLibraries const*
-cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config,
-                                                 cmTarget const* head) const
-{
-  // There is no link implementation for imported targets.
-  if(this->IsImported())
-    {
-    return 0;
-    }
-
-  // Populate the link implementation libraries for this configuration.
-  std::string CONFIG = cmSystemTools::UpperCase(config);
-  cmTargetInternals::HeadToLinkImplementationMap& hm =
-    this->Internal->LinkImplMap[CONFIG];
-
-  // If the link implementation does not depend on the head target
-  // then return the one we computed first.
-  if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
-    {
-    return &hm.begin()->second;
-    }
-
-  cmOptionalLinkImplementation& impl = hm[head];
-  if(!impl.LibrariesDone)
-    {
-    impl.LibrariesDone = true;
-    this->ComputeLinkImplementationLibraries(config, impl, head);
-    }
-  return &impl;
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::ComputeLinkImplementationLibraries(
-  const std::string& config,
-  cmOptionalLinkImplementation& impl,
-  cmTarget const* head) const
-{
-  // Collect libraries directly linked in this configuration.
-  for (std::vector<cmValueWithOrigin>::const_iterator
-      le = this->Internal->LinkImplementationPropertyEntries.begin(),
-      end = this->Internal->LinkImplementationPropertyEntries.end();
-      le != end; ++le)
-    {
-    std::vector<std::string> llibs;
-    cmGeneratorExpressionDAGChecker dagChecker(
-                                        this->GetName(),
-                                        "LINK_LIBRARIES", 0, 0);
-    cmGeneratorExpression ge(le->Backtrace);
-    cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge =
-      ge.Parse(le->Value);
-    std::string const evaluated =
-      cge->Evaluate(this->Makefile, config, false, head, &dagChecker);
-    cmSystemTools::ExpandListArgument(evaluated, llibs);
-    if(cge->GetHadHeadSensitiveCondition())
-      {
-      impl.HadHeadSensitiveCondition = true;
-      }
-
-    for(std::vector<std::string>::const_iterator li = llibs.begin();
-        li != llibs.end(); ++li)
-      {
-      // Skip entries that resolve to the target itself or are empty.
-      std::string name = this->CheckCMP0004(*li);
-      if(name == this->GetName() || name.empty())
-        {
-        if(name == this->GetName())
-          {
-          bool noMessage = false;
-          cmake::MessageType messageType = cmake::FATAL_ERROR;
-          std::ostringstream e;
-          switch(this->GetPolicyStatusCMP0038())
-            {
-            case cmPolicies::WARN:
-              {
-              e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0038) << "\n";
-              messageType = cmake::AUTHOR_WARNING;
-              }
-              break;
-            case cmPolicies::OLD:
-              noMessage = true;
-            case cmPolicies::REQUIRED_IF_USED:
-            case cmPolicies::REQUIRED_ALWAYS:
-            case cmPolicies::NEW:
-              // Issue the fatal message.
-              break;
-            }
-
-          if(!noMessage)
-            {
-            e << "Target \"" << this->GetName() << "\" links to itself.";
-            this->Makefile->GetCMakeInstance()->IssueMessage(
-              messageType, e.str(), this->GetBacktrace());
-            if (messageType == cmake::FATAL_ERROR)
-              {
-              return;
-              }
-            }
-          }
-        continue;
-        }
-
-      // The entry is meant for this configuration.
-      impl.Libraries.push_back(
-        cmLinkImplItem(name, this->FindTargetToLink(name),
-                       le->Backtrace, evaluated != le->Value));
-      }
-
-    std::set<std::string> const& seenProps = cge->GetSeenTargetProperties();
-    for (std::set<std::string>::const_iterator it = seenProps.begin();
-        it != seenProps.end(); ++it)
-      {
-      if (!this->GetProperty(*it))
-        {
-        this->LinkImplicitNullProperties.insert(*it);
-        }
-      }
-    cge->GetMaxLanguageStandard(this, this->MaxLanguageStandards);
-    }
-
-  cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
-  cmTarget::LinkLibraryVectorType const& oldllibs =
-    this->GetOriginalLinkLibraries();
-  for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin();
-      li != oldllibs.end(); ++li)
-    {
-    if(li->second != cmTarget::GENERAL && li->second != linkType)
-      {
-      std::string name = this->CheckCMP0004(li->first);
-      if(name == this->GetName() || name.empty())
-        {
-        continue;
-        }
-      // Support OLD behavior for CMP0003.
-      impl.WrongConfigLibraries.push_back(
-        cmLinkItem(name, this->FindTargetToLink(name)));
-      }
-    }
-}
-
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 cmTarget const* cmTarget::FindTargetToLink(std::string const& name) const
 cmTarget const* cmTarget::FindTargetToLink(std::string const& name) const
 {
 {

+ 3 - 67
Source/cmTarget.h

@@ -225,35 +225,12 @@ public:
 
 
   void GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const;
   void GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const;
 
 
-  cmLinkImplementationLibraries const*
-    GetLinkImplementationLibraries(const std::string& config) const;
-
-  void ComputeLinkImplementationLibraries(const std::string& config,
-                                          cmOptionalLinkImplementation& impl,
-                                          cmTarget const* head) const;
-
-  cmOptionalLinkImplementation&
-  GetLinkImplMap(std::string const& config) const;
-
   cmTarget const* FindTargetToLink(std::string const& name) const;
   cmTarget const* FindTargetToLink(std::string const& name) const;
 
 
   /** Strip off leading and trailing whitespace from an item named in
   /** Strip off leading and trailing whitespace from an item named in
       the link dependencies of this target.  */
       the link dependencies of this target.  */
   std::string CheckCMP0004(std::string const& item) const;
   std::string CheckCMP0004(std::string const& item) const;
 
 
-  /** Get the directory in which this target will be built.  If the
-      configuration name is given then the generator will add its
-      subdirectory for that configuration.  Otherwise just the canonical
-      output directory is given.  */
-  std::string GetDirectory(const std::string& config = "",
-                           bool implib = false) const;
-
-  /** Get the directory in which this targets .pdb files will be placed.
-      If the configuration name is given then the generator will add its
-      subdirectory for that configuration.  Otherwise just the canonical
-      pdb output directory is given.  */
-  std::string GetPDBDirectory(const std::string& config) const;
-
   const char* ImportedGetLocation(const std::string& config) const;
   const char* ImportedGetLocation(const std::string& config) const;
 
 
   /** Get the target major and minor version numbers interpreted from
   /** Get the target major and minor version numbers interpreted from
@@ -267,16 +244,6 @@ public:
   void
   void
   GetTargetVersion(bool soversion, int& major, int& minor, int& patch) const;
   GetTargetVersion(bool soversion, int& major, int& minor, int& patch) const;
 
 
-  /** Whether this library has \@rpath and platform supports it.  */
-  bool HasMacOSXRpathInstallNameDir(const std::string& config) const;
-
-  /** Whether this library defaults to \@rpath.  */
-  bool MacOSXRpathInstallNameDirDefault() const;
-
-  /** Test for special case of a third-party shared library that has
-      no soname at all.  */
-  bool IsImportedSharedLibWithoutSOName(const std::string& config) const;
-
   /** Does this target have a GNU implib to convert to MS format?  */
   /** Does this target have a GNU implib to convert to MS format?  */
   bool HasImplibGNUtoMS() const;
   bool HasImplibGNUtoMS() const;
 
 
@@ -285,8 +252,6 @@ public:
   bool GetImplibGNUtoMS(std::string const& gnuName, std::string& out,
   bool GetImplibGNUtoMS(std::string const& gnuName, std::string& out,
                         const char* newExt = 0) const;
                         const char* newExt = 0) const;
 
 
-  bool HaveInstallTreeRPATH() const;
-
   // Get the properties
   // Get the properties
   cmPropertyMap &GetProperties() const { return this->Properties; }
   cmPropertyMap &GetProperties() const { return this->Properties; }
 
 
@@ -335,10 +300,6 @@ public:
   /** Get a build-tree directory in which to place target support files.  */
   /** Get a build-tree directory in which to place target support files.  */
   std::string GetSupportDirectory() const;
   std::string GetSupportDirectory() const;
 
 
-  /** Return whether this target uses the default value for its output
-      directory.  */
-  bool UsesDefaultOutputDir(const std::string& config, bool implib) const;
-
   /** @return whether this target have a well defined output file name. */
   /** @return whether this target have a well defined output file name. */
   bool HaveWellDefinedOutputFiles() const;
   bool HaveWellDefinedOutputFiles() const;
 
 
@@ -353,8 +314,6 @@ public:
 
 
   void AppendBuildInterfaceIncludes();
   void AppendBuildInterfaceIncludes();
 
 
-  bool IsNullImpliedByLinkLibraries(const std::string &p) const;
-
   std::string GetDebugGeneratorExpressions(const std::string &value,
   std::string GetDebugGeneratorExpressions(const std::string &value,
                                   cmTarget::LinkLibraryType llt) const;
                                   cmTarget::LinkLibraryType llt) const;
 
 
@@ -365,12 +324,6 @@ public:
   bool LinkLanguagePropagatesToDependents() const
   bool LinkLanguagePropagatesToDependents() const
   { return this->TargetTypeValue == STATIC_LIBRARY; }
   { return this->TargetTypeValue == STATIC_LIBRARY; }
 
 
-  std::map<std::string, std::string> const&
-  GetMaxLanguageStandards() const
-  {
-    return this->MaxLanguageStandards;
-  }
-
   cmStringRange GetIncludeDirectoriesEntries() const;
   cmStringRange GetIncludeDirectoriesEntries() const;
   cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
   cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
 
 
@@ -385,6 +338,9 @@ public:
 
 
   cmStringRange GetSourceEntries() const;
   cmStringRange GetSourceEntries() const;
   cmBacktraceRange GetSourceBacktraces() const;
   cmBacktraceRange GetSourceBacktraces() const;
+  cmStringRange GetLinkImplementationEntries() const;
+  cmBacktraceRange GetLinkImplementationBacktraces() const;
+
 
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
 #if defined(_WIN32) && !defined(__CYGWIN__)
   const LinkLibraryVectorType &GetLinkLibrariesForVS6() const {
   const LinkLibraryVectorType &GetLinkLibrariesForVS6() const {
@@ -455,9 +411,6 @@ private:
   void SetPropertyDefault(const std::string& property,
   void SetPropertyDefault(const std::string& property,
                           const char* default_value);
                           const char* default_value);
 
 
-  // Returns ARCHIVE, LIBRARY, or RUNTIME based on platform and type.
-  const char* GetOutputTargetType(bool implib) const;
-
   std::string GetFullNameImported(const std::string& config,
   std::string GetFullNameImported(const std::string& config,
                                   bool implib) const;
                                   bool implib) const;
 
 
@@ -469,9 +422,7 @@ private:
   std::set<std::string> SystemIncludeDirectories;
   std::set<std::string> SystemIncludeDirectories;
   std::set<std::string> LinkDirectoriesEmmitted;
   std::set<std::string> LinkDirectoriesEmmitted;
   std::set<std::string> Utilities;
   std::set<std::string> Utilities;
-  mutable std::set<std::string> LinkImplicitNullProperties;
   std::map<std::string, cmListFileBacktrace> UtilityBacktraces;
   std::map<std::string, cmListFileBacktrace> UtilityBacktraces;
-  mutable std::map<std::string, std::string> MaxLanguageStandards;
   cmPolicies::PolicyMap PolicyMap;
   cmPolicies::PolicyMap PolicyMap;
   std::string Name;
   std::string Name;
   std::string InstallPath;
   std::string InstallPath;
@@ -501,15 +452,6 @@ private:
   bool LinkLibrariesForVS6Analyzed;
   bool LinkLibrariesForVS6Analyzed;
 #endif
 #endif
 
 
-  // Cache target output paths for each configuration.
-  struct OutputInfo;
-  OutputInfo const* GetOutputInfo(const std::string& config) const;
-  bool
-  ComputeOutputDir(const std::string& config,
-                   bool implib, std::string& out) const;
-  bool ComputePDBOutputDir(const std::string& kind, const std::string& config,
-                           std::string& out) const;
-
   // Cache import information from properties for each configuration.
   // Cache import information from properties for each configuration.
   struct ImportInfo
   struct ImportInfo
   {
   {
@@ -529,14 +471,8 @@ private:
   void ComputeImportInfo(std::string const& desired_config,
   void ComputeImportInfo(std::string const& desired_config,
                          ImportInfo& info) const;
                          ImportInfo& info) const;
 
 
-  cmLinkImplementationLibraries const*
-    GetLinkImplementationLibrariesInternal(const std::string& config,
-                                           cmTarget const* head) const;
-
   std::string ProcessSourceItemCMP0049(const std::string& s);
   std::string ProcessSourceItemCMP0049(const std::string& s);
 
 
-  void ClearLinkMaps();
-
   void MaybeInvalidatePropertyCache(const std::string& prop);
   void MaybeInvalidatePropertyCache(const std::string& prop);
 
 
   // Internal representation details.
   // Internal representation details.

+ 4 - 3
Source/cmVisualStudio10TargetGenerator.cxx

@@ -1779,7 +1779,7 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
         }
         }
       else
       else
         {
         {
-        outDir = this->Target->GetDirectory(config->c_str()) + "/";
+        outDir = this->GeneratorTarget->GetDirectory(config->c_str()) + "/";
         targetNameFull = this->GeneratorTarget->GetFullName(config->c_str());
         targetNameFull = this->GeneratorTarget->GetFullName(config->c_str());
         }
         }
       this->ConvertToWindowsSlash(intermediateDir);
       this->ConvertToWindowsSlash(intermediateDir);
@@ -2580,10 +2580,11 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
       {
       {
       linkOptions.AddFlag("GenerateDebugInformation", "false");
       linkOptions.AddFlag("GenerateDebugInformation", "false");
       }
       }
-    std::string pdb = this->Target->GetPDBDirectory(config.c_str());
+    std::string pdb = this->GeneratorTarget->GetPDBDirectory(config.c_str());
     pdb += "/";
     pdb += "/";
     pdb += targetNamePDB;
     pdb += targetNamePDB;
-    std::string imLib = this->Target->GetDirectory(config.c_str(), true);
+    std::string imLib =
+        this->GeneratorTarget->GetDirectory(config.c_str(), true);
     imLib += "/";
     imLib += "/";
     imLib += targetNameImport;
     imLib += targetNameImport;