From 952fc65d140a1b36fc2e580d7ca89de231a04412 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 10 Aug 2017 18:27:52 +0200 Subject: Autogen: Clear sources meta data cache Adds cmGeneratorTarget::clearSourcesCache() which clears the cache of precomputed sources lists and object names. The cache gets recomputed on demand. Clearing the cache is necessary in case an OBJECT library gets a source added after a target (ORIGIN) that includes it computed it's external sources cache. This may happen in AUTOMOC when ORIGIN is processed before the OBJECT library which gets a mocs_compilation.cpp file added. Closes #17152 Closes #17139 Closes #17085 Closes #15967 --- Source/cmGeneratorTarget.cxx | 10 ++++++++-- Source/cmGeneratorTarget.h | 5 +++++ Source/cmQtAutoGeneratorInitializer.cxx | 6 ++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 329c7a9..95f4543 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -326,6 +326,13 @@ std::string cmGeneratorTarget::GetOutputName( return i->second; } +void cmGeneratorTarget::ClearSourcesCache() +{ + this->KindedSourcesMap.clear(); + this->LinkImplementationLanguageIsContextDependent = true; + this->Objects.clear(); +} + void cmGeneratorTarget::AddSourceCommon(const std::string& src) { cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); @@ -333,8 +340,7 @@ void cmGeneratorTarget::AddSourceCommon(const std::string& src) CM_AUTO_PTR cge = ge.Parse(src); cge->SetEvaluateForBuildsystem(true); this->SourceEntries.push_back(new TargetPropertyEntry(cge)); - this->KindedSourcesMap.clear(); - this->LinkImplementationLanguageIsContextDependent = true; + this->ClearSourcesCache(); } void cmGeneratorTarget::AddSource(const std::string& src) diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 52147e3..b5f7f6e 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -491,6 +491,11 @@ public: std::string GetOutputName(const std::string& config, cmStateEnums::ArtifactType artifact) const; + /** Clears cached meta data for local and external source files. + * The meta data will be recomputed on demand. + */ + void ClearSourcesCache(); + void AddSource(const std::string& src); void AddTracedSources(std::vector const& srcs); diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 5a06730..2cf2ee9 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -919,6 +919,12 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( } } + // cmGeneratorTarget::GetConfigCommonSourceFiles computes the target's + // sources meta data cache. Clear it so that OBJECT library targets that + // are AUTOGEN initialized after this target get their added + // mocs_compilation.cpp source acknowledged by this target. + target->ClearSourcesCache(); + // Convert std::set to std::vector const std::vector autogenDepends(autogenDependsSet.begin(), autogenDependsSet.end()); -- cgit v0.12 From 362f9bd755c7b964184db38d1fb2217ded70af63 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Wed, 9 Aug 2017 11:22:56 +0200 Subject: Autogen: Merge and remove redundant function calls --- Source/cmGlobalGenerator.cxx | 47 +++++++++++++++++---------------- Source/cmQtAutoGeneratorInitializer.cxx | 30 +++++++-------------- Source/cmQtAutoGeneratorInitializer.h | 1 - 3 files changed, 34 insertions(+), 44 deletions(-) diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index c8b13ad..18d10c5 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1433,31 +1433,36 @@ cmGlobalGenerator::CreateQtAutoGeneratorsTargets() std::vector autogenTargets; #ifdef CMAKE_BUILD_WITH_CMAKE - for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) { - std::vector targets = - this->LocalGenerators[i]->GetGeneratorTargets(); + for (std::vector::const_iterator lgit = + this->LocalGenerators.begin(); + lgit != this->LocalGenerators.end(); ++lgit) { + cmLocalGenerator* localGen = *lgit; + const std::vector& targets = + localGen->GetGeneratorTargets(); + // Find targets that require AUTOGEN processing std::vector filteredTargets; filteredTargets.reserve(targets.size()); - for (std::vector::iterator ti = targets.begin(); + for (std::vector::const_iterator ti = targets.begin(); ti != targets.end(); ++ti) { - if ((*ti)->GetType() == cmStateEnums::GLOBAL_TARGET) { + cmGeneratorTarget* target = *ti; + if (target->GetType() == cmStateEnums::GLOBAL_TARGET) { continue; } - if ((*ti)->GetType() != cmStateEnums::EXECUTABLE && - (*ti)->GetType() != cmStateEnums::STATIC_LIBRARY && - (*ti)->GetType() != cmStateEnums::SHARED_LIBRARY && - (*ti)->GetType() != cmStateEnums::MODULE_LIBRARY && - (*ti)->GetType() != cmStateEnums::OBJECT_LIBRARY) { + if (target->GetType() != cmStateEnums::EXECUTABLE && + target->GetType() != cmStateEnums::STATIC_LIBRARY && + target->GetType() != cmStateEnums::SHARED_LIBRARY && + target->GetType() != cmStateEnums::MODULE_LIBRARY && + target->GetType() != cmStateEnums::OBJECT_LIBRARY) { continue; } - if ((!(*ti)->GetPropertyAsBool("AUTOMOC") && - !(*ti)->GetPropertyAsBool("AUTOUIC") && - !(*ti)->GetPropertyAsBool("AUTORCC")) || - (*ti)->IsImported()) { + if ((!target->GetPropertyAsBool("AUTOMOC") && + !target->GetPropertyAsBool("AUTOUIC") && + !target->GetPropertyAsBool("AUTORCC")) || + target->IsImported()) { continue; } - // don't do anything if there is no Qt4 or Qt5Core (which contains moc): - cmMakefile* mf = (*ti)->Target->GetMakefile(); + // don't do anything if there is no Qt4 or Qt5Core (which contains moc) + cmMakefile* mf = target->Target->GetMakefile(); std::string qtMajorVersion = mf->GetSafeDefinition("QT_VERSION_MAJOR"); if (qtMajorVersion == "") { qtMajorVersion = mf->GetSafeDefinition("Qt5Core_VERSION_MAJOR"); @@ -1465,17 +1470,13 @@ cmGlobalGenerator::CreateQtAutoGeneratorsTargets() if (qtMajorVersion != "4" && qtMajorVersion != "5") { continue; } - - cmGeneratorTarget* gt = *ti; - - cmQtAutoGeneratorInitializer::InitializeAutogenSources(gt); - filteredTargets.push_back(gt); + filteredTargets.push_back(target); } + // Initialize AUTOGEN targets for (std::vector::iterator ti = filteredTargets.begin(); ti != filteredTargets.end(); ++ti) { - cmQtAutoGeneratorInitializer::InitializeAutogenTarget( - this->LocalGenerators[i], *ti); + cmQtAutoGeneratorInitializer::InitializeAutogenTarget(localGen, *ti); autogenTargets.push_back(*ti); } } diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 2cf2ee9..7974977 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -263,13 +263,17 @@ static bool AddToSourceGroup(cmMakefile* makefile, const std::string& fileName, return true; } -static void AddGeneratedSource(cmMakefile* makefile, +static void AddGeneratedSource(cmGeneratorTarget* target, const std::string& filename, cmQtAutoGeneratorCommon::GeneratorType genType) { - cmSourceFile* gFile = makefile->GetOrCreateSource(filename, true); - gFile->SetProperty("GENERATED", "1"); - gFile->SetProperty("SKIP_AUTOGEN", "On"); + cmMakefile* makefile = target->Target->GetMakefile(); + { + cmSourceFile* gFile = makefile->GetOrCreateSource(filename, true); + gFile->SetProperty("GENERATED", "1"); + gFile->SetProperty("SKIP_AUTOGEN", "On"); + } + target->AddSource(filename); AddToSourceGroup(makefile, filename, genType); } @@ -692,19 +696,6 @@ static void RccSetupAutoTarget(cmGeneratorTarget const* target, AddDefinitionEscaped(makefile, "_rcc_options_options", rccFileOptions); } -void cmQtAutoGeneratorInitializer::InitializeAutogenSources( - cmGeneratorTarget* target) -{ - if (target->GetPropertyAsBool("AUTOMOC")) { - cmMakefile* makefile = target->Target->GetMakefile(); - // Mocs compilation file - const std::string mocsComp = - GetAutogenTargetBuildDir(target) + "/mocs_compilation.cpp"; - AddGeneratedSource(makefile, mocsComp, cmQtAutoGeneratorCommon::MOC); - target->AddSource(mocsComp); - } -} - void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( cmLocalGenerator* lg, cmGeneratorTarget* target) { @@ -781,6 +772,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( // Add moc compilation to generated files list if (mocEnabled) { const std::string mocsComp = autogenBuildDir + "/mocs_compilation.cpp"; + AddGeneratedSource(target, mocsComp, cmQtAutoGeneratorCommon::MOC); autogenProvides.push_back(mocsComp); } @@ -880,10 +872,8 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( rccBuildFile += ".cpp"; // Register rcc ouput file as generated - AddGeneratedSource(makefile, rccBuildFile, + AddGeneratedSource(target, rccBuildFile, cmQtAutoGeneratorCommon::RCC); - // Add rcc output file to origin target sources - target->AddSource(rccBuildFile); // Register rcc ouput file as generated by the _autogen target autogenProvides.push_back(rccBuildFile); } diff --git a/Source/cmQtAutoGeneratorInitializer.h b/Source/cmQtAutoGeneratorInitializer.h index ca806f5..11f6e1e 100644 --- a/Source/cmQtAutoGeneratorInitializer.h +++ b/Source/cmQtAutoGeneratorInitializer.h @@ -11,7 +11,6 @@ class cmLocalGenerator; class cmQtAutoGeneratorInitializer { public: - static void InitializeAutogenSources(cmGeneratorTarget* target); static void InitializeAutogenTarget(cmLocalGenerator* lg, cmGeneratorTarget* target); static void SetupAutoGenerateTarget(cmGeneratorTarget const* target); -- cgit v0.12 From 15ef27286ade97a49f6832254d3451755a824fb8 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 10 Aug 2017 19:16:16 +0200 Subject: Autogen: Add test for OBJECT libraries --- Tests/QtAutogen/CMakeLists.txt | 4 ++++ Tests/QtAutogen/objectLibrary/CMakeLists.txt | 14 ++++++++++++++ Tests/QtAutogen/objectLibrary/a/CMakeLists.txt | 2 ++ Tests/QtAutogen/objectLibrary/a/classa.cpp | 7 +++++++ Tests/QtAutogen/objectLibrary/a/classa.h | 23 +++++++++++++++++++++++ Tests/QtAutogen/objectLibrary/b/classb.cpp | 7 +++++++ Tests/QtAutogen/objectLibrary/b/classb.h | 23 +++++++++++++++++++++++ Tests/QtAutogen/objectLibrary/main.cpp | 13 +++++++++++++ 8 files changed, 93 insertions(+) create mode 100644 Tests/QtAutogen/objectLibrary/CMakeLists.txt create mode 100644 Tests/QtAutogen/objectLibrary/a/CMakeLists.txt create mode 100644 Tests/QtAutogen/objectLibrary/a/classa.cpp create mode 100644 Tests/QtAutogen/objectLibrary/a/classa.h create mode 100644 Tests/QtAutogen/objectLibrary/b/classb.cpp create mode 100644 Tests/QtAutogen/objectLibrary/b/classb.h create mode 100644 Tests/QtAutogen/objectLibrary/main.cpp diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt index 5064d26..198bf63 100644 --- a/Tests/QtAutogen/CMakeLists.txt +++ b/Tests/QtAutogen/CMakeLists.txt @@ -193,5 +193,9 @@ endif() add_subdirectory(uicInclude) # -- Test +# OBJECT libraries +add_subdirectory(objectLibrary) + +# -- Test # Complex test case add_subdirectory(complex) diff --git a/Tests/QtAutogen/objectLibrary/CMakeLists.txt b/Tests/QtAutogen/objectLibrary/CMakeLists.txt new file mode 100644 index 0000000..9b29a40 --- /dev/null +++ b/Tests/QtAutogen/objectLibrary/CMakeLists.txt @@ -0,0 +1,14 @@ +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_AUTOMOC ON) + +# Object library a defined in a subdirectory +add_subdirectory(a) + +# Object library b defined locally +include_directories(b) +add_library(b OBJECT b/classb.cpp) +target_compile_features(b PRIVATE ${QT_COMPILE_FEATURES}) + +# Executable with OBJECT library generator expressions +add_executable(someProgram main.cpp $ $) +target_link_libraries(someProgram ${QT_LIBRARIES}) diff --git a/Tests/QtAutogen/objectLibrary/a/CMakeLists.txt b/Tests/QtAutogen/objectLibrary/a/CMakeLists.txt new file mode 100644 index 0000000..fe76ac3 --- /dev/null +++ b/Tests/QtAutogen/objectLibrary/a/CMakeLists.txt @@ -0,0 +1,2 @@ +add_library(a OBJECT classa.cpp) +target_compile_features(a PRIVATE ${QT_COMPILE_FEATURES}) diff --git a/Tests/QtAutogen/objectLibrary/a/classa.cpp b/Tests/QtAutogen/objectLibrary/a/classa.cpp new file mode 100644 index 0000000..4f08fda --- /dev/null +++ b/Tests/QtAutogen/objectLibrary/a/classa.cpp @@ -0,0 +1,7 @@ +#include "classa.h" +#include + +void ClassA::slotDoSomething() +{ + qDebug() << m_member; +} diff --git a/Tests/QtAutogen/objectLibrary/a/classa.h b/Tests/QtAutogen/objectLibrary/a/classa.h new file mode 100644 index 0000000..fa5fed9 --- /dev/null +++ b/Tests/QtAutogen/objectLibrary/a/classa.h @@ -0,0 +1,23 @@ +#ifndef CLASSA_H +#define CLASSA_H + +#include +#include + +class ClassA : public QObject +{ + Q_OBJECT +public: + ClassA() + : m_member("Hello A") + { + } + +public slots: + void slotDoSomething(); + +private: + QString m_member; +}; + +#endif diff --git a/Tests/QtAutogen/objectLibrary/b/classb.cpp b/Tests/QtAutogen/objectLibrary/b/classb.cpp new file mode 100644 index 0000000..26e0926 --- /dev/null +++ b/Tests/QtAutogen/objectLibrary/b/classb.cpp @@ -0,0 +1,7 @@ +#include "classb.h" +#include + +void ClassB::slotDoSomething() +{ + qDebug() << m_member; +} diff --git a/Tests/QtAutogen/objectLibrary/b/classb.h b/Tests/QtAutogen/objectLibrary/b/classb.h new file mode 100644 index 0000000..783bb48 --- /dev/null +++ b/Tests/QtAutogen/objectLibrary/b/classb.h @@ -0,0 +1,23 @@ +#ifndef CLASSB_H +#define CLASSB_H + +#include +#include + +class ClassB : public QObject +{ + Q_OBJECT +public: + ClassB() + : m_member("Hello B") + { + } + +public slots: + void slotDoSomething(); + +private: + QString m_member; +}; + +#endif diff --git a/Tests/QtAutogen/objectLibrary/main.cpp b/Tests/QtAutogen/objectLibrary/main.cpp new file mode 100644 index 0000000..cacf0fd --- /dev/null +++ b/Tests/QtAutogen/objectLibrary/main.cpp @@ -0,0 +1,13 @@ +#include "a/classa.h" +#include "b/classb.h" + +int main(int argc, char** argv) +{ + ClassA a; + a.slotDoSomething(); + + ClassB b; + b.slotDoSomething(); + + return 0; +} -- cgit v0.12