Merge topic 'LINK_LIBRARIES-property'
7653862
Add LINK_LIBRARIES property for direct target link dependencies40cf3fb
Make linking APIs aware of 'head' target
This commit is contained in:
commit
a9f1bf4380
|
@ -172,10 +172,11 @@ satisfy dependencies.
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
cmComputeLinkDepends
|
cmComputeLinkDepends
|
||||||
::cmComputeLinkDepends(cmTarget* target, const char* config)
|
::cmComputeLinkDepends(cmTarget* target, const char* config, cmTarget* head)
|
||||||
{
|
{
|
||||||
// Store context information.
|
// Store context information.
|
||||||
this->Target = target;
|
this->Target = target;
|
||||||
|
this->HeadTarget = head;
|
||||||
this->Makefile = this->Target->GetMakefile();
|
this->Makefile = this->Target->GetMakefile();
|
||||||
this->LocalGenerator = this->Makefile->GetLocalGenerator();
|
this->LocalGenerator = this->Makefile->GetLocalGenerator();
|
||||||
this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
|
this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
|
||||||
|
@ -352,7 +353,7 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
|
||||||
{
|
{
|
||||||
// Follow the target dependencies.
|
// Follow the target dependencies.
|
||||||
if(cmTarget::LinkInterface const* iface =
|
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 target provides its own link interface information.
|
||||||
this->AddLinkEntries(depender_index, iface->Libraries);
|
this->AddLinkEntries(depender_index, iface->Libraries);
|
||||||
|
@ -444,7 +445,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
|
||||||
if(entry.Target)
|
if(entry.Target)
|
||||||
{
|
{
|
||||||
if(cmTarget::LinkInterface const* iface =
|
if(cmTarget::LinkInterface const* iface =
|
||||||
entry.Target->GetLinkInterface(this->Config))
|
entry.Target->GetLinkInterface(this->Config, this->HeadTarget))
|
||||||
{
|
{
|
||||||
// Follow public and private dependencies transitively.
|
// Follow public and private dependencies transitively.
|
||||||
this->FollowSharedDeps(index, iface, true);
|
this->FollowSharedDeps(index, iface, true);
|
||||||
|
@ -533,7 +534,7 @@ void cmComputeLinkDepends::AddDirectLinkEntries()
|
||||||
{
|
{
|
||||||
// Add direct link dependencies in this configuration.
|
// Add direct link dependencies in this configuration.
|
||||||
cmTarget::LinkImplementation const* impl =
|
cmTarget::LinkImplementation const* impl =
|
||||||
this->Target->GetLinkImplementation(this->Config);
|
this->Target->GetLinkImplementation(this->Config, this->HeadTarget);
|
||||||
this->AddLinkEntries(-1, impl->Libraries);
|
this->AddLinkEntries(-1, impl->Libraries);
|
||||||
for(std::vector<std::string>::const_iterator
|
for(std::vector<std::string>::const_iterator
|
||||||
wi = impl->WrongConfigLibraries.begin();
|
wi = impl->WrongConfigLibraries.begin();
|
||||||
|
@ -944,7 +945,7 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
|
||||||
if(cmTarget* target = this->EntryList[*ni].Target)
|
if(cmTarget* target = this->EntryList[*ni].Target)
|
||||||
{
|
{
|
||||||
if(cmTarget::LinkInterface const* iface =
|
if(cmTarget::LinkInterface const* iface =
|
||||||
target->GetLinkInterface(this->Config))
|
target->GetLinkInterface(this->Config, this->HeadTarget))
|
||||||
{
|
{
|
||||||
if(iface->Multiplicity > count)
|
if(iface->Multiplicity > count)
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,7 +32,7 @@ class cmake;
|
||||||
class cmComputeLinkDepends
|
class cmComputeLinkDepends
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cmComputeLinkDepends(cmTarget* target, const char* config);
|
cmComputeLinkDepends(cmTarget* target, const char* config, cmTarget *head);
|
||||||
~cmComputeLinkDepends();
|
~cmComputeLinkDepends();
|
||||||
|
|
||||||
// Basic information about each link item.
|
// Basic information about each link item.
|
||||||
|
@ -59,6 +59,7 @@ private:
|
||||||
|
|
||||||
// Context information.
|
// Context information.
|
||||||
cmTarget* Target;
|
cmTarget* Target;
|
||||||
|
cmTarget* HeadTarget;
|
||||||
cmMakefile* Makefile;
|
cmMakefile* Makefile;
|
||||||
cmLocalGenerator* LocalGenerator;
|
cmLocalGenerator* LocalGenerator;
|
||||||
cmGlobalGenerator* GlobalGenerator;
|
cmGlobalGenerator* GlobalGenerator;
|
||||||
|
|
|
@ -239,10 +239,12 @@ because this need be done only for shared libraries without soname-s.
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
cmComputeLinkInformation
|
cmComputeLinkInformation
|
||||||
::cmComputeLinkInformation(cmTarget* target, const char* config)
|
::cmComputeLinkInformation(cmTarget* target, const char* config,
|
||||||
|
cmTarget *headTarget)
|
||||||
{
|
{
|
||||||
// Store context information.
|
// Store context information.
|
||||||
this->Target = target;
|
this->Target = target;
|
||||||
|
this->HeadTarget = headTarget;
|
||||||
this->Makefile = this->Target->GetMakefile();
|
this->Makefile = this->Target->GetMakefile();
|
||||||
this->LocalGenerator = this->Makefile->GetLocalGenerator();
|
this->LocalGenerator = this->Makefile->GetLocalGenerator();
|
||||||
this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
|
this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
|
||||||
|
@ -265,7 +267,7 @@ cmComputeLinkInformation
|
||||||
this->OrderDependentRPath = 0;
|
this->OrderDependentRPath = 0;
|
||||||
|
|
||||||
// Get the language used for linking this target.
|
// Get the language used for linking this target.
|
||||||
this->LinkLanguage = this->Target->GetLinkerLanguage(config);
|
this->LinkLanguage = this->Target->GetLinkerLanguage(config, headTarget);
|
||||||
if(!this->LinkLanguage)
|
if(!this->LinkLanguage)
|
||||||
{
|
{
|
||||||
// The Compute method will do nothing, so skip the rest of the
|
// 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.
|
// Compute the ordered link line items.
|
||||||
cmComputeLinkDepends cld(this->Target, this->Config);
|
cmComputeLinkDepends cld(this->Target, this->Config, this->HeadTarget);
|
||||||
cld.SetOldLinkDirMode(this->OldLinkDirMode);
|
cld.SetOldLinkDirMode(this->OldLinkDirMode);
|
||||||
cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
|
cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
|
||||||
|
|
||||||
|
@ -569,7 +571,8 @@ bool cmComputeLinkInformation::Compute()
|
||||||
void cmComputeLinkInformation::AddImplicitLinkInfo()
|
void cmComputeLinkInformation::AddImplicitLinkInfo()
|
||||||
{
|
{
|
||||||
// The link closure lists all languages whose implicit info is needed.
|
// 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();
|
for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
|
||||||
li != lc->Languages.end(); ++li)
|
li != lc->Languages.end(); ++li)
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,7 +29,8 @@ class cmOrderDirectories;
|
||||||
class cmComputeLinkInformation
|
class cmComputeLinkInformation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cmComputeLinkInformation(cmTarget* target, const char* config);
|
cmComputeLinkInformation(cmTarget* target, const char* config,
|
||||||
|
cmTarget* headTarget);
|
||||||
~cmComputeLinkInformation();
|
~cmComputeLinkInformation();
|
||||||
bool Compute();
|
bool Compute();
|
||||||
|
|
||||||
|
@ -74,6 +75,7 @@ private:
|
||||||
|
|
||||||
// Context information.
|
// Context information.
|
||||||
cmTarget* Target;
|
cmTarget* Target;
|
||||||
|
cmTarget* HeadTarget;
|
||||||
cmMakefile* Makefile;
|
cmMakefile* Makefile;
|
||||||
cmLocalGenerator* LocalGenerator;
|
cmLocalGenerator* LocalGenerator;
|
||||||
cmGlobalGenerator* GlobalGenerator;
|
cmGlobalGenerator* GlobalGenerator;
|
||||||
|
|
|
@ -200,25 +200,51 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
|
||||||
// Get the depender.
|
// Get the depender.
|
||||||
cmTarget* depender = this->Targets[depender_index];
|
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::set<cmStdString> emitted;
|
||||||
|
{
|
||||||
|
std::vector<std::string> tlibs;
|
||||||
|
depender->GetDirectLinkLibraries(0, tlibs, depender);
|
||||||
// A target should not depend on itself.
|
// A target should not depend on itself.
|
||||||
emitted.insert(depender->GetName());
|
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)
|
lib != tlibs.end(); ++lib)
|
||||||
{
|
{
|
||||||
// Don't emit the same library twice for this target.
|
// 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->AddTargetDepend(depender_index, lib->c_str(), true);
|
||||||
this->AddInterfaceDepends(depender_index, lib->first.c_str(),
|
this->AddInterfaceDepends(depender_index, lib->c_str(),
|
||||||
true, emitted);
|
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.
|
// Loop over all utility dependencies.
|
||||||
{
|
{
|
||||||
|
@ -244,8 +270,9 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
|
||||||
const char *config,
|
const char *config,
|
||||||
std::set<cmStdString> &emitted)
|
std::set<cmStdString> &emitted)
|
||||||
{
|
{
|
||||||
|
cmTarget* depender = this->Targets[depender_index];
|
||||||
if(cmTarget::LinkInterface const* iface =
|
if(cmTarget::LinkInterface const* iface =
|
||||||
dependee->GetLinkInterface(config))
|
dependee->GetLinkInterface(config, depender))
|
||||||
{
|
{
|
||||||
for(std::vector<std::string>::const_iterator
|
for(std::vector<std::string>::const_iterator
|
||||||
lib = iface->Libraries.begin();
|
lib = iface->Libraries.begin();
|
||||||
|
|
|
@ -357,7 +357,8 @@ cmExportFileGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the transitive link dependencies for this configuration.
|
// 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,
|
this->SetImportLinkProperty(suffix, target,
|
||||||
"IMPORTED_LINK_INTERFACE_LANGUAGES",
|
"IMPORTED_LINK_INTERFACE_LANGUAGES",
|
||||||
|
|
|
@ -1206,7 +1206,7 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
|
||||||
|
|
||||||
// If the language is compiled as a source trust Xcode to link with it.
|
// If the language is compiled as a source trust Xcode to link with it.
|
||||||
cmTarget::LinkImplementation const* impl =
|
cmTarget::LinkImplementation const* impl =
|
||||||
cmtarget.GetLinkImplementation("NOCONFIG");
|
cmtarget.GetLinkImplementation("NOCONFIG", &cmtarget);
|
||||||
for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
|
for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
|
||||||
li != impl->Languages.end(); ++li)
|
li != impl->Languages.end(); ++li)
|
||||||
{
|
{
|
||||||
|
|
|
@ -72,6 +72,11 @@ struct cmTarget::ImportInfo
|
||||||
cmTarget::LinkInterface LinkInterface;
|
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
|
class cmTargetInternals
|
||||||
{
|
{
|
||||||
|
@ -100,20 +105,24 @@ public:
|
||||||
OptionalLinkInterface(): Exists(false) {}
|
OptionalLinkInterface(): Exists(false) {}
|
||||||
bool Exists;
|
bool Exists;
|
||||||
};
|
};
|
||||||
typedef std::map<cmStdString, OptionalLinkInterface> LinkInterfaceMapType;
|
typedef std::map<TargetConfigPair, OptionalLinkInterface>
|
||||||
|
LinkInterfaceMapType;
|
||||||
LinkInterfaceMapType LinkInterfaceMap;
|
LinkInterfaceMapType LinkInterfaceMap;
|
||||||
|
|
||||||
typedef std::map<cmStdString, cmTarget::OutputInfo> OutputInfoMapType;
|
typedef std::map<cmStdString, cmTarget::OutputInfo> OutputInfoMapType;
|
||||||
OutputInfoMapType OutputInfoMap;
|
OutputInfoMapType OutputInfoMap;
|
||||||
|
|
||||||
typedef std::map<cmStdString, cmTarget::ImportInfo> ImportInfoMapType;
|
typedef std::map<TargetConfigPair, cmTarget::ImportInfo>
|
||||||
|
ImportInfoMapType;
|
||||||
ImportInfoMapType ImportInfoMap;
|
ImportInfoMapType ImportInfoMap;
|
||||||
|
|
||||||
// Cache link implementation computation from each configuration.
|
// Cache link implementation computation from each configuration.
|
||||||
typedef std::map<cmStdString, cmTarget::LinkImplementation> LinkImplMapType;
|
typedef std::map<TargetConfigPair,
|
||||||
|
cmTarget::LinkImplementation> LinkImplMapType;
|
||||||
LinkImplMapType LinkImplMap;
|
LinkImplMapType LinkImplMap;
|
||||||
|
|
||||||
typedef std::map<cmStdString, cmTarget::LinkClosure> LinkClosureMapType;
|
typedef std::map<TargetConfigPair, cmTarget::LinkClosure>
|
||||||
|
LinkClosureMapType;
|
||||||
LinkClosureMapType LinkClosureMap;
|
LinkClosureMapType LinkClosureMap;
|
||||||
|
|
||||||
struct SourceEntry { std::vector<cmSourceFile*> Depends; };
|
struct SourceEntry { std::vector<cmSourceFile*> Depends; };
|
||||||
|
@ -510,6 +519,22 @@ void cmTarget::DefineProperties(cmake *cm)
|
||||||
"Installing a target with EXCLUDE_FROM_ALL set to true has "
|
"Installing a target with EXCLUDE_FROM_ALL set to true has "
|
||||||
"undefined behavior.");
|
"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
|
cm->DefineProperty
|
||||||
("INCLUDE_DIRECTORIES", cmProperty::TARGET,
|
("INCLUDE_DIRECTORIES", cmProperty::TARGET,
|
||||||
"List of preprocessor include file search directories.",
|
"List of preprocessor include file search directories.",
|
||||||
|
@ -2130,6 +2155,66 @@ bool cmTarget::NameResolvesToFramework(const std::string& libname)
|
||||||
NameResolvesToFramework(libname);
|
NameResolvesToFramework(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,
|
void cmTarget::AddLinkLibrary(cmMakefile& mf,
|
||||||
const char *target, const char* lib,
|
const char *target, const char* lib,
|
||||||
|
@ -2140,6 +2225,18 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
|
||||||
{
|
{
|
||||||
return;
|
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;
|
cmTarget::LibraryID tmp;
|
||||||
tmp.first = lib;
|
tmp.first = lib;
|
||||||
tmp.second = llt;
|
tmp.second = llt;
|
||||||
|
@ -3024,8 +3121,11 @@ class cmTargetCollectLinkLanguages
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cmTargetCollectLinkLanguages(cmTarget* target, const char* config,
|
cmTargetCollectLinkLanguages(cmTarget* target, const char* config,
|
||||||
std::set<cmStdString>& languages):
|
std::set<cmStdString>& languages,
|
||||||
Config(config), Languages(languages) { this->Visited.insert(target); }
|
cmTarget* head):
|
||||||
|
Config(config), Languages(languages), HeadTarget(head)
|
||||||
|
{ this->Visited.insert(target); }
|
||||||
|
|
||||||
void Visit(cmTarget* target)
|
void Visit(cmTarget* target)
|
||||||
{
|
{
|
||||||
if(!target || !this->Visited.insert(target).second)
|
if(!target || !this->Visited.insert(target).second)
|
||||||
|
@ -3034,7 +3134,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
cmTarget::LinkInterface const* iface =
|
cmTarget::LinkInterface const* iface =
|
||||||
target->GetLinkInterface(this->Config);
|
target->GetLinkInterface(this->Config, this->HeadTarget);
|
||||||
if(!iface) { return; }
|
if(!iface) { return; }
|
||||||
|
|
||||||
for(std::vector<std::string>::const_iterator
|
for(std::vector<std::string>::const_iterator
|
||||||
|
@ -3053,26 +3153,30 @@ public:
|
||||||
private:
|
private:
|
||||||
const char* Config;
|
const char* Config;
|
||||||
std::set<cmStdString>& Languages;
|
std::set<cmStdString>& Languages;
|
||||||
|
cmTarget* HeadTarget;
|
||||||
std::set<cmTarget*> Visited;
|
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;
|
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
|
cmTargetInternals::LinkClosureMapType::iterator
|
||||||
i = this->Internal->LinkClosureMap.find(key);
|
i = this->Internal->LinkClosureMap.find(key);
|
||||||
if(i == this->Internal->LinkClosureMap.end())
|
if(i == this->Internal->LinkClosureMap.end())
|
||||||
{
|
{
|
||||||
LinkClosure lc;
|
LinkClosure lc;
|
||||||
this->ComputeLinkClosure(config, lc);
|
this->ComputeLinkClosure(config, lc, head);
|
||||||
cmTargetInternals::LinkClosureMapType::value_type entry(key, lc);
|
cmTargetInternals::LinkClosureMapType::value_type entry(key, lc);
|
||||||
i = this->Internal->LinkClosureMap.insert(entry).first;
|
i = this->Internal->LinkClosureMap.insert(entry).first;
|
||||||
}
|
}
|
||||||
|
@ -3133,11 +3237,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.
|
// Get languages built in this target.
|
||||||
std::set<cmStdString> languages;
|
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();
|
for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
|
||||||
li != impl->Languages.end(); ++li)
|
li != impl->Languages.end(); ++li)
|
||||||
{
|
{
|
||||||
|
@ -3145,7 +3250,7 @@ void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add interface languages from linked targets.
|
// 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();
|
for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
|
||||||
li != impl->Libraries.end(); ++li)
|
li != impl->Libraries.end(); ++li)
|
||||||
{
|
{
|
||||||
|
@ -3284,7 +3389,8 @@ bool cmTarget::HasSOName(const char* config)
|
||||||
return ((this->GetType() == cmTarget::SHARED_LIBRARY ||
|
return ((this->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||||
this->GetType() == cmTarget::MODULE_LIBRARY) &&
|
this->GetType() == cmTarget::MODULE_LIBRARY) &&
|
||||||
!this->GetPropertyAsBool("NO_SONAME") &&
|
!this->GetPropertyAsBool("NO_SONAME") &&
|
||||||
this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
|
this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config,
|
||||||
|
this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -3293,7 +3399,7 @@ std::string cmTarget::GetSOName(const char* config)
|
||||||
if(this->IsImported())
|
if(this->IsImported())
|
||||||
{
|
{
|
||||||
// Lookup the imported soname.
|
// Lookup the imported soname.
|
||||||
if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
|
if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
|
||||||
{
|
{
|
||||||
if(info->NoSOName)
|
if(info->NoSOName)
|
||||||
{
|
{
|
||||||
|
@ -3330,7 +3436,7 @@ bool cmTarget::IsImportedSharedLibWithoutSOName(const char* config)
|
||||||
{
|
{
|
||||||
if(this->IsImported() && this->GetType() == cmTarget::SHARED_LIBRARY)
|
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;
|
return info->NoSOName;
|
||||||
}
|
}
|
||||||
|
@ -3444,7 +3550,7 @@ std::string cmTarget::NormalGetFullPath(const char* config, bool implib,
|
||||||
std::string cmTarget::ImportedGetFullPath(const char* config, bool implib)
|
std::string cmTarget::ImportedGetFullPath(const char* config, bool implib)
|
||||||
{
|
{
|
||||||
std::string result;
|
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;
|
result = implib? info->ImportLibrary : info->Location;
|
||||||
}
|
}
|
||||||
|
@ -3529,7 +3635,7 @@ void cmTarget::GetFullNameInternal(const char* config,
|
||||||
const char* suffixVar = this->GetSuffixVariableInternal(implib);
|
const char* suffixVar = this->GetSuffixVariableInternal(implib);
|
||||||
|
|
||||||
// Check for language-specific default prefix and suffix.
|
// 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)
|
if(!targetSuffix && suffixVar && *suffixVar)
|
||||||
{
|
{
|
||||||
|
@ -3900,7 +4006,7 @@ bool cmTarget::NeedRelinkBeforeInstall(const char* config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for rpath support on this platform.
|
// 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_";
|
std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
|
||||||
flagVar += ll;
|
flagVar += ll;
|
||||||
|
@ -4322,7 +4428,7 @@ bool cmTarget::IsChrpathUsed(const char* config)
|
||||||
|
|
||||||
// Enable if the rpath flag uses a separator and the target uses ELF
|
// Enable if the rpath flag uses a separator and the target uses ELF
|
||||||
// binaries.
|
// binaries.
|
||||||
if(const char* ll = this->GetLinkerLanguage(config))
|
if(const char* ll = this->GetLinkerLanguage(config, this))
|
||||||
{
|
{
|
||||||
std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
|
std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
|
||||||
sepVar += ll;
|
sepVar += ll;
|
||||||
|
@ -4346,7 +4452,7 @@ bool cmTarget::IsChrpathUsed(const char* config)
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
cmTarget::ImportInfo const*
|
cmTarget::ImportInfo const*
|
||||||
cmTarget::GetImportInfo(const char* config)
|
cmTarget::GetImportInfo(const char* config, cmTarget *headTarget)
|
||||||
{
|
{
|
||||||
// There is no imported information for non-imported targets.
|
// There is no imported information for non-imported targets.
|
||||||
if(!this->IsImported())
|
if(!this->IsImported())
|
||||||
|
@ -4365,14 +4471,16 @@ cmTarget::GetImportInfo(const char* config)
|
||||||
{
|
{
|
||||||
config_upper = "NOCONFIG";
|
config_upper = "NOCONFIG";
|
||||||
}
|
}
|
||||||
|
TargetConfigPair key(headTarget, config_upper);
|
||||||
typedef cmTargetInternals::ImportInfoMapType ImportInfoMapType;
|
typedef cmTargetInternals::ImportInfoMapType ImportInfoMapType;
|
||||||
|
|
||||||
ImportInfoMapType::const_iterator i =
|
ImportInfoMapType::const_iterator i =
|
||||||
this->Internal->ImportInfoMap.find(config_upper);
|
this->Internal->ImportInfoMap.find(key);
|
||||||
if(i == this->Internal->ImportInfoMap.end())
|
if(i == this->Internal->ImportInfoMap.end())
|
||||||
{
|
{
|
||||||
ImportInfo info;
|
ImportInfo info;
|
||||||
this->ComputeImportInfo(config_upper, info);
|
this->ComputeImportInfo(config_upper, info, headTarget);
|
||||||
ImportInfoMapType::value_type entry(config_upper, info);
|
ImportInfoMapType::value_type entry(key, info);
|
||||||
i = this->Internal->ImportInfoMap.insert(entry).first;
|
i = this->Internal->ImportInfoMap.insert(entry).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4511,8 +4619,10 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmTarget::ComputeImportInfo(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
|
// This method finds information about an imported target from its
|
||||||
// properties. The "IMPORTED_" namespace is reserved for properties
|
// properties. The "IMPORTED_" namespace is reserved for properties
|
||||||
// defined by the project exporting the target.
|
// defined by the project exporting the target.
|
||||||
|
@ -4669,12 +4779,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.
|
// Imported targets have their own link interface.
|
||||||
if(this->IsImported())
|
if(this->IsImported())
|
||||||
{
|
{
|
||||||
if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
|
if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, head))
|
||||||
{
|
{
|
||||||
return &info->LinkInterface;
|
return &info->LinkInterface;
|
||||||
}
|
}
|
||||||
|
@ -4690,14 +4801,15 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup any existing link interface for this configuration.
|
// 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
|
cmTargetInternals::LinkInterfaceMapType::iterator
|
||||||
i = this->Internal->LinkInterfaceMap.find(key);
|
i = this->Internal->LinkInterfaceMap.find(key);
|
||||||
if(i == this->Internal->LinkInterfaceMap.end())
|
if(i == this->Internal->LinkInterfaceMap.end())
|
||||||
{
|
{
|
||||||
// Compute the link interface for this configuration.
|
// Compute the link interface for this configuration.
|
||||||
cmTargetInternals::OptionalLinkInterface iface;
|
cmTargetInternals::OptionalLinkInterface iface;
|
||||||
iface.Exists = this->ComputeLinkInterface(config, iface);
|
iface.Exists = this->ComputeLinkInterface(config, iface, head);
|
||||||
|
|
||||||
// Store the information for this configuration.
|
// Store the information for this configuration.
|
||||||
cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
|
cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
|
||||||
|
@ -4708,7 +4820,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.
|
// Construct the property name suffix for this configuration.
|
||||||
std::string suffix = "_";
|
std::string suffix = "_";
|
||||||
|
@ -4765,7 +4878,8 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
|
||||||
{
|
{
|
||||||
emitted.insert(*li);
|
emitted.insert(*li);
|
||||||
}
|
}
|
||||||
LinkImplementation const* impl = this->GetLinkImplementation(config);
|
LinkImplementation const* impl = this->GetLinkImplementation(config,
|
||||||
|
headTarget);
|
||||||
for(std::vector<std::string>::const_iterator
|
for(std::vector<std::string>::const_iterator
|
||||||
li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
|
li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
|
||||||
{
|
{
|
||||||
|
@ -4793,7 +4907,8 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The link implementation is the default link interface.
|
// 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.Libraries = impl->Libraries;
|
||||||
iface.WrongConfigLibraries = impl->WrongConfigLibraries;
|
iface.WrongConfigLibraries = impl->WrongConfigLibraries;
|
||||||
if(this->GetType() == cmTarget::STATIC_LIBRARY)
|
if(this->GetType() == cmTarget::STATIC_LIBRARY)
|
||||||
|
@ -4825,7 +4940,7 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
cmTarget::LinkImplementation const*
|
cmTarget::LinkImplementation const*
|
||||||
cmTarget::GetLinkImplementation(const char* config)
|
cmTarget::GetLinkImplementation(const char* config, cmTarget *head)
|
||||||
{
|
{
|
||||||
// There is no link implementation for imported targets.
|
// There is no link implementation for imported targets.
|
||||||
if(this->IsImported())
|
if(this->IsImported())
|
||||||
|
@ -4834,14 +4949,15 @@ cmTarget::GetLinkImplementation(const char* config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup any existing link implementation for this configuration.
|
// 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
|
cmTargetInternals::LinkImplMapType::iterator
|
||||||
i = this->Internal->LinkImplMap.find(key);
|
i = this->Internal->LinkImplMap.find(key);
|
||||||
if(i == this->Internal->LinkImplMap.end())
|
if(i == this->Internal->LinkImplMap.end())
|
||||||
{
|
{
|
||||||
// Compute the link implementation for this configuration.
|
// Compute the link implementation for this configuration.
|
||||||
LinkImplementation impl;
|
LinkImplementation impl;
|
||||||
this->ComputeLinkImplementation(config, impl);
|
this->ComputeLinkImplementation(config, impl, head);
|
||||||
|
|
||||||
// Store the information for this configuration.
|
// Store the information for this configuration.
|
||||||
cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
|
cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
|
||||||
|
@ -4853,27 +4969,26 @@ cmTarget::GetLinkImplementation(const char* config)
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmTarget::ComputeLinkImplementation(const char* config,
|
void cmTarget::ComputeLinkImplementation(const char* config,
|
||||||
LinkImplementation& impl)
|
LinkImplementation& impl,
|
||||||
|
cmTarget *head)
|
||||||
{
|
{
|
||||||
// Compute which library configuration to link.
|
// Compute which library configuration to link.
|
||||||
cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
|
cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
|
||||||
|
|
||||||
// Collect libraries directly linked in this configuration.
|
// Collect libraries directly linked in this configuration.
|
||||||
LinkLibraryVectorType const& llibs = this->GetOriginalLinkLibraries();
|
std::vector<std::string> llibs;
|
||||||
for(cmTarget::LinkLibraryVectorType::const_iterator li = llibs.begin();
|
this->GetDirectLinkLibraries(config, llibs, head);
|
||||||
|
for(std::vector<std::string>::const_iterator li = llibs.begin();
|
||||||
li != llibs.end(); ++li)
|
li != llibs.end(); ++li)
|
||||||
{
|
{
|
||||||
// Skip entries that resolve to the target itself or are empty.
|
// 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())
|
if(item == this->GetName() || item.empty())
|
||||||
{
|
{
|
||||||
continue;
|
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();
|
LinkLibraryVectorType const& oldllibs = this->GetOriginalLinkLibraries();
|
||||||
|
@ -4977,16 +5092,19 @@ std::string cmTarget::CheckCMP0004(std::string const& item)
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
cmComputeLinkInformation*
|
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.
|
// Lookup any existing information for this configuration.
|
||||||
std::map<cmStdString, cmComputeLinkInformation*>::iterator
|
TargetConfigPair key(headTarget,
|
||||||
i = this->LinkInformation.find(config?config:"");
|
cmSystemTools::UpperCase(config?config:""));
|
||||||
|
cmTargetLinkInformationMap::iterator
|
||||||
|
i = this->LinkInformation.find(key);
|
||||||
if(i == this->LinkInformation.end())
|
if(i == this->LinkInformation.end())
|
||||||
{
|
{
|
||||||
// Compute information for this configuration.
|
// Compute information for this configuration.
|
||||||
cmComputeLinkInformation* info =
|
cmComputeLinkInformation* info =
|
||||||
new cmComputeLinkInformation(this, config);
|
new cmComputeLinkInformation(this, config, headTarget);
|
||||||
if(!info || !info->Compute())
|
if(!info || !info->Compute())
|
||||||
{
|
{
|
||||||
delete info;
|
delete info;
|
||||||
|
@ -4994,8 +5112,7 @@ cmTarget::GetLinkInformation(const char* config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the information for this configuration.
|
// Store the information for this configuration.
|
||||||
std::map<cmStdString, cmComputeLinkInformation*>::value_type
|
cmTargetLinkInformationMap::value_type entry(key, info);
|
||||||
entry(config?config:"", info);
|
|
||||||
i = this->LinkInformation.insert(entry).first;
|
i = this->LinkInformation.insert(entry).first;
|
||||||
}
|
}
|
||||||
return i->second;
|
return i->second;
|
||||||
|
|
|
@ -25,11 +25,13 @@ class cmSourceFile;
|
||||||
class cmGlobalGenerator;
|
class cmGlobalGenerator;
|
||||||
class cmComputeLinkInformation;
|
class cmComputeLinkInformation;
|
||||||
class cmListFileBacktrace;
|
class cmListFileBacktrace;
|
||||||
|
class cmTarget;
|
||||||
|
|
||||||
struct cmTargetLinkInformationMap:
|
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(cmTargetLinkInformationMap const& r);
|
cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r);
|
||||||
~cmTargetLinkInformationMap();
|
~cmTargetLinkInformationMap();
|
||||||
|
@ -166,6 +168,9 @@ public:
|
||||||
return this->LinkLibraries;}
|
return this->LinkLibraries;}
|
||||||
const LinkLibraryVectorType &GetOriginalLinkLibraries() const
|
const LinkLibraryVectorType &GetOriginalLinkLibraries() const
|
||||||
{return this->OriginalLinkLibraries;}
|
{return this->OriginalLinkLibraries;}
|
||||||
|
void GetDirectLinkLibraries(const char *config,
|
||||||
|
std::vector<std::string> &,
|
||||||
|
cmTarget *head);
|
||||||
|
|
||||||
/** Compute the link type to use for the given configuration. */
|
/** Compute the link type to use for the given configuration. */
|
||||||
LinkLibraryType ComputeLinkType(const char* config);
|
LinkLibraryType ComputeLinkType(const char* config);
|
||||||
|
@ -258,7 +263,8 @@ public:
|
||||||
|
|
||||||
/** Get the link interface for the given configuration. Returns 0
|
/** Get the link interface for the given configuration. Returns 0
|
||||||
if the target cannot be linked. */
|
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
|
/** The link implementation specifies the direct library
|
||||||
dependencies needed by the object files of the target. */
|
dependencies needed by the object files of the target. */
|
||||||
|
@ -274,7 +280,8 @@ public:
|
||||||
// Needed only for OLD behavior of CMP0003.
|
// Needed only for OLD behavior of CMP0003.
|
||||||
std::vector<std::string> WrongConfigLibraries;
|
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
|
/** Link information from the transitive closure of the link
|
||||||
implementation and the interfaces of its dependencies. */
|
implementation and the interfaces of its dependencies. */
|
||||||
|
@ -286,7 +293,7 @@ public:
|
||||||
// Languages whose runtime libraries must be linked.
|
// Languages whose runtime libraries must be linked.
|
||||||
std::vector<std::string> Languages;
|
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
|
/** Strip off leading and trailing whitespace from an item named in
|
||||||
the link dependencies of this target. */
|
the link dependencies of this target. */
|
||||||
|
@ -331,7 +338,7 @@ public:
|
||||||
bool FindSourceFiles();
|
bool FindSourceFiles();
|
||||||
|
|
||||||
///! Return the preferred linker language for this target
|
///! 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
|
/** Get the full name of the target according to the settings in its
|
||||||
makefile. */
|
makefile. */
|
||||||
|
@ -399,7 +406,8 @@ public:
|
||||||
std::string GetInstallNameDirForInstallTree(const char* config,
|
std::string GetInstallNameDirForInstallTree(const char* config,
|
||||||
bool for_xcode = false);
|
bool for_xcode = false);
|
||||||
|
|
||||||
cmComputeLinkInformation* GetLinkInformation(const char* config);
|
cmComputeLinkInformation* GetLinkInformation(const char* config,
|
||||||
|
cmTarget *head = 0);
|
||||||
|
|
||||||
// Get the properties
|
// Get the properties
|
||||||
cmPropertyMap &GetProperties() { return this->Properties; };
|
cmPropertyMap &GetProperties() { return this->Properties; };
|
||||||
|
@ -597,16 +605,19 @@ private:
|
||||||
|
|
||||||
// Cache import information from properties for each configuration.
|
// Cache import information from properties for each configuration.
|
||||||
struct ImportInfo;
|
struct ImportInfo;
|
||||||
ImportInfo const* GetImportInfo(const char* config);
|
ImportInfo const* GetImportInfo(const char* config,
|
||||||
void ComputeImportInfo(std::string const& desired_config, ImportInfo& info);
|
cmTarget *workingTarget);
|
||||||
|
void ComputeImportInfo(std::string const& desired_config, ImportInfo& info,
|
||||||
|
cmTarget *head);
|
||||||
|
|
||||||
cmTargetLinkInformationMap LinkInformation;
|
cmTargetLinkInformationMap LinkInformation;
|
||||||
|
|
||||||
bool ComputeLinkInterface(const char* config, LinkInterface& iface);
|
bool ComputeLinkInterface(const char* config, LinkInterface& iface,
|
||||||
|
cmTarget *head);
|
||||||
|
|
||||||
void ComputeLinkImplementation(const char* config,
|
void ComputeLinkImplementation(const char* config,
|
||||||
LinkImplementation& impl);
|
LinkImplementation& impl, cmTarget *head);
|
||||||
void ComputeLinkClosure(const char* config, LinkClosure& lc);
|
void ComputeLinkClosure(const char* config, LinkClosure& lc, cmTarget *head);
|
||||||
|
|
||||||
void ClearLinkMaps();
|
void ClearLinkMaps();
|
||||||
|
|
||||||
|
@ -614,6 +625,9 @@ private:
|
||||||
|
|
||||||
void ProcessSourceExpression(std::string const& expr);
|
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
|
// The cmMakefile instance that owns this target. This should
|
||||||
// always be set.
|
// always be set.
|
||||||
cmMakefile* Makefile;
|
cmMakefile* Makefile;
|
||||||
|
|
|
@ -34,6 +34,13 @@ generate_export_header(depB)
|
||||||
|
|
||||||
target_link_libraries(depB LINK_PRIVATE depA)
|
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)
|
add_library(depC SHARED depC.cpp)
|
||||||
generate_export_header(depC)
|
generate_export_header(depC)
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,13 @@
|
||||||
|
|
||||||
#include "depA.h"
|
#include "depA.h"
|
||||||
|
|
||||||
|
#include "libgenex.h"
|
||||||
|
|
||||||
int DepB::foo()
|
int DepB::foo()
|
||||||
{
|
{
|
||||||
DepA a;
|
DepA a;
|
||||||
|
|
||||||
return a.foo();
|
LibGenex lg;
|
||||||
|
|
||||||
|
return a.foo() + lg.foo();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
#include "libgenex.h"
|
||||||
|
|
||||||
|
int LibGenex::foo()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
#include "libgenex_export.h"
|
||||||
|
|
||||||
|
#ifndef LIBGENEX_H
|
||||||
|
#define LIBGENEX_H
|
||||||
|
|
||||||
|
struct LIBGENEX_EXPORT LibGenex
|
||||||
|
{
|
||||||
|
int foo();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue