Commit a9f1bf43 authored by Brad King's avatar Brad King Committed by Kitware Robot

Merge topic 'LINK_LIBRARIES-property'

76538627 Add LINK_LIBRARIES property for direct target link dependencies
40cf3fb9 Make linking APIs aware of 'head' target
parents e41d4951 76538627
......@@ -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)
{
......
......@@ -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;
......
......@@ -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)
{
......
......@@ -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;
......
......@@ -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.
{
......@@ -244,8 +270,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();
......
......@@ -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",
......
......@@ -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)
{
......
This diff is collapsed.
......@@ -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();
......@@ -166,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);
......@@ -258,7 +263,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 +280,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 +293,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 +338,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 +406,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 +605,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();
......@@ -614,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;
......
......@@ -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)
......
......@@ -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();
}
#include "libgenex.h"
int LibGenex::foo()
{
return 0;
}
#include "libgenex_export.h"
#ifndef LIBGENEX_H
#define LIBGENEX_H
struct LIBGENEX_EXPORT LibGenex
{
int foo();
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment