ENH: Implemented link-interface specification feature.
- Shared libs and executables with exports may now have explicit transitive link dependencies specified - Created LINK_INTERFACE_LIBRARIES and related properties - Exported targets get the interface libraries as their IMPORTED_LINK_LIBRARIES property. - The export() and install(EXPORT) commands now give an error when a linked target is not included since the user can change the interface libraries instead of adding the target.
This commit is contained in:
parent
22be36f8d5
commit
7902bc06aa
|
@ -263,17 +263,22 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
|
||||||
if(entry.Target)
|
if(entry.Target)
|
||||||
{
|
{
|
||||||
// Follow the target dependencies.
|
// Follow the target dependencies.
|
||||||
if(entry.Target->GetType() != cmTarget::EXECUTABLE)
|
if(entry.Target->IsImported())
|
||||||
{
|
{
|
||||||
if(entry.Target->IsImported())
|
// Imported targets provide their own link information.
|
||||||
{
|
this->AddImportedLinkEntries(depender_index, entry.Target);
|
||||||
this->AddImportedLinkEntries(depender_index, entry.Target);
|
}
|
||||||
}
|
else if(cmTargetLinkInterface const* interface =
|
||||||
else
|
entry.Target->GetLinkInterface(this->Config))
|
||||||
{
|
{
|
||||||
this->AddTargetLinkEntries(depender_index,
|
// This target provides its own link interface information.
|
||||||
entry.Target->GetOriginalLinkLibraries());
|
this->AddLinkEntries(depender_index, *interface);
|
||||||
}
|
}
|
||||||
|
else if(entry.Target->GetType() != cmTarget::EXECUTABLE)
|
||||||
|
{
|
||||||
|
// Use the target's link implementation as the interface.
|
||||||
|
this->AddTargetLinkEntries(depender_index,
|
||||||
|
entry.Target->GetOriginalLinkLibraries());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -16,6 +16,14 @@
|
||||||
=========================================================================*/
|
=========================================================================*/
|
||||||
#include "cmExportBuildFileGenerator.h"
|
#include "cmExportBuildFileGenerator.h"
|
||||||
|
|
||||||
|
#include "cmExportCommand.h"
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmExportBuildFileGenerator::cmExportBuildFileGenerator()
|
||||||
|
{
|
||||||
|
this->ExportCommand = 0;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
||||||
{
|
{
|
||||||
|
@ -116,9 +124,19 @@ void
|
||||||
cmExportBuildFileGenerator
|
cmExportBuildFileGenerator
|
||||||
::ComplainAboutMissingTarget(cmTarget* target, const char* dep)
|
::ComplainAboutMissingTarget(cmTarget* target, const char* dep)
|
||||||
{
|
{
|
||||||
|
if(!this->ExportCommand || !this->ExportCommand->ErrorMessage.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cmOStringStream e;
|
cmOStringStream e;
|
||||||
e << "WARNING: EXPORT(...) includes target " << target->GetName()
|
e << "called with target \"" << target->GetName()
|
||||||
<< " which links to target \"" << dep
|
<< "\" which links to target \"" << dep
|
||||||
<< "\" that is not in the export set.";
|
<< "\" that is not in the export list.\n"
|
||||||
cmSystemTools::Message(e.str().c_str());
|
<< "If the link dependency is not part of the public interface "
|
||||||
|
<< "consider setting the LINK_INTERFACE_LIBRARIES property on \""
|
||||||
|
<< target->GetName() << "\". Otherwise add it to the export list. "
|
||||||
|
<< "If the link dependency is not easy to reference in this call, "
|
||||||
|
<< "consider using the APPEND option with multiple separate calls.";
|
||||||
|
this->ExportCommand->ErrorMessage = e.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#include "cmExportFileGenerator.h"
|
#include "cmExportFileGenerator.h"
|
||||||
|
|
||||||
|
class cmExportCommand;
|
||||||
|
|
||||||
/** \class cmExportBuildFileGenerator
|
/** \class cmExportBuildFileGenerator
|
||||||
* \brief Generate a file exporting targets from a build tree.
|
* \brief Generate a file exporting targets from a build tree.
|
||||||
*
|
*
|
||||||
|
@ -31,12 +33,17 @@
|
||||||
class cmExportBuildFileGenerator: public cmExportFileGenerator
|
class cmExportBuildFileGenerator: public cmExportFileGenerator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
cmExportBuildFileGenerator();
|
||||||
|
|
||||||
/** Set the list of targets to export. */
|
/** Set the list of targets to export. */
|
||||||
void SetExports(std::vector<cmTarget*> const* exports)
|
void SetExports(std::vector<cmTarget*> const* exports)
|
||||||
{ this->Exports = exports; }
|
{ this->Exports = exports; }
|
||||||
|
|
||||||
/** Set whether to append generated code to the output file. */
|
/** Set whether to append generated code to the output file. */
|
||||||
void SetAppendMode(bool append) { this->AppendMode = append; }
|
void SetAppendMode(bool append) { this->AppendMode = append; }
|
||||||
|
|
||||||
|
/** Set the command instance through which errors should be reported. */
|
||||||
|
void SetCommand(cmExportCommand* cmd) { this->ExportCommand = cmd; }
|
||||||
protected:
|
protected:
|
||||||
// Implement virtual methods from the superclass.
|
// Implement virtual methods from the superclass.
|
||||||
virtual bool GenerateMainFile(std::ostream& os);
|
virtual bool GenerateMainFile(std::ostream& os);
|
||||||
|
@ -52,6 +59,7 @@ protected:
|
||||||
ImportPropertyMap& properties);
|
ImportPropertyMap& properties);
|
||||||
|
|
||||||
std::vector<cmTarget*> const* Exports;
|
std::vector<cmTarget*> const* Exports;
|
||||||
|
cmExportCommand* ExportCommand;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -100,12 +100,6 @@ bool cmExportCommand
|
||||||
fname += this->Filename.GetString();
|
fname += this->Filename.GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no targets are to be exported we are done.
|
|
||||||
if(this->Targets.GetVector().empty())
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect the targets to be exported.
|
// Collect the targets to be exported.
|
||||||
std::vector<cmTarget*> targets;
|
std::vector<cmTarget*> targets;
|
||||||
for(std::vector<std::string>::const_iterator
|
for(std::vector<std::string>::const_iterator
|
||||||
|
@ -149,6 +143,7 @@ bool cmExportCommand
|
||||||
ebfg.SetNamespace(this->Namespace.GetCString());
|
ebfg.SetNamespace(this->Namespace.GetCString());
|
||||||
ebfg.SetAppendMode(this->Append.IsEnabled());
|
ebfg.SetAppendMode(this->Append.IsEnabled());
|
||||||
ebfg.SetExports(&targets);
|
ebfg.SetExports(&targets);
|
||||||
|
ebfg.SetCommand(this);
|
||||||
|
|
||||||
// Compute the set of configurations exported.
|
// Compute the set of configurations exported.
|
||||||
if(const char* types =
|
if(const char* types =
|
||||||
|
@ -180,5 +175,12 @@ bool cmExportCommand
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Report generated error message if any.
|
||||||
|
if(!this->ErrorMessage.empty())
|
||||||
|
{
|
||||||
|
this->SetError(this->ErrorMessage.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#include "cmCommand.h"
|
#include "cmCommand.h"
|
||||||
|
|
||||||
|
class cmExportBuildFileGenerator;
|
||||||
|
|
||||||
/** \class cmExportLibraryDependenciesCommand
|
/** \class cmExportLibraryDependenciesCommand
|
||||||
* \brief Add a test to the lists of tests to run.
|
* \brief Add a test to the lists of tests to run.
|
||||||
*
|
*
|
||||||
|
@ -93,6 +95,9 @@ private:
|
||||||
cmCAEnabler Append;
|
cmCAEnabler Append;
|
||||||
cmCAString Namespace;
|
cmCAString Namespace;
|
||||||
cmCAString Filename;
|
cmCAString Filename;
|
||||||
|
|
||||||
|
friend class cmExportBuildFileGenerator;
|
||||||
|
std::string ErrorMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -135,9 +135,18 @@ cmExportFileGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the transitive link dependencies for this configuration.
|
// Add the transitive link dependencies for this configuration.
|
||||||
if(target->GetType() == cmTarget::STATIC_LIBRARY ||
|
if(cmTargetLinkInterface const* interface =
|
||||||
target->GetType() == cmTarget::SHARED_LIBRARY)
|
target->GetLinkInterface(config))
|
||||||
{
|
{
|
||||||
|
// This target provides a link interface, so use it.
|
||||||
|
this->SetImportLinkProperties(config, suffix, target,
|
||||||
|
*interface, properties);
|
||||||
|
}
|
||||||
|
else if(target->GetType() == cmTarget::STATIC_LIBRARY ||
|
||||||
|
target->GetType() == cmTarget::SHARED_LIBRARY)
|
||||||
|
{
|
||||||
|
// The default link interface for static and shared libraries is
|
||||||
|
// their link implementation library list.
|
||||||
this->SetImportLinkProperties(config, suffix, target, properties);
|
this->SetImportLinkProperties(config, suffix, target, properties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,9 +157,6 @@ cmExportFileGenerator
|
||||||
::SetImportLinkProperties(const char* config, std::string const& suffix,
|
::SetImportLinkProperties(const char* config, std::string const& suffix,
|
||||||
cmTarget* target, ImportPropertyMap& properties)
|
cmTarget* target, ImportPropertyMap& properties)
|
||||||
{
|
{
|
||||||
// Get the makefile in which to lookup target information.
|
|
||||||
cmMakefile* mf = target->GetMakefile();
|
|
||||||
|
|
||||||
// Compute which library configuration to link.
|
// Compute which library configuration to link.
|
||||||
cmTarget::LinkLibraryType linkType = cmTarget::OPTIMIZED;
|
cmTarget::LinkLibraryType linkType = cmTarget::OPTIMIZED;
|
||||||
if(config && cmSystemTools::UpperCase(config) == "DEBUG")
|
if(config && cmSystemTools::UpperCase(config) == "DEBUG")
|
||||||
|
@ -158,10 +164,10 @@ cmExportFileGenerator
|
||||||
linkType = cmTarget::DEBUG;
|
linkType = cmTarget::DEBUG;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct the property value.
|
// Construct the list of libs linked for this configuration.
|
||||||
|
std::vector<std::string> actual_libs;
|
||||||
cmTarget::LinkLibraryVectorType const& libs =
|
cmTarget::LinkLibraryVectorType const& libs =
|
||||||
target->GetOriginalLinkLibraries();
|
target->GetOriginalLinkLibraries();
|
||||||
std::string link_libs;
|
|
||||||
const char* sep = "";
|
const char* sep = "";
|
||||||
for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin();
|
for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin();
|
||||||
li != libs.end(); ++li)
|
li != libs.end(); ++li)
|
||||||
|
@ -174,33 +180,66 @@ cmExportFileGenerator
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Separate this from the previous entry.
|
// Store this entry.
|
||||||
link_libs += sep;
|
actual_libs.push_back(li->first);
|
||||||
sep = ";";
|
}
|
||||||
|
|
||||||
|
// Store the entries in the property.
|
||||||
|
this->SetImportLinkProperties(config, suffix, target,
|
||||||
|
actual_libs, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmExportFileGenerator
|
||||||
|
::SetImportLinkProperties(const char* config,
|
||||||
|
std::string const& suffix,
|
||||||
|
cmTarget* target,
|
||||||
|
std::vector<std::string> const& libs,
|
||||||
|
ImportPropertyMap& properties)
|
||||||
|
{
|
||||||
|
// Get the makefile in which to lookup target information.
|
||||||
|
cmMakefile* mf = target->GetMakefile();
|
||||||
|
|
||||||
|
// Construct the property value.
|
||||||
|
std::string link_libs;
|
||||||
|
const char* sep = "";
|
||||||
|
for(std::vector<std::string>::const_iterator li = libs.begin();
|
||||||
|
li != libs.end(); ++li)
|
||||||
|
{
|
||||||
// Append this entry.
|
// Append this entry.
|
||||||
if(cmTarget* tgt = mf->FindTargetToUse(li->first.c_str()))
|
if(cmTarget* tgt = mf->FindTargetToUse(li->c_str()))
|
||||||
{
|
{
|
||||||
// This is a target. Make sure it is included in the export.
|
// This is a target.
|
||||||
if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
|
if(tgt->IsImported())
|
||||||
|
{
|
||||||
|
// The target is imported (and therefore is not in the
|
||||||
|
// export). Append the raw name.
|
||||||
|
link_libs += *li;
|
||||||
|
}
|
||||||
|
else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
|
||||||
{
|
{
|
||||||
// The target is in the export. Append it with the export
|
// The target is in the export. Append it with the export
|
||||||
// namespace.
|
// namespace.
|
||||||
link_libs += this->Namespace;
|
link_libs += this->Namespace;
|
||||||
link_libs += li->first;
|
link_libs += *li;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The target is not in the export. This is probably
|
// The target is not in the export.
|
||||||
// user-error. Warn but add it anyway.
|
if(!this->AppendMode)
|
||||||
this->ComplainAboutMissingTarget(target, li->first.c_str());
|
{
|
||||||
link_libs += li->first;
|
// We are not appending, so all exported targets should be
|
||||||
|
// known here. This is probably user-error.
|
||||||
|
this->ComplainAboutMissingTarget(target, li->c_str());
|
||||||
|
}
|
||||||
|
link_libs += *li;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Append the raw name.
|
// Append the raw name.
|
||||||
link_libs += li->first;
|
link_libs += *li;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,11 @@ protected:
|
||||||
void SetImportLinkProperties(const char* config,
|
void SetImportLinkProperties(const char* config,
|
||||||
std::string const& suffix, cmTarget* target,
|
std::string const& suffix, cmTarget* target,
|
||||||
ImportPropertyMap& properties);
|
ImportPropertyMap& properties);
|
||||||
|
void SetImportLinkProperties(const char* config,
|
||||||
|
std::string const& suffix,
|
||||||
|
cmTarget* target,
|
||||||
|
std::vector<std::string> const& libs,
|
||||||
|
ImportPropertyMap& properties);
|
||||||
|
|
||||||
/** Each subclass knows how to generate its kind of export file. */
|
/** Each subclass knows how to generate its kind of export file. */
|
||||||
virtual bool GenerateMainFile(std::ostream& os) = 0;
|
virtual bool GenerateMainFile(std::ostream& os) = 0;
|
||||||
|
|
|
@ -267,9 +267,13 @@ cmExportInstallFileGenerator
|
||||||
::ComplainAboutMissingTarget(cmTarget* target, const char* dep)
|
::ComplainAboutMissingTarget(cmTarget* target, const char* dep)
|
||||||
{
|
{
|
||||||
cmOStringStream e;
|
cmOStringStream e;
|
||||||
e << "WARNING: INSTALL(EXPORT \"" << this->Name << "\" ...) "
|
e << "INSTALL(EXPORT \"" << this->Name << "\" ...) "
|
||||||
<< "includes target " << target->GetName()
|
<< "includes target \"" << target->GetName()
|
||||||
<< " which links to target \"" << dep
|
<< "\" which links to target \"" << dep
|
||||||
<< "\" that is not in the export set.";
|
<< "\" that is not in the export set. "
|
||||||
cmSystemTools::Message(e.str().c_str());
|
<< "If the link dependency is not part of the public interface "
|
||||||
|
<< "consider setting the LINK_INTERFACE_LIBRARIES property on "
|
||||||
|
<< "target \"" << target->GetName() << "\". "
|
||||||
|
<< "Otherwise add it to the export set.";
|
||||||
|
cmSystemTools::Error(e.str().c_str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,6 +311,28 @@ void cmTarget::DefineProperties(cmake *cm)
|
||||||
"located on disk for the configuration <CONFIG>. "
|
"located on disk for the configuration <CONFIG>. "
|
||||||
"The property is defined only for library and executable targets.");
|
"The property is defined only for library and executable targets.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("LINK_INTERFACE_LIBRARIES", cmProperty::TARGET,
|
||||||
|
"List public interface libraries for a shared library or executable.",
|
||||||
|
"By default linking to a shared library target transitively "
|
||||||
|
"links to targets with which the library itself was linked. "
|
||||||
|
"For an executable with exports (see the ENABLE_EXPORTS property) "
|
||||||
|
"no default transitive link dependencies are used. "
|
||||||
|
"This property replaces the default transitive link dependencies with "
|
||||||
|
"an explict list. "
|
||||||
|
"When the target is linked into another target the libraries "
|
||||||
|
"listed (and recursively their link interface libraries) will be "
|
||||||
|
"provided to the other target also. "
|
||||||
|
"If the list is empty then no transitive link dependencies will be "
|
||||||
|
"incorporated when this target is linked into another target even if "
|
||||||
|
"the default set is non-empty.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("LINK_INTERFACE_LIBRARIES_<CONFIG>", cmProperty::TARGET,
|
||||||
|
"Per-configuration list of public interface libraries for a target.",
|
||||||
|
"This is the configuration-specific version of "
|
||||||
|
"LINK_INTERFACE_LIBRARIES.");
|
||||||
|
|
||||||
cm->DefineProperty
|
cm->DefineProperty
|
||||||
("MAP_IMPORTED_CONFIG_<CONFIG>", cmProperty::TARGET,
|
("MAP_IMPORTED_CONFIG_<CONFIG>", cmProperty::TARGET,
|
||||||
"Map from project configuration to IMPORTED target's configuration.",
|
"Map from project configuration to IMPORTED target's configuration.",
|
||||||
|
@ -3040,6 +3062,80 @@ cmTarget::GetImportedLinkLibraries(const char* config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmTargetLinkInterface const* cmTarget::GetLinkInterface(const char* config)
|
||||||
|
{
|
||||||
|
// Link interfaces are supported only for non-imported shared
|
||||||
|
// libraries and executables that export symbols. Imported targets
|
||||||
|
// provide their own link information.
|
||||||
|
if(this->IsImported() ||
|
||||||
|
(this->GetType() != cmTarget::SHARED_LIBRARY &&
|
||||||
|
!this->IsExecutableWithExports()))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup any existing link interface for this configuration.
|
||||||
|
std::map<cmStdString, cmTargetLinkInterface*>::iterator
|
||||||
|
i = this->LinkInterface.find(config?config:"");
|
||||||
|
if(i == this->LinkInterface.end())
|
||||||
|
{
|
||||||
|
// Compute the link interface for this configuration.
|
||||||
|
cmTargetLinkInterface* interface = this->ComputeLinkInterface(config);
|
||||||
|
|
||||||
|
// Store the information for this configuration.
|
||||||
|
std::map<cmStdString, cmTargetLinkInterface*>::value_type
|
||||||
|
entry(config?config:"", interface);
|
||||||
|
i = this->LinkInterface.insert(entry).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmTargetLinkInterface* cmTarget::ComputeLinkInterface(const char* config)
|
||||||
|
{
|
||||||
|
// Construct the property name suffix for this configuration.
|
||||||
|
std::string suffix = "_";
|
||||||
|
if(config && *config)
|
||||||
|
{
|
||||||
|
suffix += cmSystemTools::UpperCase(config);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
suffix += "NOCONFIG";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup the link interface libraries.
|
||||||
|
const char* libs = 0;
|
||||||
|
{
|
||||||
|
// Lookup the per-configuration property.
|
||||||
|
std::string propName = "LINK_INTERFACE_LIBRARIES";
|
||||||
|
propName += suffix;
|
||||||
|
libs = this->GetProperty(propName.c_str());
|
||||||
|
|
||||||
|
// If not set, try the generic property.
|
||||||
|
if(!libs)
|
||||||
|
{
|
||||||
|
libs = this->GetProperty("LINK_INTERFACE_LIBRARIES");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If still not set, there is no link interface.
|
||||||
|
if(!libs)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the interface libraries even if the list is empty.
|
||||||
|
if(cmTargetLinkInterface* interface = new cmTargetLinkInterface)
|
||||||
|
{
|
||||||
|
cmSystemTools::ExpandListArgument(libs, *interface);
|
||||||
|
return interface;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
cmComputeLinkInformation*
|
cmComputeLinkInformation*
|
||||||
cmTarget::GetLinkInformation(const char* config)
|
cmTarget::GetLinkInformation(const char* config)
|
||||||
|
@ -3088,3 +3184,26 @@ cmTargetLinkInformationMap::~cmTargetLinkInformationMap()
|
||||||
delete i->second;
|
delete i->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmTargetLinkInterfaceMap
|
||||||
|
::cmTargetLinkInterfaceMap(cmTargetLinkInterfaceMap const& r): derived()
|
||||||
|
{
|
||||||
|
// Ideally cmTarget instances should never be copied. However until
|
||||||
|
// we can make a sweep to remove that, this copy constructor avoids
|
||||||
|
// allowing the resources (LinkInterface) from getting copied. In
|
||||||
|
// the worst case this will lead to extra cmTargetLinkInterface
|
||||||
|
// instances. We also enforce in debug mode that the map be emptied
|
||||||
|
// when copied.
|
||||||
|
static_cast<void>(r);
|
||||||
|
assert(r.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmTargetLinkInterfaceMap::~cmTargetLinkInterfaceMap()
|
||||||
|
{
|
||||||
|
for(derived::iterator i = this->begin(); i != this->end(); ++i)
|
||||||
|
{
|
||||||
|
delete i->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,20 @@ struct cmTargetLinkInformationMap:
|
||||||
~cmTargetLinkInformationMap();
|
~cmTargetLinkInformationMap();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct cmTargetLinkInterface: public std::vector<std::string>
|
||||||
|
{
|
||||||
|
typedef std::vector<std::string> derived;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cmTargetLinkInterfaceMap:
|
||||||
|
public std::map<cmStdString, cmTargetLinkInterface*>
|
||||||
|
{
|
||||||
|
typedef std::map<cmStdString, cmTargetLinkInterface*> derived;
|
||||||
|
cmTargetLinkInterfaceMap() {}
|
||||||
|
cmTargetLinkInterfaceMap(cmTargetLinkInterfaceMap const& r);
|
||||||
|
~cmTargetLinkInterfaceMap();
|
||||||
|
};
|
||||||
|
|
||||||
/** \class cmTarget
|
/** \class cmTarget
|
||||||
* \brief Represent a library or executable target loaded from a makefile.
|
* \brief Represent a library or executable target loaded from a makefile.
|
||||||
*
|
*
|
||||||
|
@ -209,6 +223,12 @@ public:
|
||||||
std::vector<std::string> const*
|
std::vector<std::string> const*
|
||||||
GetImportedLinkLibraries(const char* config);
|
GetImportedLinkLibraries(const char* config);
|
||||||
|
|
||||||
|
/** Get the library interface dependencies. This is the set of
|
||||||
|
libraries from which something that links to this target may
|
||||||
|
also receive symbols. Returns 0 if the user has not specified
|
||||||
|
such dependencies or for static libraries. */
|
||||||
|
cmTargetLinkInterface const* GetLinkInterface(const char* config);
|
||||||
|
|
||||||
/** Get the directory in which this target will be built. If the
|
/** Get the directory in which this target will be built. If the
|
||||||
configuration name is given then the generator will add its
|
configuration name is given then the generator will add its
|
||||||
subdirectory for that configuration. Otherwise just the canonical
|
subdirectory for that configuration. Otherwise just the canonical
|
||||||
|
@ -476,6 +496,10 @@ private:
|
||||||
|
|
||||||
cmTargetLinkInformationMap LinkInformation;
|
cmTargetLinkInformationMap LinkInformation;
|
||||||
|
|
||||||
|
// Link interface.
|
||||||
|
cmTargetLinkInterface* ComputeLinkInterface(const char* config);
|
||||||
|
cmTargetLinkInterfaceMap LinkInterface;
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
Loading…
Reference in New Issue