summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Holtermann <sebholt@xwmw.org>2017-10-25 15:44:28 (GMT)
committerBrad King <brad.king@kitware.com>2017-10-27 13:37:15 (GMT)
commit798e4f2fad4013f1c759d66b42cfcd73d7dac428 (patch)
tree8bf3f5606ee9de9e9fe51bb88af0d9017e6d36f7
parentb305e81b3e7e517cb445a4d0dfba127a3e563170 (diff)
downloadCMake-798e4f2fad4013f1c759d66b42cfcd73d7dac428.zip
CMake-798e4f2fad4013f1c759d66b42cfcd73d7dac428.tar.gz
CMake-798e4f2fad4013f1c759d66b42cfcd73d7dac428.tar.bz2
Autogen: Don't add STATIC_LIBRARY cycle targets to the _autogen dependencies
When a STATIC_LIBRARY cycle is detected we don't add any STATIC_LIBRARY target from the cycle to the `_autogen` target dependencies. Closes #17389
-rw-r--r--Source/cmQtAutoGeneratorInitializer.cxx100
1 files changed, 83 insertions, 17 deletions
diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
index e7080cd..c7550e6 100644
--- a/Source/cmQtAutoGeneratorInitializer.cxx
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -9,6 +9,7 @@
#include "cmFilePathChecksum.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmLinkItem.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
@@ -16,6 +17,7 @@
#include "cmSourceFile.h"
#include "cmSourceGroup.h"
#include "cmState.h"
+#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cm_sys_stat.h"
@@ -24,6 +26,7 @@
#include <algorithm>
#include <array>
+#include <deque>
#include <map>
#include <set>
#include <sstream>
@@ -156,7 +159,7 @@ static void GetConfigs(cmMakefile* makefile, std::string& configDefault,
{
configDefault = makefile->GetConfigurations(configsList);
if (configsList.empty()) {
- configsList.push_back("");
+ configsList.push_back(configDefault);
}
}
@@ -299,6 +302,50 @@ static std::vector<std::string> AddGeneratedSource(
return genFiles;
}
+/* @brief Tests if targetDepend is a STATIC_LIBRARY and if any of its
+ * recursive STATIC_LIBRARY dependencies depends on targetOrigin
+ * (STATIC_LIBRARY cycle).
+ */
+static bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin,
+ cmGeneratorTarget const* targetDepend,
+ std::string const& config)
+{
+ bool cycle = false;
+ if ((targetOrigin->GetType() == cmStateEnums::STATIC_LIBRARY) &&
+ (targetDepend->GetType() == cmStateEnums::STATIC_LIBRARY)) {
+ std::set<cmGeneratorTarget const*> knownLibs;
+ std::deque<cmGeneratorTarget const*> testLibs;
+
+ // Insert initial static_library dependency
+ knownLibs.insert(targetDepend);
+ testLibs.push_back(targetDepend);
+
+ while (!testLibs.empty()) {
+ cmGeneratorTarget const* testTarget = testLibs.front();
+ testLibs.pop_front();
+ // Check if the test target is the origin target (cycle)
+ if (testTarget == targetOrigin) {
+ cycle = true;
+ break;
+ }
+ // Collect all static_library dependencies from the test target
+ cmLinkImplementationLibraries const* libs =
+ testTarget->GetLinkImplementationLibraries(config);
+ if (libs != nullptr) {
+ for (cmLinkItem const& item : libs->Libraries) {
+ cmGeneratorTarget const* depTarget = item.Target;
+ if ((depTarget != nullptr) &&
+ (depTarget->GetType() == cmStateEnums::STATIC_LIBRARY) &&
+ knownLibs.insert(depTarget).second) {
+ testLibs.push_back(depTarget);
+ }
+ }
+ }
+ }
+ }
+ return cycle;
+}
+
struct cmQtAutoGenSetup
{
std::set<std::string> MocSkip;
@@ -631,7 +678,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
GetConfigs(makefile, configDefault, configsList);
std::set<std::string> autogenDependFiles;
- std::set<std::string> autogenDependTargets;
+ std::set<cmTarget*> autogenDependTargets;
std::vector<std::string> autogenProvides;
// Remove build directories on cleanup
@@ -953,7 +1000,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
// Allow target and file dependencies
auto* depTarget = makefile->FindTargetToUse(depName);
if (depTarget != nullptr) {
- autogenDependTargets.insert(depTarget->GetName());
+ autogenDependTargets.insert(depTarget);
} else {
autogenDependFiles.insert(depName);
}
@@ -980,8 +1027,8 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
// Create the autogen target/command
if (usePRE_BUILD) {
// Add additional autogen target dependencies to origin target
- for (std::string const& depTarget : autogenDependTargets) {
- target->Target->AddUtility(depTarget, makefile);
+ for (cmTarget* depTarget : autogenDependTargets) {
+ target->Target->AddUtility(depTarget->GetName(), makefile);
}
// Add the pre-build command directly to bypass the OBJECT_LIBRARY
@@ -999,20 +1046,35 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
target->Target->AddPreBuildCommand(cc);
} else {
- // Add utility target dependencies to the autogen target dependencies
- for (std::string const& depTarget : target->Target->GetUtilities()) {
- autogenDependTargets.insert(depTarget);
- }
+ // Convert file dependencies std::set to std::vector
+ std::vector<std::string> autogenDepends(autogenDependFiles.begin(),
+ autogenDependFiles.end());
+
// Add link library target dependencies to the autogen target dependencies
- for (const auto& item : target->Target->GetOriginalLinkLibraries()) {
- if (makefile->FindTargetToUse(item.first) != nullptr) {
- autogenDependTargets.insert(item.first);
+ for (std::string const& config : configsList) {
+ cmLinkImplementationLibraries const* libs =
+ target->GetLinkImplementationLibraries(config);
+ if (libs != nullptr) {
+ for (cmLinkItem const& item : libs->Libraries) {
+ cmGeneratorTarget const* libTarget = item.Target;
+ if ((libTarget != nullptr) &&
+ !StaticLibraryCycle(target, libTarget, config)) {
+ std::string util;
+ if (configsList.size() > 1) {
+ util += "$<$<CONFIG:";
+ util += config;
+ util += ">:";
+ }
+ util += libTarget->GetName();
+ if (configsList.size() > 1) {
+ util += ">";
+ }
+ autogenDepends.push_back(util);
+ }
+ }
}
}
- // Convert file dependencies std::set to std::vector
- const std::vector<std::string> autogenDepends(autogenDependFiles.begin(),
- autogenDependFiles.end());
// Create autogen target
cmTarget* autogenTarget = makefile->AddUtilityCommand(
autogenTargetName, true, workingDirectory.c_str(),
@@ -1022,9 +1084,13 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
localGen->AddGeneratorTarget(
new cmGeneratorTarget(autogenTarget, localGen));
+ // Forward origin utilities to autogen target
+ for (std::string const& depName : target->Target->GetUtilities()) {
+ autogenTarget->AddUtility(depName, makefile);
+ }
// Add additional autogen target dependencies to autogen target
- for (std::string const& depTarget : autogenDependTargets) {
- autogenTarget->AddUtility(depTarget, makefile);
+ for (cmTarget* depTarget : autogenDependTargets) {
+ autogenTarget->AddUtility(depTarget->GetName(), makefile);
}
// Set FOLDER property in autogen target