summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmComputeLinkDepends.cxx23
-rw-r--r--Source/cmComputeLinkDepends.h1
-rw-r--r--Source/cmExportFileGenerator.cxx8
-rw-r--r--Source/cmTarget.cxx64
-rw-r--r--Source/cmTarget.h6
5 files changed, 101 insertions, 1 deletions
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 50a63eb..b5cee42 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -900,7 +900,7 @@ cmComputeLinkDepends::MakePendingComponent(unsigned int component)
// advantage that the item directly linked by a target requiring
// this component will come first which minimizes the number of
// repeats needed.
- pc.Count = 2;
+ pc.Count = this->ComputeComponentCount(nl);
}
// Store the entries to be seen.
@@ -910,6 +910,27 @@ cmComputeLinkDepends::MakePendingComponent(unsigned int component)
}
//----------------------------------------------------------------------------
+int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
+{
+ int count = 2;
+ for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
+ {
+ if(cmTarget* target = this->EntryList[*ni].Target)
+ {
+ if(cmTarget::LinkInterface const* iface =
+ target->GetLinkInterface(this->Config))
+ {
+ if(iface->Multiplicity > count)
+ {
+ count = iface->Multiplicity;
+ }
+ }
+ }
+ }
+ return count;
+}
+
+//----------------------------------------------------------------------------
void cmComputeLinkDepends::DisplayFinalEntries()
{
fprintf(stderr, "target [%s] links to:\n", this->Target->GetName());
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index d692010..f313319 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -153,6 +153,7 @@ private:
void VisitComponent(unsigned int c);
void VisitEntry(int index);
PendingComponent& MakePendingComponent(unsigned int component);
+ int ComputeComponentCount(NodeList const& nl);
void DisplayFinalEntries();
// Record of the original link line.
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 8c15a26..b8ef417 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -161,6 +161,14 @@ cmExportFileGenerator
this->SetImportLinkProperty(suffix, target,
"IMPORTED_LINK_DEPENDENT_LIBRARIES",
iface->SharedDeps, properties);
+ if(iface->Multiplicity > 0)
+ {
+ std::string prop = "IMPORTED_LINK_INTERFACE_MULTIPLICITY";
+ prop += suffix;
+ cmOStringStream m;
+ m << iface->Multiplicity;
+ properties[prop] = m.str();
+ }
}
}
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 4885b07..8b4ac6f 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -335,6 +335,18 @@ void cmTarget::DefineProperties(cmake *cm)
"for the named configuration.");
cm->DefineProperty
+ ("IMPORTED_LINK_INTERFACE_MULTIPLICITY", cmProperty::TARGET,
+ "Repetition count for cycles of IMPORTED static libraries.",
+ "This is LINK_INTERFACE_MULTIPLICITY for IMPORTED targets.");
+ cm->DefineProperty
+ ("IMPORTED_LINK_INTERFACE_MULTIPLICITY_<CONFIG>", cmProperty::TARGET,
+ "Per-configuration repetition count for cycles of IMPORTED archives.",
+ "This is the configuration-specific version of "
+ "IMPORTED_LINK_INTERFACE_MULTIPLICITY. "
+ "If set, this property completely overrides the generic property "
+ "for the named configuration.");
+
+ cm->DefineProperty
("IMPORTED_LOCATION", cmProperty::TARGET,
"Full path to the main file on disk for an IMPORTED target.",
"Specifies the location of an IMPORTED target file on disk. "
@@ -508,6 +520,25 @@ void cmTarget::DefineProperties(cmake *cm)
"for the named configuration.");
cm->DefineProperty
+ ("LINK_INTERFACE_MULTIPLICITY", cmProperty::TARGET,
+ "Repetition count for STATIC libraries with cyclic dependencies.",
+ "When linking to a STATIC library target with cyclic dependencies the "
+ "linker may need to scan more than once through the archives in the "
+ "strongly connected component of the dependency graph. "
+ "CMake by default constructs the link line so that the linker will "
+ "scan through the component at least twice. "
+ "This property specifies the minimum number of scans if it is larger "
+ "than the default. "
+ "CMake uses the largest value specified by any target in a component.");
+ cm->DefineProperty
+ ("LINK_INTERFACE_MULTIPLICITY_<CONFIG>", cmProperty::TARGET,
+ "Per-configuration repetition count for cycles of STATIC libraries.",
+ "This is the configuration-specific version of "
+ "LINK_INTERFACE_MULTIPLICITY. "
+ "If set, this property completely overrides the generic property "
+ "for the named configuration.");
+
+ cm->DefineProperty
("MAP_IMPORTED_CONFIG_<CONFIG>", cmProperty::TARGET,
"Map from project configuration to IMPORTED target's configuration.",
"List configurations of an imported target that may be used for "
@@ -3877,6 +3908,22 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
info.LinkInterface.Languages);
}
}
+
+ // Get the cyclic repetition count.
+ if(this->GetType() == cmTarget::STATIC_LIBRARY)
+ {
+ std::string linkProp = "IMPORTED_LINK_INTERFACE_MULTIPLICITY";
+ linkProp += suffix;
+ if(const char* config_reps = this->GetProperty(linkProp.c_str()))
+ {
+ sscanf(config_reps, "%u", &info.LinkInterface.Multiplicity);
+ }
+ else if(const char* reps =
+ this->GetProperty("IMPORTED_LINK_INTERFACE_MULTIPLICITY"))
+ {
+ sscanf(reps, "%u", &info.LinkInterface.Multiplicity);
+ }
+ }
}
//----------------------------------------------------------------------------
@@ -4010,6 +4057,23 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
}
}
+ if(this->GetType() == cmTarget::STATIC_LIBRARY)
+ {
+ // How many repetitions are needed if this library has cyclic
+ // dependencies?
+ std::string propName = "LINK_INTERFACE_MULTIPLICITY";
+ propName += suffix;
+ if(const char* config_reps = this->GetProperty(propName.c_str()))
+ {
+ sscanf(config_reps, "%u", &iface.Multiplicity);
+ }
+ else if(const char* reps =
+ this->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
+ {
+ sscanf(reps, "%u", &iface.Multiplicity);
+ }
+ }
+
return true;
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index e0118fc..7b8c2ba 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -249,9 +249,15 @@ public:
// Shared library dependencies needed for linking on some platforms.
std::vector<std::string> SharedDeps;
+ // Number of repetitions of a strongly connected component of two
+ // or more static libraries.
+ int Multiplicity;
+
// Libraries listed for other configurations.
// Needed only for OLD behavior of CMP0003.
std::vector<std::string> WrongConfigLibraries;
+
+ LinkInterface(): Multiplicity(0) {}
};
/** Get the link interface for the given configuration. Returns 0