diff options
author | Brad King <brad.king@kitware.com> | 2017-10-27 13:41:11 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2017-10-27 13:41:11 (GMT) |
commit | dc4d2021e121e045a881ebed758d0ab977205621 (patch) | |
tree | f319a55afe90f96cd5016085c79b240aced41b20 | |
parent | f01576012f17d5552bc37d8f436ef7e3b47b3a86 (diff) | |
parent | 3a4db8617e42d47363309fa317d2cac2ee61a684 (diff) | |
download | CMake-dc4d2021e121e045a881ebed758d0ab977205621.zip CMake-dc4d2021e121e045a881ebed758d0ab977205621.tar.gz CMake-dc4d2021e121e045a881ebed758d0ab977205621.tar.bz2 |
Merge branch 'autogen-static-library-cycles' into release-3.10
Merge-request: !1408
-rw-r--r-- | Source/cmQtAutoGeneratorInitializer.cxx | 100 | ||||
-rw-r--r-- | Tests/QtAutogen/CMakeLists.txt | 4 | ||||
-rw-r--r-- | Tests/QtAutogen/staticLibraryCycle/CMakeLists.txt | 17 | ||||
-rw-r--r-- | Tests/QtAutogen/staticLibraryCycle/a.cpp | 7 | ||||
-rw-r--r-- | Tests/QtAutogen/staticLibraryCycle/a.h | 13 | ||||
-rw-r--r-- | Tests/QtAutogen/staticLibraryCycle/b.cpp | 7 | ||||
-rw-r--r-- | Tests/QtAutogen/staticLibraryCycle/b.h | 13 | ||||
-rw-r--r-- | Tests/QtAutogen/staticLibraryCycle/c.cpp | 7 | ||||
-rw-r--r-- | Tests/QtAutogen/staticLibraryCycle/c.h | 13 | ||||
-rw-r--r-- | Tests/QtAutogen/staticLibraryCycle/main.cpp | 8 |
10 files changed, 172 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 diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt index ec35b89..b9d8e46 100644 --- a/Tests/QtAutogen/CMakeLists.txt +++ b/Tests/QtAutogen/CMakeLists.txt @@ -214,5 +214,9 @@ add_subdirectory(objectLibrary) add_subdirectory(sameName) # -- Test +# Tests static library cycles +add_subdirectory(staticLibraryCycle) + +# -- Test # Complex test case add_subdirectory(complex) diff --git a/Tests/QtAutogen/staticLibraryCycle/CMakeLists.txt b/Tests/QtAutogen/staticLibraryCycle/CMakeLists.txt new file mode 100644 index 0000000..144a435 --- /dev/null +++ b/Tests/QtAutogen/staticLibraryCycle/CMakeLists.txt @@ -0,0 +1,17 @@ +# Test AUTOMOC and AUTORCC on source files with the same name +# but in different subdirectories + +set(CMAKE_AUTOMOC ON) + +# Cyclic static libraries +add_library(slc_a STATIC a.cpp) +target_link_libraries(slc_a ${QT_LIBRARIES} slc_b) + +add_library(slc_b STATIC b.cpp) +target_link_libraries(slc_b ${QT_LIBRARIES} slc_c) + +add_library(slc_c STATIC c.cpp) +target_link_libraries(slc_c ${QT_LIBRARIES} slc_a) + +add_executable(slc main.cpp) +target_link_libraries(slc ${QT_LIBRARIES} slc_a) diff --git a/Tests/QtAutogen/staticLibraryCycle/a.cpp b/Tests/QtAutogen/staticLibraryCycle/a.cpp new file mode 100644 index 0000000..97cc66e --- /dev/null +++ b/Tests/QtAutogen/staticLibraryCycle/a.cpp @@ -0,0 +1,7 @@ +#include "a.h" +#include "b.h" + +A::A() +{ + B b; +} diff --git a/Tests/QtAutogen/staticLibraryCycle/a.h b/Tests/QtAutogen/staticLibraryCycle/a.h new file mode 100644 index 0000000..7176170 --- /dev/null +++ b/Tests/QtAutogen/staticLibraryCycle/a.h @@ -0,0 +1,13 @@ +#ifndef CLASSA_HPP +#define CLASSA_HPP + +#include <QObject> + +class A : public QObject +{ + Q_OBJECT +public: + A(); +}; + +#endif diff --git a/Tests/QtAutogen/staticLibraryCycle/b.cpp b/Tests/QtAutogen/staticLibraryCycle/b.cpp new file mode 100644 index 0000000..a807d89 --- /dev/null +++ b/Tests/QtAutogen/staticLibraryCycle/b.cpp @@ -0,0 +1,7 @@ +#include "b.h" +#include "c.h" + +B::B() +{ + C c; +} diff --git a/Tests/QtAutogen/staticLibraryCycle/b.h b/Tests/QtAutogen/staticLibraryCycle/b.h new file mode 100644 index 0000000..ededbd8 --- /dev/null +++ b/Tests/QtAutogen/staticLibraryCycle/b.h @@ -0,0 +1,13 @@ +#ifndef CLASSB_HPP +#define CLASSB_HPP + +#include <QObject> + +class B : public QObject +{ + Q_OBJECT +public: + B(); +}; + +#endif diff --git a/Tests/QtAutogen/staticLibraryCycle/c.cpp b/Tests/QtAutogen/staticLibraryCycle/c.cpp new file mode 100644 index 0000000..7d427c2 --- /dev/null +++ b/Tests/QtAutogen/staticLibraryCycle/c.cpp @@ -0,0 +1,7 @@ +#include "c.h" +#include "a.h" + +C::C() +{ + A a; +} diff --git a/Tests/QtAutogen/staticLibraryCycle/c.h b/Tests/QtAutogen/staticLibraryCycle/c.h new file mode 100644 index 0000000..20f3725 --- /dev/null +++ b/Tests/QtAutogen/staticLibraryCycle/c.h @@ -0,0 +1,13 @@ +#ifndef CLASSC_HPP +#define CLASSC_HPP + +#include <QObject> + +class C : public QObject +{ + Q_OBJECT +public: + C(); +}; + +#endif diff --git a/Tests/QtAutogen/staticLibraryCycle/main.cpp b/Tests/QtAutogen/staticLibraryCycle/main.cpp new file mode 100644 index 0000000..f5b7fd2 --- /dev/null +++ b/Tests/QtAutogen/staticLibraryCycle/main.cpp @@ -0,0 +1,8 @@ +#include "a.h" + +int main(int argv, char** args) +{ + // Object instances + A a; + return 0; +} |