[Cmake-commits] CMake branch, next, updated. v2.8.10.2-1480-g2d80aa8
Brad King
brad.king at kitware.com
Tue Jan 8 09:10:07 EST 2013
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".
The branch, next has been updated
via 2d80aa8046360f25da5652d139a98495101617be (commit)
via 765386279815f208c5f83b1ad2b66776e990feb9 (commit)
via 40cf3fb95bc391519c0db4be1dc03c49e040579f (commit)
from a9eadf8c1795fcde367c1e449f39a4ad6405a2eb (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2d80aa8046360f25da5652d139a98495101617be
commit 2d80aa8046360f25da5652d139a98495101617be
Merge: a9eadf8 7653862
Author: Brad King <brad.king at kitware.com>
AuthorDate: Tue Jan 8 09:10:04 2013 -0500
Commit: CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Tue Jan 8 09:10:04 2013 -0500
Merge topic 'LINK_LIBRARIES-property' into next
7653862 Add LINK_LIBRARIES property for direct target link dependencies
40cf3fb Make linking APIs aware of 'head' target
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=765386279815f208c5f83b1ad2b66776e990feb9
commit 765386279815f208c5f83b1ad2b66776e990feb9
Author: Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Dec 6 12:14:03 2012 +0100
Commit: Brad King <brad.king at kitware.com>
CommitDate: Tue Jan 8 09:02:43 2013 -0500
Add LINK_LIBRARIES property for direct target link dependencies
Previously we kept direct link dependencies in OriginalLinkLibraries.
The property exposes the information in the CMake language through the
get/set_property commands. We preserve the OriginalLinkLibraries value
internally to support old APIs like that for CMP0003's OLD behavior, but
the property is now authoritative. This follows up from commit d5cf644a
(Split link information processing into two steps, 2012-11-01).
This will be used later to populate the link interface properties when
exporting targets, and will later allow use of generator expressions
when linking to libraries with target_link_libraries.
Also make targets depend on the (config-specific) union of dependencies.
CMake now allows linking to dependencies or not depending on the config.
However, generated build systems are not all capable of processing
config-specific dependencies, so the targets depend on the union of
dependencies for all configs.
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index c3a75e4..8fd95b9 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -200,25 +200,51 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
// Get the depender.
cmTarget* depender = this->Targets[depender_index];
- // Loop over all targets linked directly.
+ // Loop over all targets linked directly in all configs.
+ // We need to make targets depend on the union of all config-specific
+ // dependencies in all targets, because the generated build-systems can't
+ // deal with config-specific dependencies.
{
- cmTarget::LinkLibraryVectorType const& tlibs =
- depender->GetOriginalLinkLibraries();
std::set<cmStdString> emitted;
+ {
+ std::vector<std::string> tlibs;
+ depender->GetDirectLinkLibraries(0, tlibs, depender);
// A target should not depend on itself.
emitted.insert(depender->GetName());
- for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin();
+ for(std::vector<std::string>::const_iterator lib = tlibs.begin();
lib != tlibs.end(); ++lib)
{
// Don't emit the same library twice for this target.
- if(emitted.insert(lib->first).second)
+ if(emitted.insert(*lib).second)
{
- this->AddTargetDepend(depender_index, lib->first.c_str(), true);
- this->AddInterfaceDepends(depender_index, lib->first.c_str(),
+ this->AddTargetDepend(depender_index, lib->c_str(), true);
+ this->AddInterfaceDepends(depender_index, lib->c_str(),
true, emitted);
}
}
}
+ std::vector<std::string> configs;
+ depender->GetMakefile()->GetConfigurations(configs);
+ for (std::vector<std::string>::const_iterator it = configs.begin();
+ it != configs.end(); ++it)
+ {
+ std::vector<std::string> tlibs;
+ depender->GetDirectLinkLibraries(it->c_str(), tlibs, depender);
+ // A target should not depend on itself.
+ emitted.insert(depender->GetName());
+ for(std::vector<std::string>::const_iterator lib = tlibs.begin();
+ lib != tlibs.end(); ++lib)
+ {
+ // Don't emit the same library twice for this target.
+ if(emitted.insert(*lib).second)
+ {
+ this->AddTargetDepend(depender_index, lib->c_str(), true);
+ this->AddInterfaceDepends(depender_index, lib->c_str(),
+ true, emitted);
+ }
+ }
+ }
+ }
// Loop over all utility dependencies.
{
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 1338ec4..25054c5 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -520,6 +520,22 @@ void cmTarget::DefineProperties(cmake *cm)
"undefined behavior.");
cm->DefineProperty
+ ("LINK_LIBRARIES", cmProperty::TARGET,
+ "List of direct link dependencies.",
+ "This property specifies the list of libraries or targets which will be "
+ "used for linking. "
+ "In addition to accepting values from the target_link_libraries "
+ "command, values may be set directly on any target using the "
+ "set_property command. "
+ "\n"
+ "The target property values are used by the generators to set "
+ "the link libraries for the compiler. "
+ "See also the target_link_libraries command.\n"
+ "Contents of LINK_LIBRARIES may use \"generator expressions\" with "
+ "the syntax \"$<...>\". "
+ CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
+
+ cm->DefineProperty
("INCLUDE_DIRECTORIES", cmProperty::TARGET,
"List of preprocessor include file search directories.",
"This property specifies the list of directories given "
@@ -2140,6 +2156,66 @@ bool cmTarget::NameResolvesToFramework(const std::string& libname)
}
//----------------------------------------------------------------------------
+void cmTarget::GetDirectLinkLibraries(const char *config,
+ std::vector<std::string> &libs, cmTarget *head)
+{
+ const char *prop = this->GetProperty("LINK_LIBRARIES");
+ if (prop)
+ {
+ cmListFileBacktrace lfbt;
+ cmGeneratorExpression ge(lfbt);
+
+ cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+ this->GetName(),
+ "LINK_LIBRARIES", 0, 0);
+ cmSystemTools::ExpandListArgument(ge.Parse(prop)->Evaluate(this->Makefile,
+ config,
+ false,
+ head,
+ &dagChecker),
+ libs);
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::GetDebugGeneratorExpressions(const std::string &value,
+ cmTarget::LinkLibraryType llt)
+{
+ if (llt == GENERAL)
+ {
+ return value;
+ }
+
+ // Get the list of configurations considered to be DEBUG.
+ std::vector<std::string> const& debugConfigs =
+ this->Makefile->GetCMakeInstance()->GetDebugConfigs();
+
+ std::string configString = "$<CONFIG:" + debugConfigs[0] + ">";
+
+ if (debugConfigs.size() > 1)
+ {
+ for(std::vector<std::string>::const_iterator
+ li = debugConfigs.begin() + 1; li != debugConfigs.end(); ++li)
+ {
+ configString += ",$<CONFIG:" + *li + ">";
+ }
+ configString = "$<OR:" + configString + ">";
+ }
+
+ if (llt == OPTIMIZED)
+ {
+ configString = "$<NOT:" + configString + ">";
+ }
+ return "$<" + configString + ":" + value + ">";
+}
+
+//----------------------------------------------------------------------------
+static std::string targetNameGenex(const char *lib)
+{
+ return std::string("$<TARGET_NAME:") + lib + ">";
+}
+
+//----------------------------------------------------------------------------
void cmTarget::AddLinkLibrary(cmMakefile& mf,
const char *target, const char* lib,
LinkLibraryType llt)
@@ -2149,6 +2225,18 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
{
return;
}
+
+ {
+ cmTarget *tgt = this->Makefile->FindTargetToUse(lib);
+ const bool isNonImportedTarget = tgt && !tgt->IsImported();
+
+ std::string libName = isNonImportedTarget ? targetNameGenex(lib)
+ : std::string(lib);
+ this->AppendProperty("LINK_LIBRARIES",
+ this->GetDebugGeneratorExpressions(libName,
+ llt).c_str());
+ }
+
cmTarget::LibraryID tmp;
tmp.first = lib;
tmp.second = llt;
@@ -4884,26 +4972,23 @@ void cmTarget::ComputeLinkImplementation(const char* config,
LinkImplementation& impl,
cmTarget *head)
{
- (void)head;
// Compute which library configuration to link.
cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
// Collect libraries directly linked in this configuration.
- LinkLibraryVectorType const& llibs = this->GetOriginalLinkLibraries();
- for(cmTarget::LinkLibraryVectorType::const_iterator li = llibs.begin();
+ std::vector<std::string> llibs;
+ this->GetDirectLinkLibraries(config, llibs, head);
+ 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 item = this->CheckCMP0004(li->first);
+ std::string item = this->CheckCMP0004(*li);
if(item == this->GetName() || item.empty())
{
continue;
}
- if(li->second == cmTarget::GENERAL || li->second == linkType)
- {
- // The entry is meant for this configuration.
- impl.Libraries.push_back(item);
- }
+ // The entry is meant for this configuration.
+ impl.Libraries.push_back(item);
}
LinkLibraryVectorType const& oldllibs = this->GetOriginalLinkLibraries();
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 29c73b6..d4069fa 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -168,6 +168,9 @@ public:
return this->LinkLibraries;}
const LinkLibraryVectorType &GetOriginalLinkLibraries() const
{return this->OriginalLinkLibraries;}
+ void GetDirectLinkLibraries(const char *config,
+ std::vector<std::string> &,
+ cmTarget *head);
/** Compute the link type to use for the given configuration. */
LinkLibraryType ComputeLinkType(const char* config);
@@ -622,6 +625,9 @@ private:
void ProcessSourceExpression(std::string const& expr);
+ std::string GetDebugGeneratorExpressions(const std::string &value,
+ cmTarget::LinkLibraryType llt);
+
// The cmMakefile instance that owns this target. This should
// always be set.
cmMakefile* Makefile;
diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
index 60b36fc..63ae675 100644
--- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
@@ -34,6 +34,13 @@ generate_export_header(depB)
target_link_libraries(depB LINK_PRIVATE depA)
+add_library(libgenex SHARED libgenex.cpp)
+generate_export_header(libgenex)
+
+set_property(TARGET depB APPEND PROPERTY
+ LINK_LIBRARIES $<1:libgenex>
+)
+
add_library(depC SHARED depC.cpp)
generate_export_header(depC)
diff --git a/Tests/CMakeCommands/target_link_libraries/depB.cpp b/Tests/CMakeCommands/target_link_libraries/depB.cpp
index 1bbe38b..4f46552 100644
--- a/Tests/CMakeCommands/target_link_libraries/depB.cpp
+++ b/Tests/CMakeCommands/target_link_libraries/depB.cpp
@@ -3,9 +3,13 @@
#include "depA.h"
+#include "libgenex.h"
+
int DepB::foo()
{
DepA a;
- return a.foo();
+ LibGenex lg;
+
+ return a.foo() + lg.foo();
}
diff --git a/Tests/CMakeCommands/target_link_libraries/libgenex.cpp b/Tests/CMakeCommands/target_link_libraries/libgenex.cpp
new file mode 100644
index 0000000..c925c08
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/libgenex.cpp
@@ -0,0 +1,7 @@
+
+#include "libgenex.h"
+
+int LibGenex::foo()
+{
+ return 0;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/libgenex.h b/Tests/CMakeCommands/target_link_libraries/libgenex.h
new file mode 100644
index 0000000..733f9b6
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/libgenex.h
@@ -0,0 +1,12 @@
+
+#include "libgenex_export.h"
+
+#ifndef LIBGENEX_H
+#define LIBGENEX_H
+
+struct LIBGENEX_EXPORT LibGenex
+{
+ int foo();
+};
+
+#endif
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=40cf3fb95bc391519c0db4be1dc03c49e040579f
commit 40cf3fb95bc391519c0db4be1dc03c49e040579f
Author: Stephen Kelly <steveire at gmail.com>
AuthorDate: Fri Jan 4 13:31:01 2013 +0100
Commit: Brad King <brad.king at kitware.com>
CommitDate: Tue Jan 8 08:53:25 2013 -0500
Make linking APIs aware of 'head' target
The 'head' is the dependent target to be linked with the current target.
It will be used to evaluate generator expressions with proper handling
of mapped configurations and is used as the source target of properties.
This requires that memoization is done with a key of a pair of target
and config, instead of just config, because now the result also depends
on the target. Removing the memoization entirely is not an option
because it slows cmake down considerably.
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 055aab0..dec2b54 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -172,10 +172,11 @@ satisfy dependencies.
//----------------------------------------------------------------------------
cmComputeLinkDepends
-::cmComputeLinkDepends(cmTarget* target, const char* config)
+::cmComputeLinkDepends(cmTarget* target, const char* config, cmTarget* head)
{
// Store context information.
this->Target = target;
+ this->HeadTarget = head;
this->Makefile = this->Target->GetMakefile();
this->LocalGenerator = this->Makefile->GetLocalGenerator();
this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
@@ -352,7 +353,7 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
{
// Follow the target dependencies.
if(cmTarget::LinkInterface const* iface =
- entry.Target->GetLinkInterface(this->Config))
+ entry.Target->GetLinkInterface(this->Config, this->HeadTarget))
{
// This target provides its own link interface information.
this->AddLinkEntries(depender_index, iface->Libraries);
@@ -444,7 +445,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
if(entry.Target)
{
if(cmTarget::LinkInterface const* iface =
- entry.Target->GetLinkInterface(this->Config))
+ entry.Target->GetLinkInterface(this->Config, this->HeadTarget))
{
// Follow public and private dependencies transitively.
this->FollowSharedDeps(index, iface, true);
@@ -533,7 +534,7 @@ void cmComputeLinkDepends::AddDirectLinkEntries()
{
// Add direct link dependencies in this configuration.
cmTarget::LinkImplementation const* impl =
- this->Target->GetLinkImplementation(this->Config);
+ this->Target->GetLinkImplementation(this->Config, this->HeadTarget);
this->AddLinkEntries(-1, impl->Libraries);
for(std::vector<std::string>::const_iterator
wi = impl->WrongConfigLibraries.begin();
@@ -944,7 +945,7 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
if(cmTarget* target = this->EntryList[*ni].Target)
{
if(cmTarget::LinkInterface const* iface =
- target->GetLinkInterface(this->Config))
+ target->GetLinkInterface(this->Config, this->HeadTarget))
{
if(iface->Multiplicity > count)
{
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index 80a0454..1d5d1b9 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -32,7 +32,7 @@ class cmake;
class cmComputeLinkDepends
{
public:
- cmComputeLinkDepends(cmTarget* target, const char* config);
+ cmComputeLinkDepends(cmTarget* target, const char* config, cmTarget *head);
~cmComputeLinkDepends();
// Basic information about each link item.
@@ -59,6 +59,7 @@ private:
// Context information.
cmTarget* Target;
+ cmTarget* HeadTarget;
cmMakefile* Makefile;
cmLocalGenerator* LocalGenerator;
cmGlobalGenerator* GlobalGenerator;
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index d8ffb5e..504c6e7 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -239,10 +239,12 @@ because this need be done only for shared libraries without soname-s.
//----------------------------------------------------------------------------
cmComputeLinkInformation
-::cmComputeLinkInformation(cmTarget* target, const char* config)
+::cmComputeLinkInformation(cmTarget* target, const char* config,
+ cmTarget *headTarget)
{
// Store context information.
this->Target = target;
+ this->HeadTarget = headTarget;
this->Makefile = this->Target->GetMakefile();
this->LocalGenerator = this->Makefile->GetLocalGenerator();
this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
@@ -265,7 +267,7 @@ cmComputeLinkInformation
this->OrderDependentRPath = 0;
// Get the language used for linking this target.
- this->LinkLanguage = this->Target->GetLinkerLanguage(config);
+ this->LinkLanguage = this->Target->GetLinkerLanguage(config, headTarget);
if(!this->LinkLanguage)
{
// The Compute method will do nothing, so skip the rest of the
@@ -503,7 +505,7 @@ bool cmComputeLinkInformation::Compute()
}
// Compute the ordered link line items.
- cmComputeLinkDepends cld(this->Target, this->Config);
+ cmComputeLinkDepends cld(this->Target, this->Config, this->HeadTarget);
cld.SetOldLinkDirMode(this->OldLinkDirMode);
cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
@@ -569,7 +571,8 @@ bool cmComputeLinkInformation::Compute()
void cmComputeLinkInformation::AddImplicitLinkInfo()
{
// The link closure lists all languages whose implicit info is needed.
- cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config);
+ cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config,
+ this->HeadTarget);
for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
li != lc->Languages.end(); ++li)
{
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index e0078af..1a76922 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -29,7 +29,8 @@ class cmOrderDirectories;
class cmComputeLinkInformation
{
public:
- cmComputeLinkInformation(cmTarget* target, const char* config);
+ cmComputeLinkInformation(cmTarget* target, const char* config,
+ cmTarget* headTarget);
~cmComputeLinkInformation();
bool Compute();
@@ -74,6 +75,7 @@ private:
// Context information.
cmTarget* Target;
+ cmTarget* HeadTarget;
cmMakefile* Makefile;
cmLocalGenerator* LocalGenerator;
cmGlobalGenerator* GlobalGenerator;
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 3b15ec1..c3a75e4 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -244,8 +244,9 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
const char *config,
std::set<cmStdString> &emitted)
{
+ cmTarget* depender = this->Targets[depender_index];
if(cmTarget::LinkInterface const* iface =
- dependee->GetLinkInterface(config))
+ dependee->GetLinkInterface(config, depender))
{
for(std::vector<std::string>::const_iterator
lib = iface->Libraries.begin();
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 2b133be..90c0c41 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -357,7 +357,8 @@ cmExportFileGenerator
}
// Add the transitive link dependencies for this configuration.
- if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config))
+ if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config,
+ target))
{
this->SetImportLinkProperty(suffix, target,
"IMPORTED_LINK_INTERFACE_LANGUAGES",
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index b2d325c..4c26b82 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1206,7 +1206,7 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
// If the language is compiled as a source trust Xcode to link with it.
cmTarget::LinkImplementation const* impl =
- cmtarget.GetLinkImplementation("NOCONFIG");
+ cmtarget.GetLinkImplementation("NOCONFIG", &cmtarget);
for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
li != impl->Languages.end(); ++li)
{
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index ca53a39..1338ec4 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -72,6 +72,11 @@ struct cmTarget::ImportInfo
cmTarget::LinkInterface LinkInterface;
};
+struct TargetConfigPair : public std::pair<cmTarget*, std::string> {
+ TargetConfigPair(cmTarget* tgt, const std::string &config)
+ : std::pair<cmTarget*, std::string>(tgt, config) {}
+};
+
//----------------------------------------------------------------------------
class cmTargetInternals
{
@@ -100,20 +105,24 @@ public:
OptionalLinkInterface(): Exists(false) {}
bool Exists;
};
- typedef std::map<cmStdString, OptionalLinkInterface> LinkInterfaceMapType;
+ typedef std::map<TargetConfigPair, OptionalLinkInterface>
+ LinkInterfaceMapType;
LinkInterfaceMapType LinkInterfaceMap;
typedef std::map<cmStdString, cmTarget::OutputInfo> OutputInfoMapType;
OutputInfoMapType OutputInfoMap;
- typedef std::map<cmStdString, cmTarget::ImportInfo> ImportInfoMapType;
+ typedef std::map<TargetConfigPair, cmTarget::ImportInfo>
+ ImportInfoMapType;
ImportInfoMapType ImportInfoMap;
// Cache link implementation computation from each configuration.
- typedef std::map<cmStdString, cmTarget::LinkImplementation> LinkImplMapType;
+ typedef std::map<TargetConfigPair,
+ cmTarget::LinkImplementation> LinkImplMapType;
LinkImplMapType LinkImplMap;
- typedef std::map<cmStdString, cmTarget::LinkClosure> LinkClosureMapType;
+ typedef std::map<TargetConfigPair, cmTarget::LinkClosure>
+ LinkClosureMapType;
LinkClosureMapType LinkClosureMap;
struct SourceEntry { std::vector<cmSourceFile*> Depends; };
@@ -3024,8 +3033,11 @@ class cmTargetCollectLinkLanguages
{
public:
cmTargetCollectLinkLanguages(cmTarget* target, const char* config,
- std::set<cmStdString>& languages):
- Config(config), Languages(languages) { this->Visited.insert(target); }
+ std::set<cmStdString>& languages,
+ cmTarget* head):
+ Config(config), Languages(languages), HeadTarget(head)
+ { this->Visited.insert(target); }
+
void Visit(cmTarget* target)
{
if(!target || !this->Visited.insert(target).second)
@@ -3034,7 +3046,7 @@ public:
}
cmTarget::LinkInterface const* iface =
- target->GetLinkInterface(this->Config);
+ target->GetLinkInterface(this->Config, this->HeadTarget);
if(!iface) { return; }
for(std::vector<std::string>::const_iterator
@@ -3053,26 +3065,30 @@ public:
private:
const char* Config;
std::set<cmStdString>& Languages;
+ cmTarget* HeadTarget;
std::set<cmTarget*> Visited;
};
//----------------------------------------------------------------------------
-const char* cmTarget::GetLinkerLanguage(const char* config)
+const char* cmTarget::GetLinkerLanguage(const char* config, cmTarget *head)
{
- const char* lang = this->GetLinkClosure(config)->LinkerLanguage.c_str();
+ cmTarget *headTarget = head ? head : this;
+ const char* lang = this->GetLinkClosure(config, headTarget)
+ ->LinkerLanguage.c_str();
return *lang? lang : 0;
}
//----------------------------------------------------------------------------
-cmTarget::LinkClosure const* cmTarget::GetLinkClosure(const char* config)
+cmTarget::LinkClosure const* cmTarget::GetLinkClosure(const char* config,
+ cmTarget *head)
{
- std::string key = cmSystemTools::UpperCase(config? config : "");
+ TargetConfigPair key(head, cmSystemTools::UpperCase(config ? config : ""));
cmTargetInternals::LinkClosureMapType::iterator
i = this->Internal->LinkClosureMap.find(key);
if(i == this->Internal->LinkClosureMap.end())
{
LinkClosure lc;
- this->ComputeLinkClosure(config, lc);
+ this->ComputeLinkClosure(config, lc, head);
cmTargetInternals::LinkClosureMapType::value_type entry(key, lc);
i = this->Internal->LinkClosureMap.insert(entry).first;
}
@@ -3133,11 +3149,12 @@ public:
};
//----------------------------------------------------------------------------
-void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc)
+void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc,
+ cmTarget *head)
{
// Get languages built in this target.
std::set<cmStdString> languages;
- LinkImplementation const* impl = this->GetLinkImplementation(config);
+ LinkImplementation const* impl = this->GetLinkImplementation(config, head);
for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
li != impl->Languages.end(); ++li)
{
@@ -3145,7 +3162,7 @@ void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc)
}
// Add interface languages from linked targets.
- cmTargetCollectLinkLanguages cll(this, config, languages);
+ cmTargetCollectLinkLanguages cll(this, config, languages, head);
for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
li != impl->Libraries.end(); ++li)
{
@@ -3284,7 +3301,8 @@ bool cmTarget::HasSOName(const char* config)
return ((this->GetType() == cmTarget::SHARED_LIBRARY ||
this->GetType() == cmTarget::MODULE_LIBRARY) &&
!this->GetPropertyAsBool("NO_SONAME") &&
- this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
+ this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config,
+ this)));
}
//----------------------------------------------------------------------------
@@ -3293,7 +3311,7 @@ std::string cmTarget::GetSOName(const char* config)
if(this->IsImported())
{
// Lookup the imported soname.
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
{
if(info->NoSOName)
{
@@ -3330,7 +3348,7 @@ bool cmTarget::IsImportedSharedLibWithoutSOName(const char* config)
{
if(this->IsImported() && this->GetType() == cmTarget::SHARED_LIBRARY)
{
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
{
return info->NoSOName;
}
@@ -3444,7 +3462,7 @@ std::string cmTarget::NormalGetFullPath(const char* config, bool implib,
std::string cmTarget::ImportedGetFullPath(const char* config, bool implib)
{
std::string result;
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
{
result = implib? info->ImportLibrary : info->Location;
}
@@ -3529,7 +3547,7 @@ void cmTarget::GetFullNameInternal(const char* config,
const char* suffixVar = this->GetSuffixVariableInternal(implib);
// Check for language-specific default prefix and suffix.
- if(const char* ll = this->GetLinkerLanguage(config))
+ if(const char* ll = this->GetLinkerLanguage(config, this))
{
if(!targetSuffix && suffixVar && *suffixVar)
{
@@ -3900,7 +3918,7 @@ bool cmTarget::NeedRelinkBeforeInstall(const char* config)
}
// Check for rpath support on this platform.
- if(const char* ll = this->GetLinkerLanguage(config))
+ if(const char* ll = this->GetLinkerLanguage(config, this))
{
std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
flagVar += ll;
@@ -4322,7 +4340,7 @@ bool cmTarget::IsChrpathUsed(const char* config)
// Enable if the rpath flag uses a separator and the target uses ELF
// binaries.
- if(const char* ll = this->GetLinkerLanguage(config))
+ if(const char* ll = this->GetLinkerLanguage(config, this))
{
std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
sepVar += ll;
@@ -4346,7 +4364,7 @@ bool cmTarget::IsChrpathUsed(const char* config)
//----------------------------------------------------------------------------
cmTarget::ImportInfo const*
-cmTarget::GetImportInfo(const char* config)
+cmTarget::GetImportInfo(const char* config, cmTarget *headTarget)
{
// There is no imported information for non-imported targets.
if(!this->IsImported())
@@ -4365,14 +4383,16 @@ cmTarget::GetImportInfo(const char* config)
{
config_upper = "NOCONFIG";
}
+ TargetConfigPair key(headTarget, config_upper);
typedef cmTargetInternals::ImportInfoMapType ImportInfoMapType;
+
ImportInfoMapType::const_iterator i =
- this->Internal->ImportInfoMap.find(config_upper);
+ this->Internal->ImportInfoMap.find(key);
if(i == this->Internal->ImportInfoMap.end())
{
ImportInfo info;
- this->ComputeImportInfo(config_upper, info);
- ImportInfoMapType::value_type entry(config_upper, info);
+ this->ComputeImportInfo(config_upper, info, headTarget);
+ ImportInfoMapType::value_type entry(key, info);
i = this->Internal->ImportInfoMap.insert(entry).first;
}
@@ -4511,8 +4531,10 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
//----------------------------------------------------------------------------
void cmTarget::ComputeImportInfo(std::string const& desired_config,
- ImportInfo& info)
+ ImportInfo& info,
+ cmTarget *headTarget)
{
+ (void)headTarget;
// This method finds information about an imported target from its
// properties. The "IMPORTED_" namespace is reserved for properties
// defined by the project exporting the target.
@@ -4669,12 +4691,13 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
}
//----------------------------------------------------------------------------
-cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config)
+cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config,
+ cmTarget *head)
{
// Imported targets have their own link interface.
if(this->IsImported())
{
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, head))
{
return &info->LinkInterface;
}
@@ -4690,14 +4713,15 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config)
}
// Lookup any existing link interface for this configuration.
- std::string key = cmSystemTools::UpperCase(config? config : "");
+ TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
+
cmTargetInternals::LinkInterfaceMapType::iterator
i = this->Internal->LinkInterfaceMap.find(key);
if(i == this->Internal->LinkInterfaceMap.end())
{
// Compute the link interface for this configuration.
cmTargetInternals::OptionalLinkInterface iface;
- iface.Exists = this->ComputeLinkInterface(config, iface);
+ iface.Exists = this->ComputeLinkInterface(config, iface, head);
// Store the information for this configuration.
cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
@@ -4708,7 +4732,8 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config)
}
//----------------------------------------------------------------------------
-bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
+bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
+ cmTarget *headTarget)
{
// Construct the property name suffix for this configuration.
std::string suffix = "_";
@@ -4765,7 +4790,8 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
{
emitted.insert(*li);
}
- LinkImplementation const* impl = this->GetLinkImplementation(config);
+ LinkImplementation const* impl = this->GetLinkImplementation(config,
+ headTarget);
for(std::vector<std::string>::const_iterator
li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
{
@@ -4793,7 +4819,8 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
else
{
// The link implementation is the default link interface.
- LinkImplementation const* impl = this->GetLinkImplementation(config);
+ LinkImplementation const* impl = this->GetLinkImplementation(config,
+ headTarget);
iface.Libraries = impl->Libraries;
iface.WrongConfigLibraries = impl->WrongConfigLibraries;
if(this->GetType() == cmTarget::STATIC_LIBRARY)
@@ -4825,7 +4852,7 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
//----------------------------------------------------------------------------
cmTarget::LinkImplementation const*
-cmTarget::GetLinkImplementation(const char* config)
+cmTarget::GetLinkImplementation(const char* config, cmTarget *head)
{
// There is no link implementation for imported targets.
if(this->IsImported())
@@ -4834,14 +4861,15 @@ cmTarget::GetLinkImplementation(const char* config)
}
// Lookup any existing link implementation for this configuration.
- std::string key = cmSystemTools::UpperCase(config? config : "");
+ TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
+
cmTargetInternals::LinkImplMapType::iterator
i = this->Internal->LinkImplMap.find(key);
if(i == this->Internal->LinkImplMap.end())
{
// Compute the link implementation for this configuration.
LinkImplementation impl;
- this->ComputeLinkImplementation(config, impl);
+ this->ComputeLinkImplementation(config, impl, head);
// Store the information for this configuration.
cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
@@ -4853,8 +4881,10 @@ cmTarget::GetLinkImplementation(const char* config)
//----------------------------------------------------------------------------
void cmTarget::ComputeLinkImplementation(const char* config,
- LinkImplementation& impl)
+ LinkImplementation& impl,
+ cmTarget *head)
{
+ (void)head;
// Compute which library configuration to link.
cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
@@ -4977,16 +5007,19 @@ std::string cmTarget::CheckCMP0004(std::string const& item)
//----------------------------------------------------------------------------
cmComputeLinkInformation*
-cmTarget::GetLinkInformation(const char* config)
+cmTarget::GetLinkInformation(const char* config, cmTarget *head)
{
+ cmTarget *headTarget = head ? head : this;
// Lookup any existing information for this configuration.
- std::map<cmStdString, cmComputeLinkInformation*>::iterator
- i = this->LinkInformation.find(config?config:"");
+ TargetConfigPair key(headTarget,
+ cmSystemTools::UpperCase(config?config:""));
+ cmTargetLinkInformationMap::iterator
+ i = this->LinkInformation.find(key);
if(i == this->LinkInformation.end())
{
// Compute information for this configuration.
cmComputeLinkInformation* info =
- new cmComputeLinkInformation(this, config);
+ new cmComputeLinkInformation(this, config, headTarget);
if(!info || !info->Compute())
{
delete info;
@@ -4994,8 +5027,7 @@ cmTarget::GetLinkInformation(const char* config)
}
// Store the information for this configuration.
- std::map<cmStdString, cmComputeLinkInformation*>::value_type
- entry(config?config:"", info);
+ cmTargetLinkInformationMap::value_type entry(key, info);
i = this->LinkInformation.insert(entry).first;
}
return i->second;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 52d5ca6..29c73b6 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -25,11 +25,13 @@ class cmSourceFile;
class cmGlobalGenerator;
class cmComputeLinkInformation;
class cmListFileBacktrace;
+class cmTarget;
struct cmTargetLinkInformationMap:
- public std::map<cmStdString, cmComputeLinkInformation*>
+ public std::map<std::pair<cmTarget*, std::string>, cmComputeLinkInformation*>
{
- typedef std::map<cmStdString, cmComputeLinkInformation*> derived;
+ typedef std::map<std::pair<cmTarget*, std::string>,
+ cmComputeLinkInformation*> derived;
cmTargetLinkInformationMap() {}
cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r);
~cmTargetLinkInformationMap();
@@ -258,7 +260,8 @@ public:
/** Get the link interface for the given configuration. Returns 0
if the target cannot be linked. */
- LinkInterface const* GetLinkInterface(const char* config);
+ LinkInterface const* GetLinkInterface(const char* config,
+ cmTarget *headTarget);
/** The link implementation specifies the direct library
dependencies needed by the object files of the target. */
@@ -274,7 +277,8 @@ public:
// Needed only for OLD behavior of CMP0003.
std::vector<std::string> WrongConfigLibraries;
};
- LinkImplementation const* GetLinkImplementation(const char* config);
+ LinkImplementation const* GetLinkImplementation(const char* config,
+ cmTarget *head);
/** Link information from the transitive closure of the link
implementation and the interfaces of its dependencies. */
@@ -286,7 +290,7 @@ public:
// Languages whose runtime libraries must be linked.
std::vector<std::string> Languages;
};
- LinkClosure const* GetLinkClosure(const char* config);
+ LinkClosure const* GetLinkClosure(const char* config, cmTarget *head);
/** Strip off leading and trailing whitespace from an item named in
the link dependencies of this target. */
@@ -331,7 +335,7 @@ public:
bool FindSourceFiles();
///! Return the preferred linker language for this target
- const char* GetLinkerLanguage(const char* config = 0);
+ const char* GetLinkerLanguage(const char* config = 0, cmTarget *head = 0);
/** Get the full name of the target according to the settings in its
makefile. */
@@ -399,7 +403,8 @@ public:
std::string GetInstallNameDirForInstallTree(const char* config,
bool for_xcode = false);
- cmComputeLinkInformation* GetLinkInformation(const char* config);
+ cmComputeLinkInformation* GetLinkInformation(const char* config,
+ cmTarget *head = 0);
// Get the properties
cmPropertyMap &GetProperties() { return this->Properties; };
@@ -597,16 +602,19 @@ private:
// Cache import information from properties for each configuration.
struct ImportInfo;
- ImportInfo const* GetImportInfo(const char* config);
- void ComputeImportInfo(std::string const& desired_config, ImportInfo& info);
+ ImportInfo const* GetImportInfo(const char* config,
+ cmTarget *workingTarget);
+ void ComputeImportInfo(std::string const& desired_config, ImportInfo& info,
+ cmTarget *head);
cmTargetLinkInformationMap LinkInformation;
- bool ComputeLinkInterface(const char* config, LinkInterface& iface);
+ bool ComputeLinkInterface(const char* config, LinkInterface& iface,
+ cmTarget *head);
void ComputeLinkImplementation(const char* config,
- LinkImplementation& impl);
- void ComputeLinkClosure(const char* config, LinkClosure& lc);
+ LinkImplementation& impl, cmTarget *head);
+ void ComputeLinkClosure(const char* config, LinkClosure& lc, cmTarget *head);
void ClearLinkMaps();
-----------------------------------------------------------------------
Summary of changes:
hooks/post-receive
--
CMake
More information about the Cmake-commits
mailing list