diff options
-rw-r--r-- | Modules/AutogenInfo.cmake.in | 3 | ||||
-rw-r--r-- | Source/CMakeLists.txt | 5 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 74 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.h | 4 | ||||
-rw-r--r-- | Source/cmQtAutoGen.cxx (renamed from Source/cmQtAutoGeneratorCommon.cxx) | 49 | ||||
-rw-r--r-- | Source/cmQtAutoGen.h (renamed from Source/cmQtAutoGeneratorCommon.h) | 18 | ||||
-rw-r--r-- | Source/cmQtAutoGenDigest.h | 62 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorInitializer.cxx | 784 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorInitializer.h | 13 | ||||
-rw-r--r-- | Source/cmQtAutoGenerators.cxx | 300 | ||||
-rw-r--r-- | Source/cmQtAutoGenerators.h | 7 |
11 files changed, 660 insertions, 659 deletions
diff --git a/Modules/AutogenInfo.cmake.in b/Modules/AutogenInfo.cmake.in index 60ceebc..80522ab 100644 --- a/Modules/AutogenInfo.cmake.in +++ b/Modules/AutogenInfo.cmake.in @@ -9,6 +9,7 @@ set(AM_SOURCES @_sources@) set(AM_HEADERS @_headers@) # Qt environment set(AM_QT_VERSION_MAJOR @_qt_version_major@) +set(AM_QT_VERSION_MINOR @_qt_version_minor@) set(AM_QT_MOC_EXECUTABLE @_qt_moc_executable@) set(AM_QT_UIC_EXECUTABLE @_qt_uic_executable@) set(AM_QT_RCC_EXECUTABLE @_qt_rcc_executable@) @@ -28,7 +29,7 @@ set(AM_UIC_OPTIONS_FILES @_qt_uic_options_files@) set(AM_UIC_OPTIONS_OPTIONS @_qt_uic_options_options@) set(AM_UIC_SEARCH_PATHS @_uic_search_paths@) # RCC settings -set(AM_RCC_SOURCES @_rcc_files@ ) +set(AM_RCC_SOURCES @_rcc_files@) set(AM_RCC_INPUTS @_rcc_inputs@) set(AM_RCC_OPTIONS_FILES @_rcc_options_files@) set(AM_RCC_OPTIONS_OPTIONS @_rcc_options_options@) diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index bcc3437..9cd7b84 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -307,8 +307,9 @@ set(SRCS cmPropertyDefinitionMap.h cmPropertyMap.cxx cmPropertyMap.h - cmQtAutoGeneratorCommon.cxx - cmQtAutoGeneratorCommon.h + cmQtAutoGen.cxx + cmQtAutoGen.h + cmQtAutoGenDigest.h cmQtAutoGeneratorInitializer.cxx cmQtAutoGeneratorInitializer.h cmQtAutoGenerators.cxx diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index ab35593..39c181a 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1263,8 +1263,7 @@ bool cmGlobalGenerator::Compute() #ifdef CMAKE_BUILD_WITH_CMAKE // Iterate through all targets and set up automoc for those which have // the AUTOMOC, AUTOUIC or AUTORCC property set - std::vector<cmGeneratorTarget const*> autogenTargets = - this->CreateQtAutoGeneratorsTargets(); + cmQtAutoGenDigestUPV autogenDigests = this->CreateQtAutoGeneratorsTargets(); #endif unsigned int i; @@ -1287,11 +1286,10 @@ bool cmGlobalGenerator::Compute() } #ifdef CMAKE_BUILD_WITH_CMAKE - for (std::vector<cmGeneratorTarget const*>::iterator it = - autogenTargets.begin(); - it != autogenTargets.end(); ++it) { - cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(*it); + for (const cmQtAutoGenDigestUP& digest : autogenDigests) { + cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(*digest); } + autogenDigests.clear(); #endif for (i = 0; i < this->LocalGenerators.size(); ++i) { @@ -1427,24 +1425,16 @@ bool cmGlobalGenerator::ComputeTargetDepends() return true; } -std::vector<const cmGeneratorTarget*> -cmGlobalGenerator::CreateQtAutoGeneratorsTargets() +cmQtAutoGenDigestUPV cmGlobalGenerator::CreateQtAutoGeneratorsTargets() { - std::vector<const cmGeneratorTarget*> autogenTargets; + cmQtAutoGenDigestUPV autogenDigests; #ifdef CMAKE_BUILD_WITH_CMAKE - for (std::vector<cmLocalGenerator*>::const_iterator lgit = - this->LocalGenerators.begin(); - lgit != this->LocalGenerators.end(); ++lgit) { - cmLocalGenerator* localGen = *lgit; + for (cmLocalGenerator* localGen : this->LocalGenerators) { const std::vector<cmGeneratorTarget*>& targets = localGen->GetGeneratorTargets(); // Find targets that require AUTOGEN processing - std::vector<cmGeneratorTarget*> filteredTargets; - filteredTargets.reserve(targets.size()); - for (std::vector<cmGeneratorTarget*>::const_iterator ti = targets.begin(); - ti != targets.end(); ++ti) { - cmGeneratorTarget* target = *ti; + for (cmGeneratorTarget* target : targets) { if (target->GetType() == cmStateEnums::GLOBAL_TARGET) { continue; } @@ -1455,33 +1445,43 @@ cmGlobalGenerator::CreateQtAutoGeneratorsTargets() target->GetType() != cmStateEnums::OBJECT_LIBRARY) { continue; } - if ((!target->GetPropertyAsBool("AUTOMOC") && - !target->GetPropertyAsBool("AUTOUIC") && - !target->GetPropertyAsBool("AUTORCC")) || - target->IsImported()) { + if (target->IsImported()) { continue; } - // 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"); + + const bool mocEnabled = target->GetPropertyAsBool("AUTOMOC"); + const bool uicEnabled = target->GetPropertyAsBool("AUTOUIC"); + const bool rccEnabled = target->GetPropertyAsBool("AUTORCC"); + if (!mocEnabled && !uicEnabled && !rccEnabled) { + continue; } - if (qtMajorVersion != "4" && qtMajorVersion != "5") { + + std::string qtVersionMajor = + cmQtAutoGeneratorInitializer::GetQtMajorVersion(target); + // don't do anything if there is no Qt4 or Qt5Core (which contains moc) + if (qtVersionMajor != "4" && qtVersionMajor != "5") { continue; } - filteredTargets.push_back(target); - } - // Initialize AUTOGEN targets - for (std::vector<cmGeneratorTarget*>::iterator ti = - filteredTargets.begin(); - ti != filteredTargets.end(); ++ti) { - cmQtAutoGeneratorInitializer::InitializeAutogenTarget(localGen, *ti); - autogenTargets.push_back(*ti); + + { + cmQtAutoGenDigestUP digest(new cmQtAutoGenDigest(target)); + digest->QtVersionMajor = std::move(qtVersionMajor); + digest->QtVersionMinor = + cmQtAutoGeneratorInitializer::GetQtMinorVersion( + target, digest->QtVersionMajor); + digest->MocEnabled = mocEnabled; + digest->UicEnabled = uicEnabled; + digest->RccEnabled = rccEnabled; + autogenDigests.emplace_back(std::move(digest)); + } } } + // Initialize autogen targets + for (const cmQtAutoGenDigestUP& digest : autogenDigests) { + cmQtAutoGeneratorInitializer::InitializeAutogenTarget(*digest); + } #endif - return autogenTargets; + return autogenDigests; } cmLinkLineComputer* cmGlobalGenerator::CreateLinkLineComputer( diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 3931ab8..18ca682 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -15,6 +15,7 @@ #include "cmCustomCommandLines.h" #include "cmExportSetMap.h" +#include "cmQtAutoGenDigest.h" #include "cmStateSnapshot.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -422,7 +423,8 @@ protected: virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const; - std::vector<const cmGeneratorTarget*> CreateQtAutoGeneratorsTargets(); + // Qt auto generators + cmQtAutoGenDigestUPV CreateQtAutoGeneratorsTargets(); std::string SelectMakeProgram(const std::string& makeProgram, const std::string& makeDefault = "") const; diff --git a/Source/cmQtAutoGeneratorCommon.cxx b/Source/cmQtAutoGen.cxx index a8e6b96..f1453b4 100644 --- a/Source/cmQtAutoGeneratorCommon.cxx +++ b/Source/cmQtAutoGen.cxx @@ -1,6 +1,6 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmQtAutoGeneratorCommon.h" +#include "cmQtAutoGen.h" #include "cmAlgorithms.h" #include "cmSystemTools.h" @@ -10,6 +10,13 @@ #include <sstream> #include <stddef.h> +// - Static variables + +const std::string genNameGen = "AutoGen"; +const std::string genNameMoc = "AutoMoc"; +const std::string genNameUic = "AutoUic"; +const std::string genNameRcc = "AutoRcc"; + // - Static functions static std::string utilStripCR(std::string const& line) @@ -41,7 +48,7 @@ static bool RccListInputsQt4(const std::string& fileName, if (errorMessage != nullptr) { std::ostringstream ost; ost << "AutoRcc: Error: Rcc file not readable:\n" - << cmQtAutoGeneratorCommon::Quoted(fileName) << "\n"; + << cmQtAutoGen::Quoted(fileName) << "\n"; *errorMessage = ost.str(); } allGood = false; @@ -156,7 +163,7 @@ static bool RccListInputsQt5(const std::string& rccCommand, if (errorMessage != nullptr) { std::ostringstream ost; ost << "AutoRcc: Error: Rcc lists unparsable output:\n" - << cmQtAutoGeneratorCommon::Quoted(eline) << "\n"; + << cmQtAutoGen::Quoted(eline) << "\n"; *errorMessage = ost.str(); } return false; @@ -173,9 +180,29 @@ static bool RccListInputsQt5(const std::string& rccCommand, // - Class definitions -const char* cmQtAutoGeneratorCommon::listSep = "@LSEP@"; +const std::string cmQtAutoGen::listSep = "@LSEP@"; + +const std::string& cmQtAutoGen::GeneratorName(GeneratorType type) +{ + switch (type) { + case GeneratorType::GEN: + return genNameGen; + case GeneratorType::MOC: + return genNameMoc; + case GeneratorType::UIC: + return genNameUic; + case GeneratorType::RCC: + return genNameRcc; + } + return genNameGen; +} + +std::string cmQtAutoGen::GeneratorNameUpper(GeneratorType genType) +{ + return cmSystemTools::UpperCase(cmQtAutoGen::GeneratorName(genType)); +} -std::string cmQtAutoGeneratorCommon::Quoted(const std::string& text) +std::string cmQtAutoGen::Quoted(const std::string& text) { static const char* rep[18] = { "\\", "\\\\", "\"", "\\\"", "\a", "\\a", "\b", "\\b", "\f", "\\f", "\n", "\\n", @@ -191,11 +218,11 @@ std::string cmQtAutoGeneratorCommon::Quoted(const std::string& text) return res; } -bool cmQtAutoGeneratorCommon::RccListInputs(const std::string& qtMajorVersion, - const std::string& rccCommand, - const std::string& fileName, - std::vector<std::string>& files, - std::string* errorMessage) +bool cmQtAutoGen::RccListInputs(const std::string& qtMajorVersion, + const std::string& rccCommand, + const std::string& fileName, + std::vector<std::string>& files, + std::string* errorMessage) { bool allGood = false; if (cmsys::SystemTools::FileExists(fileName.c_str())) { @@ -208,7 +235,7 @@ bool cmQtAutoGeneratorCommon::RccListInputs(const std::string& qtMajorVersion, if (errorMessage != nullptr) { std::ostringstream ost; ost << "AutoRcc: Error: Rcc file does not exist:\n" - << cmQtAutoGeneratorCommon::Quoted(fileName) << "\n"; + << cmQtAutoGen::Quoted(fileName) << "\n"; *errorMessage = ost.str(); } } diff --git a/Source/cmQtAutoGeneratorCommon.h b/Source/cmQtAutoGen.h index 23a882a..88fd0fc 100644 --- a/Source/cmQtAutoGeneratorCommon.h +++ b/Source/cmQtAutoGen.h @@ -1,27 +1,35 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cmQtAutoGeneratorCommon_h -#define cmQtAutoGeneratorCommon_h +#ifndef cmQtAutoGen_h +#define cmQtAutoGen_h #include "cmConfigure.h" // IWYU pragma: keep #include <string> #include <vector> -class cmQtAutoGeneratorCommon +/** \class cmQtAutoGen + * \brief Class used as namespace for QtAutogen related types and functions + */ +class cmQtAutoGen { - // - Types and statics public: - static const char* listSep; + static const std::string listSep; enum GeneratorType { + GEN, // General MOC, UIC, RCC }; public: + /// @brief Returns the generator name + static const std::string& GeneratorName(GeneratorType genType); + /// @brief Returns the generator name in upper case + static std::string GeneratorNameUpper(GeneratorType genType); + /// @brief Returns a the string escaped and enclosed in quotes /// static std::string Quoted(const std::string& text); diff --git a/Source/cmQtAutoGenDigest.h b/Source/cmQtAutoGenDigest.h new file mode 100644 index 0000000..2bd9f04 --- /dev/null +++ b/Source/cmQtAutoGenDigest.h @@ -0,0 +1,62 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmQtAutoGenDigest_h +#define cmQtAutoGenDigest_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include <memory> +#include <string> +#include <vector> + +class cmGeneratorTarget; + +class cmQtAutoGenDigestQrc +{ +public: + cmQtAutoGenDigestQrc() + : Generated(false) + { + } + +public: + std::string QrcFile; + std::string RccFile; + bool Generated; + std::vector<std::string> Options; + std::vector<std::string> Resources; +}; + +/** \class cmQtAutoGenDigest + * \brief Filtered set of QtAutogen variables for a specific target + */ +class cmQtAutoGenDigest +{ +public: + cmQtAutoGenDigest(cmGeneratorTarget* target) + : Target(target) + , MocEnabled(false) + , UicEnabled(false) + , RccEnabled(false) + { + } + +public: + cmGeneratorTarget* Target; + std::string QtVersionMajor; + std::string QtVersionMinor; + bool MocEnabled; + bool UicEnabled; + bool RccEnabled; + std::vector<std::string> Headers; + std::vector<std::string> HeadersGenerated; + std::vector<std::string> Sources; + std::vector<std::string> SourcesGenerated; + std::vector<cmQtAutoGenDigestQrc> Qrcs; +}; + +// Utility types +typedef std::unique_ptr<cmQtAutoGenDigest> cmQtAutoGenDigestUP; +typedef std::vector<cmQtAutoGenDigestUP> cmQtAutoGenDigestUPV; + +#endif diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index ebfb6f0..3fe4028 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -1,7 +1,7 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmQtAutoGen.h" #include "cmQtAutoGeneratorInitializer.h" -#include "cmQtAutoGeneratorCommon.h" #include "cmAlgorithms.h" #include "cmCustomCommand.h" @@ -23,6 +23,7 @@ #include "cmsys/FStream.hxx" #include <algorithm> +#include <array> #include <map> #include <set> #include <sstream> @@ -35,12 +36,18 @@ inline static const char* SafeString(const char* value) return (value != nullptr) ? value : ""; } -static std::string GetSafeProperty(cmGeneratorTarget const* target, - const char* key) +inline static std::string GetSafeProperty(cmGeneratorTarget const* target, + const char* key) { return std::string(SafeString(target->GetProperty(key))); } +inline static std::string GetSafeProperty(cmSourceFile const* sf, + const char* key) +{ + return std::string(SafeString(sf->GetProperty(key))); +} + inline static bool AutogenMultiConfig(cmGlobalGenerator* globalGen) { return globalGen->IsMultiConfig(); @@ -76,39 +83,40 @@ static std::string GetAutogenTargetBuildDir(cmGeneratorTarget const* target) return targetDir; } -static std::string GetQtMajorVersion(cmGeneratorTarget const* target) +std::string cmQtAutoGeneratorInitializer::GetQtMajorVersion( + cmGeneratorTarget const* target) { cmMakefile* makefile = target->Target->GetMakefile(); - std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR"); - if (qtMajorVersion.empty()) { - qtMajorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR"); + std::string qtMajor = makefile->GetSafeDefinition("QT_VERSION_MAJOR"); + if (qtMajor.empty()) { + qtMajor = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR"); } const char* targetQtVersion = target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", ""); if (targetQtVersion != nullptr) { - qtMajorVersion = targetQtVersion; + qtMajor = targetQtVersion; } - return qtMajorVersion; + return qtMajor; } -static std::string GetQtMinorVersion(cmGeneratorTarget const* target, - const std::string& qtMajorVersion) +std::string cmQtAutoGeneratorInitializer::GetQtMinorVersion( + cmGeneratorTarget const* target, const std::string& qtVersionMajor) { cmMakefile* makefile = target->Target->GetMakefile(); - std::string qtMinorVersion; - if (qtMajorVersion == "5") { - qtMinorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MINOR"); + std::string qtMinor; + if (qtVersionMajor == "5") { + qtMinor = makefile->GetSafeDefinition("Qt5Core_VERSION_MINOR"); } - if (qtMinorVersion.empty()) { - qtMinorVersion = makefile->GetSafeDefinition("QT_VERSION_MINOR"); + if (qtMinor.empty()) { + qtMinor = makefile->GetSafeDefinition("QT_VERSION_MINOR"); } const char* targetQtVersion = target->GetLinkInterfaceDependentStringProperty("QT_MINOR_VERSION", ""); if (targetQtVersion != nullptr) { - qtMinorVersion = targetQtVersion; + qtMinor = targetQtVersion; } - return qtMinorVersion; + return qtMinor; } static bool QtVersionGreaterOrEqual(const std::string& major, @@ -168,9 +176,8 @@ static std::vector<std::string> GetConfigurationSuffixes(cmMakefile* makefile) std::vector<std::string> suffixes; if (AutogenMultiConfig(makefile->GetGlobalGenerator())) { makefile->GetConfigurations(suffixes); - for (std::vector<std::string>::iterator it = suffixes.begin(); - it != suffixes.end(); ++it) { - it->insert(0, "_"); + for (std::string& suffix : suffixes) { + suffix.insert(0, "_"); } } if (suffixes.empty()) { @@ -201,32 +208,39 @@ static void AddDefinitionEscaped(cmMakefile* makefile, const char* key, } static bool AddToSourceGroup(cmMakefile* makefile, const std::string& fileName, - cmQtAutoGeneratorCommon::GeneratorType genType) + cmQtAutoGen::GeneratorType genType) { cmSourceGroup* sourceGroup = nullptr; // Acquire source group { - const char* groupName = nullptr; - // Use generator specific group name - switch (genType) { - case cmQtAutoGeneratorCommon::MOC: - groupName = - makefile->GetState()->GetGlobalProperty("AUTOMOC_SOURCE_GROUP"); - break; - case cmQtAutoGeneratorCommon::RCC: - groupName = - makefile->GetState()->GetGlobalProperty("AUTORCC_SOURCE_GROUP"); - break; - default: - break; - } - // Use default group name on demand - if ((groupName == nullptr) || (*groupName == 0)) { - groupName = - makefile->GetState()->GetGlobalProperty("AUTOGEN_SOURCE_GROUP"); + std::string property; + std::string groupName; + { + std::array<std::string, 2> props; + // Use generator specific group name + switch (genType) { + case cmQtAutoGen::MOC: + props[0] = "AUTOMOC_SOURCE_GROUP"; + break; + case cmQtAutoGen::RCC: + props[0] = "AUTORCC_SOURCE_GROUP"; + break; + default: + props[0] = "AUTOGEN_SOURCE_GROUP"; + break; + } + props[1] = "AUTOGEN_SOURCE_GROUP"; + for (std::string& prop : props) { + const char* propName = makefile->GetState()->GetGlobalProperty(prop); + if ((propName != nullptr) && (*propName != '\0')) { + groupName = propName; + property = std::move(prop); + break; + } + } } // Generate a source group on demand - if ((groupName != nullptr) && (*groupName != 0)) { + if (!groupName.empty()) { { const char* delimiter = makefile->GetDefinition("SOURCE_GROUP_DELIMITER"); @@ -242,9 +256,12 @@ static bool AddToSourceGroup(cmMakefile* makefile, const std::string& fileName, } } if (sourceGroup == nullptr) { - cmSystemTools::Error( - "Autogen: Could not create or find source group: ", - cmQtAutoGeneratorCommon::Quoted(groupName).c_str()); + std::ostringstream ost; + ost << cmQtAutoGen::GeneratorNameUpper(genType); + ost << ": " << property; + ost << ": Could not find or create the source group "; + ost << cmQtAutoGen::Quoted(groupName); + cmSystemTools::Error(ost.str().c_str()); return false; } } @@ -263,7 +280,7 @@ static void AddCleanFile(cmMakefile* makefile, const std::string& fileName) static void AddGeneratedSource(cmGeneratorTarget* target, const std::string& filename, - cmQtAutoGeneratorCommon::GeneratorType genType) + cmQtAutoGen::GeneratorType genType) { cmMakefile* makefile = target->Target->GetMakefile(); { @@ -276,32 +293,24 @@ static void AddGeneratedSource(cmGeneratorTarget* target, AddToSourceGroup(makefile, filename, genType); } -struct AutogenSetup +struct cmQtAutoGenSetup { - std::vector<std::string> sources; - std::vector<std::string> headers; + std::set<std::string> MocSkip; + std::set<std::string> UicSkip; - std::set<std::string> mocSkip; - std::set<std::string> uicSkip; - - std::map<std::string, std::string> configSuffix; - std::map<std::string, std::string> configMocIncludes; - std::map<std::string, std::string> configMocDefines; - std::map<std::string, std::string> configUicOptions; + std::map<std::string, std::string> ConfigMocIncludes; + std::map<std::string, std::string> ConfigMocDefines; + std::map<std::string, std::string> ConfigUicOptions; }; -static void SetupAcquireScanFiles(cmGeneratorTarget const* target, - bool mocEnabled, bool uicEnabled, - const std::vector<cmSourceFile*>& srcFiles, - AutogenSetup& setup) +static void SetupAcquireSkipFiles(cmQtAutoGenDigest const& digest, + cmQtAutoGenSetup& setup) { // Read skip files from makefile sources { const std::vector<cmSourceFile*>& allSources = - target->Makefile->GetSourceFiles(); - for (std::vector<cmSourceFile*>::const_iterator fit = allSources.begin(); - fit != allSources.end(); ++fit) { - cmSourceFile* sf = *fit; + digest.Target->Makefile->GetSourceFiles(); + for (cmSourceFile* sf : allSources) { // sf->GetExtension() is only valid after sf->GetFullPath() ... const std::string& fPath = sf->GetFullPath(); const cmSystemTools::FileFormat fileType = @@ -311,95 +320,33 @@ static void SetupAcquireScanFiles(cmGeneratorTarget const* target, continue; } const bool skipAll = sf->GetPropertyAsBool("SKIP_AUTOGEN"); - const bool mocSkip = - mocEnabled && (skipAll || sf->GetPropertyAsBool("SKIP_AUTOMOC")); - const bool uicSkip = - uicEnabled && (skipAll || sf->GetPropertyAsBool("SKIP_AUTOUIC")); + const bool mocSkip = digest.MocEnabled && + (skipAll || sf->GetPropertyAsBool("SKIP_AUTOMOC")); + const bool uicSkip = digest.UicEnabled && + (skipAll || sf->GetPropertyAsBool("SKIP_AUTOUIC")); if (mocSkip || uicSkip) { const std::string absFile = cmsys::SystemTools::GetRealPath(fPath); if (mocSkip) { - setup.mocSkip.insert(absFile); + setup.MocSkip.insert(absFile); } if (uicSkip) { - setup.uicSkip.insert(absFile); + setup.UicSkip.insert(absFile); } } } } - - const cmPolicies::PolicyStatus CMP0071_status = - target->Makefile->GetPolicyStatus(cmPolicies::CMP0071); - for (std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin(); - fileIt != srcFiles.end(); ++fileIt) { - cmSourceFile* sf = *fileIt; - // sf->GetExtension() is only valid after sf->GetFullPath() ... - const std::string& fPath = sf->GetFullPath(); - const cmSystemTools::FileFormat fileType = - cmSystemTools::GetFileFormat(sf->GetExtension().c_str()); - if (!(fileType == cmSystemTools::CXX_FILE_FORMAT) && - !(fileType == cmSystemTools::HEADER_FILE_FORMAT)) { - continue; - } - // Real file path - const std::string absFile = cmsys::SystemTools::GetRealPath(fPath); - // Skip test - const bool mocSkip = !mocEnabled || (setup.mocSkip.count(absFile) != 0); - const bool uicSkip = !uicEnabled || (setup.uicSkip.count(absFile) != 0); - if (mocSkip && uicSkip) { - continue; - } - - // For GENERATED files check status of policy CMP0071 - if (sf->GetPropertyAsBool("GENERATED")) { - bool policyAccept = false; - switch (CMP0071_status) { - case cmPolicies::WARN: { - std::ostringstream ost; - ost << cmPolicies::GetPolicyWarning(cmPolicies::CMP0071) << "\n"; - ost << "AUTOMOC/AUTOUIC: Ignoring GENERATED source file:\n"; - ost << " " << cmQtAutoGeneratorCommon::Quoted(absFile) << "\n"; - target->Makefile->IssueMessage(cmake::AUTHOR_WARNING, ost.str()); - } - CM_FALLTHROUGH; - case cmPolicies::OLD: - // Ignore GENERATED file - break; - case cmPolicies::REQUIRED_IF_USED: - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::NEW: - // Process GENERATED file - policyAccept = true; - break; - } - if (!policyAccept) { - continue; - } - } - - // Add file name to sources or headers list - switch (fileType) { - case cmSystemTools::CXX_FILE_FORMAT: - setup.sources.push_back(absFile); - break; - case cmSystemTools::HEADER_FILE_FORMAT: - setup.headers.push_back(absFile); - break; - default: - break; - } - } } -static void SetupAutoTargetMoc(cmGeneratorTarget const* target, - std::string const& qtMajorVersion, +static void SetupAutoTargetMoc(const cmQtAutoGenDigest& digest, std::string const& config, std::vector<std::string> const& configs, - AutogenSetup& setup) + cmQtAutoGenSetup& setup) { + cmGeneratorTarget const* target = digest.Target; cmLocalGenerator* localGen = target->GetLocalGenerator(); cmMakefile* makefile = target->Target->GetMakefile(); - AddDefinitionEscaped(makefile, "_moc_skip", setup.mocSkip); + AddDefinitionEscaped(makefile, "_moc_skip", setup.MocSkip); AddDefinitionEscaped(makefile, "_moc_options", GetSafeProperty(target, "AUTOMOC_MOC_OPTIONS")); AddDefinitionEscaped(makefile, "_moc_relaxed_mode", @@ -410,8 +357,8 @@ static void SetupAutoTargetMoc(cmGeneratorTarget const* target, AddDefinitionEscaped(makefile, "_moc_depend_filters", GetSafeProperty(target, "AUTOMOC_DEPEND_FILTERS")); - if (QtVersionGreaterOrEqual( - qtMajorVersion, GetQtMinorVersion(target, qtMajorVersion), 5, 8)) { + if (QtVersionGreaterOrEqual(digest.QtVersionMajor, digest.QtVersionMinor, 5, + 8)) { AddDefinitionEscaped( makefile, "_moc_predefs_cmd", makefile->GetSafeDefinition("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND")); @@ -426,17 +373,16 @@ static void SetupAutoTargetMoc(cmGeneratorTarget const* target, AddDefinitionEscaped(makefile, "_moc_compile_defs", compileDefs); // Configuration specific settings - for (std::vector<std::string>::const_iterator li = configs.begin(); - li != configs.end(); ++li) { + for (const std::string& cfg : configs) { std::string configIncs; std::string configCompileDefs; - GetCompileDefinitionsAndDirectories(target, *li, configIncs, + GetCompileDefinitionsAndDirectories(target, cfg, configIncs, configCompileDefs); if (configIncs != incs) { - setup.configMocIncludes[*li] = configIncs; + setup.ConfigMocIncludes[cfg] = configIncs; } if (configCompileDefs != compileDefs) { - setup.configMocDefines[*li] = configCompileDefs; + setup.ConfigMocDefines[cfg] = configCompileDefs; } } } @@ -446,14 +392,14 @@ static void SetupAutoTargetMoc(cmGeneratorTarget const* target, std::string mocExec; std::string err; - if (qtMajorVersion == "5") { + if (digest.QtVersionMajor == "5") { cmGeneratorTarget* tgt = localGen->FindGeneratorTargetToUse("Qt5::moc"); if (tgt != nullptr) { mocExec = SafeString(tgt->ImportedGetLocation("")); } else { err = "AUTOMOC: Qt5::moc target not found"; } - } else if (qtMajorVersion == "4") { + } else if (digest.QtVersionMajor == "4") { cmGeneratorTarget* tgt = localGen->FindGeneratorTargetToUse("Qt4::moc"); if (tgt != nullptr) { mocExec = SafeString(tgt->ImportedGetLocation("")); @@ -481,16 +427,15 @@ static void UicGetOpts(cmGeneratorTarget const* target, optString = cmJoin(opts, ";"); } -static void SetupAutoTargetUic(cmGeneratorTarget const* target, - std::string const& qtMajorVersion, +static void SetupAutoTargetUic(const cmQtAutoGenDigest& digest, std::string const& config, std::vector<std::string> const& configs, - AutogenSetup& setup) + cmQtAutoGenSetup& setup) { - cmLocalGenerator* localGen = target->GetLocalGenerator(); + cmGeneratorTarget const* target = digest.Target; cmMakefile* makefile = target->Target->GetMakefile(); - AddDefinitionEscaped(makefile, "_uic_skip", setup.uicSkip); + AddDefinitionEscaped(makefile, "_uic_skip", setup.UicSkip); // Uic search paths { @@ -500,9 +445,8 @@ static void SetupAutoTargetUic(cmGeneratorTarget const* target, if (!usp.empty()) { cmSystemTools::ExpandListArgument(usp, uicSearchPaths); const std::string srcDir = makefile->GetCurrentSourceDirectory(); - for (std::vector<std::string>::iterator it = uicSearchPaths.begin(); - it != uicSearchPaths.end(); ++it) { - *it = cmSystemTools::CollapseFullPath(*it, srcDir); + for (std::string& path : uicSearchPaths) { + path = cmSystemTools::CollapseFullPath(path, srcDir); } } } @@ -516,12 +460,11 @@ static void SetupAutoTargetUic(cmGeneratorTarget const* target, AddDefinitionEscaped(makefile, "_uic_target_options", uicOpts); // Configuration specific settings - for (std::vector<std::string>::const_iterator li = configs.begin(); - li != configs.end(); ++li) { + for (const std::string& cfg : configs) { std::string configUicOpts; - UicGetOpts(target, *li, configUicOpts); + UicGetOpts(target, cfg, configUicOpts); if (configUicOpts != uicOpts) { - setup.configUicOptions[*li] = configUicOpts; + setup.ConfigUicOptions[cfg] = configUicOpts; } } } @@ -532,21 +475,18 @@ static void SetupAutoTargetUic(cmGeneratorTarget const* target, { const std::string uiExt = "ui"; const std::vector<cmSourceFile*>& srcFiles = makefile->GetSourceFiles(); - for (std::vector<cmSourceFile*>::const_iterator fit = srcFiles.begin(); - fit != srcFiles.end(); ++fit) { - cmSourceFile* sf = *fit; + for (cmSourceFile* sf : srcFiles) { // sf->GetExtension() is only valid after sf->GetFullPath() ... const std::string& fPath = sf->GetFullPath(); if (sf->GetExtension() == uiExt) { // Check if the files has uic options - std::string uicOpts = sf->GetProperty("AUTOUIC_OPTIONS"); + std::string uicOpts = GetSafeProperty(sf, "AUTOUIC_OPTIONS"); if (!uicOpts.empty()) { const std::string absFile = cmsys::SystemTools::GetRealPath(fPath); // Check if file isn't skipped - if (setup.uicSkip.count(absFile) == 0) { + if (setup.UicSkip.count(absFile) == 0) { uiFileFiles.push_back(absFile); - cmSystemTools::ReplaceString(uicOpts, ";", - cmQtAutoGeneratorCommon::listSep); + cmSystemTools::ReplaceString(uicOpts, ";", cmQtAutoGen::listSep); uiFileOptions.push_back(uicOpts); } } @@ -562,14 +502,15 @@ static void SetupAutoTargetUic(cmGeneratorTarget const* target, std::string err; std::string uicExec; - if (qtMajorVersion == "5") { + cmLocalGenerator* localGen = target->GetLocalGenerator(); + if (digest.QtVersionMajor == "5") { cmGeneratorTarget* tgt = localGen->FindGeneratorTargetToUse("Qt5::uic"); if (tgt != nullptr) { uicExec = SafeString(tgt->ImportedGetLocation("")); } else { // Project does not use Qt5Widgets, but has AUTOUIC ON anyway } - } else if (qtMajorVersion == "4") { + } else if (digest.QtVersionMajor == "4") { cmGeneratorTarget* tgt = localGen->FindGeneratorTargetToUse("Qt4::uic"); if (tgt != nullptr) { uicExec = SafeString(tgt->ImportedGetLocation("")); @@ -625,14 +566,16 @@ static void RccMergeOptions(std::vector<std::string>& opts, const std::vector<std::string>& fileOpts, bool isQt5) { - static const char* valueOptions[] = { "name", "root", "compress", - "threshold" }; + typedef std::vector<std::string>::iterator Iter; + typedef std::vector<std::string>::const_iterator CIter; + static const char* valueOptions[4] = { "name", "root", "compress", + "threshold" }; + std::vector<std::string> extraOpts; - for (std::vector<std::string>::const_iterator fit = fileOpts.begin(); - fit != fileOpts.end(); ++fit) { - std::vector<std::string>::iterator existingIt = - std::find(opts.begin(), opts.end(), *fit); - if (existingIt != opts.end()) { + for (CIter fit = fileOpts.begin(), fitEnd = fileOpts.end(); fit != fitEnd; + ++fit) { + Iter existIt = std::find(opts.begin(), opts.end(), *fit); + if (existIt != opts.end()) { const char* optName = fit->c_str(); if (*optName == '-') { ++optName; @@ -644,10 +587,10 @@ static void RccMergeOptions(std::vector<std::string>& opts, if ((optName != fit->c_str()) && std::find_if(cmArrayBegin(valueOptions), cmArrayEnd(valueOptions), cmStrCmp(optName)) != cmArrayEnd(valueOptions)) { - const std::vector<std::string>::iterator existValueIt(existingIt + 1); - const std::vector<std::string>::const_iterator fileValueIt(fit + 1); - if ((existValueIt != opts.end()) && (fileValueIt != fileOpts.end())) { - *existValueIt = *fileValueIt; + const Iter existItNext(existIt + 1); + const CIter fitNext(fit + 1); + if ((existItNext != opts.end()) && (fitNext != fitEnd)) { + *existItNext = *fitNext; ++fit; } } @@ -655,73 +598,42 @@ static void RccMergeOptions(std::vector<std::string>& opts, extraOpts.push_back(*fit); } } + // Append options opts.insert(opts.end(), extraOpts.begin(), extraOpts.end()); } -static void SetupAutoTargetRcc(cmGeneratorTarget const* target, - const std::string& qtMajorVersion, - const std::vector<cmSourceFile*>& srcFiles) +static void SetupAutoTargetRcc(const cmQtAutoGenDigest& digest) { + cmGeneratorTarget const* target = digest.Target; cmMakefile* makefile = target->Target->GetMakefile(); - const bool qtMajorVersion5 = (qtMajorVersion == "5"); - const std::string rccCommand = RccGetExecutable(target, qtMajorVersion); std::vector<std::string> rccFiles; std::vector<std::string> rccInputs; std::vector<std::string> rccFileFiles; std::vector<std::string> rccFileOptions; - std::vector<std::string> rccOptionsTarget; - - cmSystemTools::ExpandListArgument(GetSafeProperty(target, "AUTORCC_OPTIONS"), - rccOptionsTarget); - - for (std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin(); - fileIt != srcFiles.end(); ++fileIt) { - cmSourceFile* sf = *fileIt; - // sf->GetExtension() is only valid after sf->GetFullPath() ... - const std::string& fPath = sf->GetFullPath(); - if ((sf->GetExtension() == "qrc") && - !sf->GetPropertyAsBool("SKIP_AUTOGEN") && - !sf->GetPropertyAsBool("SKIP_AUTORCC")) { - const std::string absFile = cmsys::SystemTools::GetRealPath(fPath); - // qrc file - rccFiles.push_back(absFile); - // qrc file entries - { - std::string entriesList = "{"; - // Read input file list only for non generated .qrc files. - if (!sf->GetPropertyAsBool("GENERATED")) { - std::string error; - std::vector<std::string> files; - if (cmQtAutoGeneratorCommon::RccListInputs( - qtMajorVersion, rccCommand, absFile, files, &error)) { - entriesList += cmJoin(files, cmQtAutoGeneratorCommon::listSep); - } else { - cmSystemTools::Error(error.c_str()); - } - } - entriesList += "}"; - rccInputs.push_back(entriesList); - } - // rcc options for this qrc file - { - // Merged target and file options - std::vector<std::string> rccOptions(rccOptionsTarget); - if (const char* prop = sf->GetProperty("AUTORCC_OPTIONS")) { - std::vector<std::string> optsVec; - cmSystemTools::ExpandListArgument(prop, optsVec); - RccMergeOptions(rccOptions, optsVec, qtMajorVersion5); - } - // Only store non empty options lists - if (!rccOptions.empty()) { - rccFileFiles.push_back(absFile); - rccFileOptions.push_back( - cmJoin(rccOptions, cmQtAutoGeneratorCommon::listSep)); - } + + for (const cmQtAutoGenDigestQrc& qrcDigest : digest.Qrcs) { + const std::string absFile = qrcDigest.QrcFile; + // Register file + rccFiles.push_back(absFile); + // Register (known) resource files + { + std::string entriesList = "{"; + if (!qrcDigest.Generated) { + entriesList += cmJoin(qrcDigest.Resources, cmQtAutoGen::listSep); } + entriesList += "}"; + rccInputs.push_back(entriesList); + } + // rcc options for this qrc file + if (!qrcDigest.Options.empty()) { + rccFileFiles.push_back(absFile); + rccFileOptions.push_back( + cmJoin(qrcDigest.Options, cmQtAutoGen::listSep)); } } - AddDefinitionEscaped(makefile, "_qt_rcc_executable", rccCommand); + AddDefinitionEscaped(makefile, "_qt_rcc_executable", + RccGetExecutable(target, digest.QtVersionMajor)); AddDefinitionEscaped(makefile, "_rcc_files", rccFiles); AddDefinitionEscaped(makefile, "_rcc_inputs", rccInputs); AddDefinitionEscaped(makefile, "_rcc_options_files", rccFileFiles); @@ -729,33 +641,23 @@ static void SetupAutoTargetRcc(cmGeneratorTarget const* target, } void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( - cmLocalGenerator* localGen, cmGeneratorTarget* target) + cmQtAutoGenDigest& digest) { + cmGeneratorTarget* target = digest.Target; cmMakefile* makefile = target->Target->GetMakefile(); + cmLocalGenerator* localGen = target->GetLocalGenerator(); cmGlobalGenerator* globalGen = localGen->GetGlobalGenerator(); // Create a custom target for running generators at buildtime - const bool mocEnabled = target->GetPropertyAsBool("AUTOMOC"); - const bool uicEnabled = target->GetPropertyAsBool("AUTOUIC"); - const bool rccEnabled = target->GetPropertyAsBool("AUTORCC"); const bool multiConfig = AutogenMultiConfig(globalGen); const std::string autogenTargetName = GetAutogenTargetName(target); const std::string autogenBuildDir = GetAutogenTargetBuildDir(target); const std::string workingDirectory = cmSystemTools::CollapseFullPath("", makefile->GetCurrentBinaryDirectory()); const std::vector<std::string> suffixes = GetConfigurationSuffixes(makefile); - std::set<std::string> autogenDependsSet; + std::set<std::string> autogenDepends; std::vector<std::string> autogenProvides; - bool usePRE_BUILD = false; - if (globalGen->GetName().find("Visual Studio") != std::string::npos) { - // Under VS use a PRE_BUILD event instead of a separate target to - // reduce the number of targets loaded into the IDE. - // This also works around a VS 11 bug that may skip updating the target: - // https://connect.microsoft.com/VisualStudio/feedback/details/769495 - usePRE_BUILD = true; - } - // Remove build directories on cleanup AddCleanFile(makefile, autogenBuildDir); @@ -763,9 +665,8 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( { std::string base = GetAutogenTargetFilesDir(target); base += "/AutogenOldSettings"; - for (std::vector<std::string>::const_iterator it = suffixes.begin(); - it != suffixes.end(); ++it) { - AddCleanFile(makefile, base + *it + ".cmake"); + for (const std::string& suffix : suffixes) { + AddCleanFile(makefile, (base + suffix).append(".cmake")); } } @@ -785,13 +686,13 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( std::string autogenComment; { std::vector<std::string> toolNames; - if (mocEnabled) { + if (digest.MocEnabled) { toolNames.push_back("MOC"); } - if (uicEnabled) { + if (digest.UicEnabled) { toolNames.push_back("UIC"); } - if (rccEnabled) { + if (digest.RccEnabled) { toolNames.push_back("RCC"); } @@ -808,14 +709,14 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( } // Add moc compilation to generated files list - if (mocEnabled) { + if (digest.MocEnabled) { const std::string mocsComp = autogenBuildDir + "/mocs_compilation.cpp"; - AddGeneratedSource(target, mocsComp, cmQtAutoGeneratorCommon::MOC); + AddGeneratedSource(target, mocsComp, cmQtAutoGen::MOC); autogenProvides.push_back(mocsComp); } // Add autogen includes directory to the origin target INCLUDE_DIRECTORIES - if (mocEnabled || uicEnabled) { + if (digest.MocEnabled || digest.UicEnabled) { std::string includeDir = autogenBuildDir + "/include"; if (multiConfig) { includeDir += "_$<CONFIG>"; @@ -823,49 +724,12 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( target->AddIncludeDirectory(includeDir, true); } - // Add user defined autogen target dependencies - { - const std::string deps = GetSafeProperty(target, "AUTOGEN_TARGET_DEPENDS"); - if (!deps.empty()) { - std::vector<std::string> extraDepends; - cmSystemTools::ExpandListArgument(deps, extraDepends); - autogenDependsSet.insert(extraDepends.begin(), extraDepends.end()); - } - } - // Add utility target dependencies to the autogen dependencies - { - const std::set<std::string>& utils = target->Target->GetUtilities(); - for (std::set<std::string>::const_iterator it = utils.begin(); - it != utils.end(); ++it) { - const std::string& targetName = *it; - if (makefile->FindTargetToUse(targetName) != nullptr) { - autogenDependsSet.insert(targetName); - } - } - } - // Add link library target dependencies to the autogen dependencies - { - const cmTarget::LinkLibraryVectorType& libVec = - target->Target->GetOriginalLinkLibraries(); - for (cmTarget::LinkLibraryVectorType::const_iterator it = libVec.begin(); - it != libVec.end(); ++it) { - const std::string& libName = it->first; - if (makefile->FindTargetToUse(libName) != nullptr) { - autogenDependsSet.insert(libName); - } - } - } - // Extract relevant source files - std::vector<std::string> generatedSources; - std::vector<std::pair<std::string, bool>> qrcSources; { const std::string qrcExt = "qrc"; std::vector<cmSourceFile*> srcFiles; target->GetConfigCommonSourceFiles(srcFiles); - for (std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin(); - fileIt != srcFiles.end(); ++fileIt) { - cmSourceFile* sf = *fileIt; + for (cmSourceFile* sf : srcFiles) { if (sf->GetPropertyAsBool("SKIP_AUTOGEN")) { continue; } @@ -873,26 +737,49 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( const std::string& fPath = sf->GetFullPath(); const std::string& ext = sf->GetExtension(); // Register generated files that will be scanned by moc or uic - if (mocEnabled || uicEnabled) { + if (digest.MocEnabled || digest.UicEnabled) { const cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat(ext.c_str()); if ((fileType == cmSystemTools::CXX_FILE_FORMAT) || (fileType == cmSystemTools::HEADER_FILE_FORMAT)) { - if (sf->GetPropertyAsBool("GENERATED")) { - if ((mocEnabled && !sf->GetPropertyAsBool("SKIP_AUTOMOC")) || - (uicEnabled && !sf->GetPropertyAsBool("SKIP_AUTOUIC"))) { - generatedSources.push_back( - cmsys::SystemTools::GetRealPath(fPath)); + const std::string absPath = cmsys::SystemTools::GetRealPath(fPath); + if ((digest.MocEnabled && !sf->GetPropertyAsBool("SKIP_AUTOMOC")) || + (digest.UicEnabled && !sf->GetPropertyAsBool("SKIP_AUTOUIC"))) { + // Register source + const bool generated = sf->GetPropertyAsBool("GENERATED"); + if (fileType == cmSystemTools::HEADER_FILE_FORMAT) { + if (generated) { + digest.HeadersGenerated.push_back(absPath); + } else { + digest.Headers.push_back(absPath); + } + } else { + if (generated) { + digest.SourcesGenerated.push_back(absPath); + } else { + digest.Sources.push_back(absPath); + } } } } } // Register rcc enabled files - if (rccEnabled && (ext == qrcExt) && + if (digest.RccEnabled && (ext == qrcExt) && !sf->GetPropertyAsBool("SKIP_AUTORCC")) { - qrcSources.push_back( - std::pair<std::string, bool>(cmsys::SystemTools::GetRealPath(fPath), - sf->GetPropertyAsBool("GENERATED"))); + // Register qrc file + { + cmQtAutoGenDigestQrc qrcDigest; + qrcDigest.QrcFile = cmsys::SystemTools::GetRealPath(fPath); + qrcDigest.Generated = sf->GetPropertyAsBool("GENERATED"); + // RCC options + { + const std::string opts = GetSafeProperty(sf, "AUTORCC_OPTIONS"); + if (!opts.empty()) { + cmSystemTools::ExpandListArgument(opts, qrcDigest.Options); + } + } + digest.Qrcs.push_back(std::move(qrcDigest)); + } } } // cmGeneratorTarget::GetConfigCommonSourceFiles computes the target's @@ -902,89 +789,176 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( target->ClearSourcesCache(); } - if (!generatedSources.empty()) { - for (std::vector<std::string>::const_iterator it = - generatedSources.begin(); - it != generatedSources.end(); ++it) { - autogenDependsSet.insert(*it); + // Process GENERATED sources and headers + if (!digest.SourcesGenerated.empty() || !digest.HeadersGenerated.empty()) { + // Check status of policy CMP0071 + bool policyAccept = false; + bool policyWarn = false; + const cmPolicies::PolicyStatus CMP0071_status = + target->Makefile->GetPolicyStatus(cmPolicies::CMP0071); + switch (CMP0071_status) { + case cmPolicies::WARN: + policyWarn = true; + CM_FALLTHROUGH; + case cmPolicies::OLD: + // Ignore GENERATED file + break; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + // Process GENERATED file + policyAccept = true; + break; + } + + if (policyAccept) { + // Accept GENERATED sources + for (const std::string& absFile : digest.HeadersGenerated) { + digest.Headers.push_back(absFile); + } + for (const std::string& absFile : digest.SourcesGenerated) { + digest.Sources.push_back(absFile); + } + } else if (policyWarn) { + std::ostringstream ost; + ost << cmPolicies::GetPolicyWarning(cmPolicies::CMP0071) << "\n"; + ost << "AUTOMOC,AUTOUIC: Ignoring GENERATED source file(s):\n"; + for (const std::string& absFile : digest.HeadersGenerated) { + ost << " " << cmQtAutoGen::Quoted(absFile) << "\n"; + } + for (const std::string& absFile : digest.SourcesGenerated) { + ost << " " << cmQtAutoGen::Quoted(absFile) << "\n"; + } + makefile->IssueMessage(cmake::AUTHOR_WARNING, ost.str()); + } + // Depend on GENERATED sources even when they are not processed by AUTOGEN + for (const std::string& absFile : digest.HeadersGenerated) { + autogenDepends.insert(absFile); + } + for (const std::string& absFile : digest.SourcesGenerated) { + autogenDepends.insert(absFile); } } + // Sort headers and sources + std::sort(digest.Headers.begin(), digest.Headers.end()); + std::sort(digest.Sources.begin(), digest.Sources.end()); - if (!qrcSources.empty()) { - const std::string qtMajorVersion = GetQtMajorVersion(target); - const std::string rccCommand = RccGetExecutable(target, qtMajorVersion); + // Process qrc files + if (!digest.Qrcs.empty()) { + const bool QtV5 = (digest.QtVersionMajor == "5"); const cmFilePathChecksum fpathCheckSum(makefile); - for (std::vector<std::pair<std::string, bool>>::const_iterator it = - qrcSources.begin(); - it != qrcSources.end(); ++it) { - const std::string& absFile = it->first; - - // Compose rcc output file name + const std::string rcc = RccGetExecutable(target, digest.QtVersionMajor); + // Target rcc options + std::vector<std::string> optionsTarget; + cmSystemTools::ExpandListArgument( + GetSafeProperty(target, "AUTORCC_OPTIONS"), optionsTarget); + + for (cmQtAutoGenDigestQrc& qrcDigest : digest.Qrcs) { + // RCC output file name { - std::string rccBuildFile = autogenBuildDir + "/"; - rccBuildFile += fpathCheckSum.getPart(absFile); - rccBuildFile += "/qrc_"; - rccBuildFile += - cmsys::SystemTools::GetFilenameWithoutLastExtension(absFile); - rccBuildFile += ".cpp"; - - // Register rcc ouput file as generated - AddGeneratedSource(target, rccBuildFile, cmQtAutoGeneratorCommon::RCC); - // Register rcc ouput file as generated by the _autogen target - autogenProvides.push_back(rccBuildFile); + std::string rccFile = autogenBuildDir + "/"; + rccFile += fpathCheckSum.getPart(qrcDigest.QrcFile); + rccFile += "/qrc_"; + rccFile += cmsys::SystemTools::GetFilenameWithoutLastExtension( + qrcDigest.QrcFile); + rccFile += ".cpp"; + + AddGeneratedSource(target, rccFile, cmQtAutoGen::RCC); + autogenProvides.push_back(rccFile); + qrcDigest.RccFile = std::move(rccFile); } - - if (it->second) { - // Add generated qrc file to the dependencies - autogenDependsSet.insert(absFile); + // RCC options + { + std::vector<std::string> opts = optionsTarget; + if (!qrcDigest.Options.empty()) { + RccMergeOptions(opts, qrcDigest.Options, QtV5); + } + qrcDigest.Options = std::move(opts); + } + // GENERATED or not + if (qrcDigest.Generated) { + // Add GENERATED qrc file to the dependencies + autogenDepends.insert(qrcDigest.QrcFile); } else { - // Run cmake again when .qrc file changes - makefile->AddCMakeDependFile(absFile); - // Add the qrc input files to the dependencies + // Add the resource files to the dependencies { std::string error; - std::vector<std::string> extraDepends; - if (cmQtAutoGeneratorCommon::RccListInputs( - qtMajorVersion, rccCommand, absFile, extraDepends, &error)) { - autogenDependsSet.insert(extraDepends.begin(), extraDepends.end()); + if (cmQtAutoGen::RccListInputs(digest.QtVersionMajor, rcc, + qrcDigest.QrcFile, + qrcDigest.Resources, &error)) { + autogenDepends.insert(qrcDigest.Resources.begin(), + qrcDigest.Resources.end()); } else { cmSystemTools::Error(error.c_str()); } } + // Run cmake again when .qrc file changes + makefile->AddCMakeDependFile(qrcDigest.QrcFile); + } + } + } + + // Add user defined autogen target dependencies + { + const std::string deps = GetSafeProperty(target, "AUTOGEN_TARGET_DEPENDS"); + if (!deps.empty()) { + std::vector<std::string> extraDeps; + cmSystemTools::ExpandListArgument(deps, extraDeps); + autogenDepends.insert(extraDeps.begin(), extraDeps.end()); + } + } + // Add utility target dependencies to the autogen target dependencies + { + const std::set<std::string>& utils = target->Target->GetUtilities(); + for (const std::string& targetName : utils) { + if (makefile->FindTargetToUse(targetName) != nullptr) { + autogenDepends.insert(targetName); + } + } + } + // Add link library target dependencies to the autogen target dependencies + { + const auto& libVec = target->Target->GetOriginalLinkLibraries(); + for (const auto& item : libVec) { + if (makefile->FindTargetToUse(item.first) != nullptr) { + autogenDepends.insert(item.first); } } } // Convert std::set to std::vector - const std::vector<std::string> autogenDepends(autogenDependsSet.begin(), - autogenDependsSet.end()); - // Disable PRE_BUILD on demand + const std::vector<std::string> depends(autogenDepends.begin(), + autogenDepends.end()); + autogenDepends.clear(); + + // Use PRE_BUILD on demand + bool usePRE_BUILD = false; + if (globalGen->GetName().find("Visual Studio") != std::string::npos) { + // Under VS use a PRE_BUILD event instead of a separate target to + // reduce the number of targets loaded into the IDE. + // This also works around a VS 11 bug that may skip updating the target: + // https://connect.microsoft.com/VisualStudio/feedback/details/769495 + usePRE_BUILD = true; + } + // Disable PRE_BUILD in some cases if (usePRE_BUILD) { - if (!generatedSources.empty() || !qrcSources.empty()) { - // - Cannot use PRE_BUILD with generated files - // - Cannot use PRE_BUILD because the resource files themselves - // may not be sources within the target so VS may not know the - // target needs to re-build at all. - usePRE_BUILD = false; - } - if (usePRE_BUILD) { - // If the autogen target depends on an other target don't use PRE_BUILD - for (std::vector<std::string>::const_iterator it = - autogenDepends.begin(); - it != autogenDepends.end(); ++it) { - if (makefile->FindTargetToUse(*it) != nullptr) { - usePRE_BUILD = false; - break; - } + // - Cannot use PRE_BUILD with GENERATED qrc files because the + // resource files themselves may not be sources within the target + // so VS may not know the target needs to re-build at all. + for (cmQtAutoGenDigestQrc& qrcDigest : digest.Qrcs) { + if (qrcDigest.Generated) { + usePRE_BUILD = false; + break; } } } + // Create the autogen target/command if (usePRE_BUILD) { // Add the pre-build command directly to bypass the OBJECT_LIBRARY // rejection in cmMakefile::AddCustomCommandToTarget because we know // PRE_BUILD will work for an OBJECT_LIBRARY in this specific case. - std::vector<std::string> no_output; - cmCustomCommand cc(makefile, no_output, autogenProvides, autogenDepends, + const std::vector<std::string> no_output; + cmCustomCommand cc(makefile, no_output, autogenProvides, depends, commandLines, autogenComment.c_str(), workingDirectory.c_str()); cc.SetEscapeOldStyle(false); @@ -993,7 +967,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( } else { cmTarget* autogenTarget = makefile->AddUtilityCommand( autogenTargetName, true, workingDirectory.c_str(), - /*byproducts=*/autogenProvides, autogenDepends, commandLines, false, + /*byproducts=*/autogenProvides, depends, commandLines, false, autogenComment.c_str()); localGen->AddGeneratorTarget( @@ -1009,7 +983,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( } // Inherit FOLDER property from target (#13688) if (autogenFolder == nullptr) { - autogenFolder = target->Target->GetProperty("FOLDER"); + autogenFolder = SafeString(target->Target->GetProperty("FOLDER")); } if ((autogenFolder != nullptr) && (*autogenFolder != '\0')) { autogenTarget->SetProperty("FOLDER", autogenFolder); @@ -1022,8 +996,9 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( } void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget( - cmGeneratorTarget const* target) + const cmQtAutoGenDigest& digest) { + cmGeneratorTarget const* target = digest.Target; cmMakefile* makefile = target->Target->GetMakefile(); // forget the variables added here afterwards again: @@ -1037,43 +1012,34 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget( // Configuration suffixes std::map<std::string, std::string> configSuffix; if (AutogenMultiConfig(target->GetGlobalGenerator())) { - for (std::vector<std::string>::const_iterator it = configs.begin(); - it != configs.end(); ++it) { - configSuffix[*it] = "_" + *it; + for (const std::string& cfg : configs) { + configSuffix[cfg] = "_" + cfg; } } // Configurations settings buffers - AutogenSetup setup; + cmQtAutoGenSetup setup; // Basic setup + AddDefinitionEscaped(makefile, "_build_dir", + GetAutogenTargetBuildDir(target)); + AddDefinitionEscaped(makefile, "_qt_version_major", digest.QtVersionMajor); + AddDefinitionEscaped(makefile, "_qt_version_minor", digest.QtVersionMinor); + AddDefinitionEscaped(makefile, "_sources", digest.Sources); + AddDefinitionEscaped(makefile, "_headers", digest.Headers); { - const bool mocEnabled = target->GetPropertyAsBool("AUTOMOC"); - const bool uicEnabled = target->GetPropertyAsBool("AUTOUIC"); - const bool rccEnabled = target->GetPropertyAsBool("AUTORCC"); - const std::string qtMajorVersion = GetQtMajorVersion(target); - { - std::vector<cmSourceFile*> srcFiles; - target->GetConfigCommonSourceFiles(srcFiles); - if (mocEnabled || uicEnabled) { - SetupAcquireScanFiles(target, mocEnabled, uicEnabled, srcFiles, setup); - if (mocEnabled) { - SetupAutoTargetMoc(target, qtMajorVersion, config, configs, setup); - } - if (uicEnabled) { - SetupAutoTargetUic(target, qtMajorVersion, config, configs, setup); - } + if (digest.MocEnabled || digest.UicEnabled) { + SetupAcquireSkipFiles(digest, setup); + if (digest.MocEnabled) { + SetupAutoTargetMoc(digest, config, configs, setup); } - if (rccEnabled) { - SetupAutoTargetRcc(target, qtMajorVersion, srcFiles); + if (digest.UicEnabled) { + SetupAutoTargetUic(digest, config, configs, setup); } } - - AddDefinitionEscaped(makefile, "_build_dir", - GetAutogenTargetBuildDir(target)); - AddDefinitionEscaped(makefile, "_qt_version_major", qtMajorVersion); - AddDefinitionEscaped(makefile, "_sources", setup.sources); - AddDefinitionEscaped(makefile, "_headers", setup.headers); + if (digest.RccEnabled) { + SetupAutoTargetRcc(digest); + } } // Generate info file @@ -1086,8 +1052,8 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget( } // Append custom definitions to info file on demand - if (!configSuffix.empty() || !setup.configMocDefines.empty() || - !setup.configMocIncludes.empty() || !setup.configUicOptions.empty()) { + if (!configSuffix.empty() || !setup.ConfigMocDefines.empty() || + !setup.ConfigMocIncludes.empty() || !setup.ConfigUicOptions.empty()) { // Ensure we have write permission in case .in was read-only. mode_t perm = 0; @@ -1105,38 +1071,26 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget( cmsys::ofstream ofs(infoFile.c_str(), std::ios::app); if (ofs) { ofs << "# Configuration specific options\n"; - for (std::map<std::string, std::string>::iterator - it = configSuffix.begin(), - end = configSuffix.end(); - it != end; ++it) { - ofs << "set(AM_CONFIG_SUFFIX_" << it->first << " " - << cmOutputConverter::EscapeForCMake(it->second) << ")\n"; + for (const auto& item : configSuffix) { + ofs << "set(AM_CONFIG_SUFFIX_" << item.first << " " + << cmOutputConverter::EscapeForCMake(item.second) << ")\n"; } - for (std::map<std::string, std::string>::iterator - it = setup.configMocDefines.begin(), - end = setup.configMocDefines.end(); - it != end; ++it) { - ofs << "set(AM_MOC_DEFINITIONS_" << it->first << " " - << cmOutputConverter::EscapeForCMake(it->second) << ")\n"; + for (const auto& item : setup.ConfigMocDefines) { + ofs << "set(AM_MOC_DEFINITIONS_" << item.first << " " + << cmOutputConverter::EscapeForCMake(item.second) << ")\n"; } - for (std::map<std::string, std::string>::iterator - it = setup.configMocIncludes.begin(), - end = setup.configMocIncludes.end(); - it != end; ++it) { - ofs << "set(AM_MOC_INCLUDES_" << it->first << " " - << cmOutputConverter::EscapeForCMake(it->second) << ")\n"; + for (const auto& item : setup.ConfigMocIncludes) { + ofs << "set(AM_MOC_INCLUDES_" << item.first << " " + << cmOutputConverter::EscapeForCMake(item.second) << ")\n"; } - for (std::map<std::string, std::string>::iterator - it = setup.configUicOptions.begin(), - end = setup.configUicOptions.end(); - it != end; ++it) { - ofs << "set(AM_UIC_TARGET_OPTIONS_" << it->first << " " - << cmOutputConverter::EscapeForCMake(it->second) << ")\n"; + for (const auto& item : setup.ConfigUicOptions) { + ofs << "set(AM_UIC_TARGET_OPTIONS_" << item.first << " " + << cmOutputConverter::EscapeForCMake(item.second) << ")\n"; } } else { // File open error std::string error = "Internal CMake error when trying to open file: "; - error += cmQtAutoGeneratorCommon::Quoted(infoFile); + error += cmQtAutoGen::Quoted(infoFile); error += " for writing."; cmSystemTools::Error(error.c_str()); } diff --git a/Source/cmQtAutoGeneratorInitializer.h b/Source/cmQtAutoGeneratorInitializer.h index 48ae70e..1264ca5 100644 --- a/Source/cmQtAutoGeneratorInitializer.h +++ b/Source/cmQtAutoGeneratorInitializer.h @@ -4,16 +4,21 @@ #define cmQtAutoGeneratorInitializer_h #include "cmConfigure.h" // IWYU pragma: keep +#include "cmQtAutoGenDigest.h" + +#include <string> class cmGeneratorTarget; -class cmLocalGenerator; class cmQtAutoGeneratorInitializer { public: - static void InitializeAutogenTarget(cmLocalGenerator* localGen, - cmGeneratorTarget* target); - static void SetupAutoGenerateTarget(cmGeneratorTarget const* target); + static std::string GetQtMajorVersion(cmGeneratorTarget const* target); + static std::string GetQtMinorVersion(cmGeneratorTarget const* target, + const std::string& qtVersionMajor); + + static void InitializeAutogenTarget(cmQtAutoGenDigest& digest); + static void SetupAutoGenerateTarget(cmQtAutoGenDigest const& digest); }; #endif diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index d7f1ea7..e9929f4 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -1,11 +1,12 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmQtAutoGen.h" #include "cmQtAutoGenerators.h" -#include "cmQtAutoGeneratorCommon.h" #include "cmsys/FStream.hxx" #include "cmsys/Terminal.h" #include <algorithm> +#include <array> #include <assert.h> #include <list> #include <sstream> @@ -39,23 +40,22 @@ static const char* SettingsKeyRcc = "AM_RCC_SETTINGS_HASH"; inline static std::string Quoted(const std::string& text) { - return cmQtAutoGeneratorCommon::Quoted(text); + return cmQtAutoGen::Quoted(text); } static std::string QuotedCommand(const std::vector<std::string>& command) { std::string res; - for (std::vector<std::string>::const_iterator cit = command.begin(); - cit != command.end(); ++cit) { + for (const std::string& item : command) { if (!res.empty()) { res.push_back(' '); } - const std::string cesc = Quoted(*cit); - if (cit->empty() || (cesc.size() > (cit->size() + 2)) || + const std::string cesc = Quoted(item); + if (item.empty() || (cesc.size() > (item.size() + 2)) || (cesc.find(' ') != std::string::npos)) { res += cesc; } else { - res += *cit; + res += item; } } return res; @@ -136,9 +136,8 @@ static bool FileNameIsUnique(const std::string& filePath, { size_t count(0); const std::string fileName = cmsys::SystemTools::GetFilenameName(filePath); - for (std::map<std::string, std::string>::const_iterator si = fileMap.begin(); - si != fileMap.end(); ++si) { - if (cmsys::SystemTools::GetFilenameName(si->first) == fileName) { + for (const auto& item : fileMap) { + if (cmsys::SystemTools::GetFilenameName(item.first) == fileName) { ++count; if (count > 1) { return false; @@ -191,31 +190,13 @@ static std::string JoinOptionsMap( const std::map<std::string, std::string>& opts) { std::string result; - for (std::map<std::string, std::string>::const_iterator it = opts.begin(); - it != opts.end(); ++it) { - if (it != opts.begin()) { - result += cmQtAutoGeneratorCommon::listSep; + for (const auto& item : opts) { + if (!result.empty()) { + result += cmQtAutoGen::listSep; } - result += it->first; + result += item.first; result += "==="; - result += it->second; - } - return result; -} - -static std::string JoinExts(const std::vector<std::string>& lst) -{ - std::string result; - if (!lst.empty()) { - const std::string separator = ","; - for (std::vector<std::string>::const_iterator it = lst.begin(); - it != lst.end(); ++it) { - if (it != lst.begin()) { - result += separator; - } - result += '.'; - result += *it; - } + result += item.second; } return result; } @@ -425,11 +406,9 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( { std::vector<std::string> MocMacroNames; InfoGet(makefile, "AM_MOC_MACRO_NAMES", MocMacroNames); - for (std::vector<std::string>::const_iterator dit = - MocMacroNames.begin(); - dit != MocMacroNames.end(); ++dit) { - this->MocMacroFilters.push_back( - MocMacroFilter(*dit, "[^a-zA-Z0-9_]" + *dit + "[^a-zA-Z0-9_]")); + for (const std::string& item : MocMacroNames) { + this->MocMacroFilters.emplace_back( + item, ("[^a-zA-Z0-9_]" + item).append("[^a-zA-Z0-9_]")); } } { @@ -443,9 +422,10 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( } // Insert user defined dependency filters if ((mocDependFilters.size() % 2) == 0) { - for (std::vector<std::string>::const_iterator dit = - mocDependFilters.begin(); - dit != mocDependFilters.end(); dit += 2) { + for (std::vector<std::string>::const_iterator + dit = mocDependFilters.begin(), + ditEnd = mocDependFilters.end(); + dit != ditEnd; dit += 2) { if (!this->MocDependFilterPush(*dit, *(dit + 1))) { return false; } @@ -478,8 +458,7 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( fileIt = uicFilesVec.begin(), optionIt = uicOptionsVec.begin(); fileIt != uicFilesVec.end(); ++fileIt, ++optionIt) { - cmSystemTools::ReplaceString(*optionIt, - cmQtAutoGeneratorCommon::listSep, ";"); + cmSystemTools::ReplaceString(*optionIt, cmQtAutoGen::listSep, ";"); this->UicOptions[*fileIt] = *optionIt; } } else { @@ -506,8 +485,7 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( optionIt = rccOptionsVec.begin(); fileIt != rccFilesVec.end(); ++fileIt, ++optionIt) { // Replace item separator - cmSystemTools::ReplaceString(*optionIt, - cmQtAutoGeneratorCommon::listSep, ";"); + cmSystemTools::ReplaceString(*optionIt, cmQtAutoGen::listSep, ";"); this->RccOptions[*fileIt] = *optionIt; } } else { @@ -529,8 +507,7 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( // Remove braces *inputIt = inputIt->substr(1, inputIt->size() - 2); // Replace item separator - cmSystemTools::ReplaceString(*inputIt, - cmQtAutoGeneratorCommon::listSep, ";"); + cmSystemTools::ReplaceString(*inputIt, cmQtAutoGen::listSep, ";"); std::vector<std::string> rccInputFiles; cmSystemTools::ExpandListArgument(*inputIt, rccInputFiles); this->RccInputs[*fileIt] = rccInputFiles; @@ -629,7 +606,7 @@ bool cmQtAutoGenerators::SettingsFileWrite() SettingAppend(settings, SettingsKeyUic, this->SettingsStringUic); SettingAppend(settings, SettingsKeyRcc, this->SettingsStringRcc); // Write settings file - if (!this->FileWrite("AutoGen", this->SettingsFile, settings)) { + if (!this->FileWrite(cmQtAutoGen::GEN, this->SettingsFile, settings)) { this->LogError("AutoGen: Error: Could not write old settings file " + Quoted(this->SettingsFile)); // Remove old settings file to trigger a full rebuild on the next run @@ -679,14 +656,14 @@ void cmQtAutoGenerators::Init(cmMakefile* makefile) this->MocIncludePaths.reserve(includes.size()); // Append project directories only { - const char* movePaths[2] = { this->ProjectBinaryDir.c_str(), - this->ProjectSourceDir.c_str() }; - for (const char* const* mpit = cmArrayBegin(movePaths); - mpit != cmArrayEnd(movePaths); ++mpit) { + const std::array<const std::string*, 2> movePaths = { + { &this->ProjectBinaryDir, &this->ProjectSourceDir } + }; + for (const std::string* ppath : movePaths) { std::list<std::string>::iterator it = includes.begin(); while (it != includes.end()) { const std::string& path = *it; - if (cmsys::SystemTools::StringStartsWith(path, *mpit)) { + if (cmSystemTools::StringStartsWith(path, ppath->c_str())) { this->MocIncludePaths.push_back(path); it = includes.erase(it); } else { @@ -702,10 +679,7 @@ void cmQtAutoGenerators::Init(cmMakefile* makefile) // Compose moc includes list { std::set<std::string> frameworkPaths; - for (std::vector<std::string>::const_iterator it = - this->MocIncludePaths.begin(); - it != this->MocIncludePaths.end(); ++it) { - const std::string& path = *it; + for (const std::string& path : this->MocIncludePaths) { this->MocIncludes.push_back("-I" + path); // Extract framework path if (cmHasLiteralSuffix(path, ".framework/Headers")) { @@ -718,10 +692,9 @@ void cmQtAutoGenerators::Init(cmMakefile* makefile) } } // Append framework includes - for (std::set<std::string>::const_iterator it = frameworkPaths.begin(); - it != frameworkPaths.end(); ++it) { + for (const std::string& path : frameworkPaths) { this->MocIncludes.push_back("-F"); - this->MocIncludes.push_back(*it); + this->MocIncludes.push_back(path); } } } @@ -757,28 +730,23 @@ bool cmQtAutoGenerators::RunAutogen() std::set<std::string> uicHeaderFiles; // Parse sources - for (std::vector<std::string>::const_iterator it = this->Sources.begin(); - it != this->Sources.end(); ++it) { - const std::string& absFilename = cmsys::SystemTools::GetRealPath(*it); + for (const std::string& src : this->Sources) { // Parse source file for MOC/UIC - if (!this->ParseSourceFile(absFilename, mocsIncluded, mocDepends, - uisIncluded, this->MocRelaxedMode)) { + if (!this->ParseSourceFile(src, mocsIncluded, mocDepends, uisIncluded, + this->MocRelaxedMode)) { return false; } // Find additional headers - this->SearchHeadersForSourceFile(absFilename, mocHeaderFiles, - uicHeaderFiles); + this->SearchHeadersForSourceFile(src, mocHeaderFiles, uicHeaderFiles); } // Parse headers - for (std::vector<std::string>::const_iterator it = this->Headers.begin(); - it != this->Headers.end(); ++it) { - const std::string& headerName = cmsys::SystemTools::GetRealPath(*it); - if (!this->MocSkip(headerName)) { - mocHeaderFiles.insert(headerName); + for (const std::string& hdr : this->Headers) { + if (!this->MocSkip(hdr)) { + mocHeaderFiles.insert(hdr); } - if (!this->UicSkip(headerName)) { - uicHeaderFiles.insert(headerName); + if (!this->UicSkip(hdr)) { + uicHeaderFiles.insert(hdr); } } if (!this->ParseHeaders(mocHeaderFiles, uicHeaderFiles, mocsIncluded, @@ -807,10 +775,7 @@ bool cmQtAutoGenerators::RunAutogen() bool cmQtAutoGenerators::MocRequired(const std::string& contentText, std::string* macroName) { - for (std::vector<MocMacroFilter>::iterator fit = - this->MocMacroFilters.begin(); - fit != this->MocMacroFilters.end(); ++fit) { - MocMacroFilter& filter = *fit; + for (MocMacroFilter& filter : this->MocMacroFilters) { // Run a simple find string operation before the expensive // regular expression check if (contentText.find(filter.first) != std::string::npos) { @@ -830,10 +795,7 @@ void cmQtAutoGenerators::MocFindDepends( const std::string& absFilename, const std::string& contentText, std::map<std::string, std::set<std::string>>& mocDepends) { - for (std::vector<MocDependFilter>::iterator fit = - this->MocDependFilters.begin(); - fit != this->MocDependFilters.end(); ++fit) { - MocDependFilter& filter = *fit; + for (MocDependFilter& filter : this->MocDependFilters) { // Run a simple find string operation before the expensive // regular expression check if (contentText.find(filter.key) != std::string::npos) { @@ -1008,9 +970,8 @@ bool cmQtAutoGenerators::MocParseSourceContent( ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n" << "The file includes the moc file " << Quoted(incString) << ", but could not find header " - << Quoted(incRealBasename + "{" + - JoinExts(this->HeaderExtensions) + "}"); - ; + << Quoted(incRealBasename + ".{" + + cmJoin(this->HeaderExtensions, ",") + "}"); this->LogError(ost.str()); return false; } @@ -1166,19 +1127,19 @@ void cmQtAutoGenerators::SearchHeadersForSourceFile( const std::string& absFilename, std::set<std::string>& mocHeaderFiles, std::set<std::string>& uicHeaderFiles) const { - std::string basepaths[2]; + std::array<std::string, 2> basepaths; { std::string bpath = SubDirPrefix(absFilename); bpath += cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename); // search for default header files and private header files basepaths[0] = bpath; - basepaths[1] = bpath + "_p"; + basepaths[1] = bpath; + basepaths[1] += "_p"; } - for (const std::string* bpit = cmArrayBegin(basepaths); - bpit != cmArrayEnd(basepaths); ++bpit) { + for (const std::string& bPath : basepaths) { std::string headerName; - if (this->FindHeader(headerName, *bpit)) { + if (this->FindHeader(headerName, bPath)) { // Moc headers if (!this->MocSkip(absFilename) && !this->MocSkip(headerName)) { mocHeaderFiles.insert(headerName); @@ -1205,9 +1166,7 @@ bool cmQtAutoGenerators::ParseHeaders( headerFiles.insert(mocHeaderFiles.begin(), mocHeaderFiles.end()); headerFiles.insert(uicHeaderFiles.begin(), uicHeaderFiles.end()); - for (std::set<std::string>::const_iterator hIt = headerFiles.begin(); - hIt != headerFiles.end(); ++hIt) { - const std::string& headerName = *hIt; + for (const std::string& headerName : headerFiles) { std::string contentText; if (ReadAll(contentText, headerName)) { // Parse header content for MOC @@ -1276,10 +1235,8 @@ bool cmQtAutoGenerators::MocGenerateAll( cmd.insert(cmd.end(), this->MocIncludes.begin(), this->MocIncludes.end()); // Add definitions - for (std::vector<std::string>::const_iterator it = - this->MocDefinitions.begin(); - it != this->MocDefinitions.end(); ++it) { - cmd.push_back("-D" + (*it)); + for (const std::string& def : this->MocDefinitions) { + cmd.push_back("-D" + def); } // Add options cmd.insert(cmd.end(), this->MocOptions.begin(), @@ -1298,7 +1255,8 @@ bool cmQtAutoGenerators::MocGenerateAll( } // (Re)write predefs file only on demand if (this->FileDiffers(this->MocPredefsFileAbs, output)) { - if (this->FileWrite("AutoMoc", this->MocPredefsFileAbs, output)) { + if (this->FileWrite(cmQtAutoGen::MOC, this->MocPredefsFileAbs, + output)) { this->MocPredefsChanged = true; } else { return false; @@ -1356,7 +1314,8 @@ bool cmQtAutoGenerators::MocGenerateAll( if (this->Verbose) { this->LogBold("Generating MOC compilation " + this->MocCompFileRel); } - if (!this->FileWrite("AutoMoc", this->MocCompFileAbs, automocSource)) { + if (!this->FileWrite(cmQtAutoGen::MOC, this->MocCompFileAbs, + automocSource)) { return false; } } else if (mocCompFileGenerated) { @@ -1411,7 +1370,7 @@ bool cmQtAutoGenerators::MocGenerateFile( } // Make sure the parent directory exists - if (this->MakeParentDirectory("AutoMoc", mocFileAbs)) { + if (this->MakeParentDirectory(cmQtAutoGen::MOC, mocFileAbs)) { // Compose moc command std::vector<std::string> cmd; cmd.push_back(this->MocExecutable); @@ -1419,10 +1378,8 @@ bool cmQtAutoGenerators::MocGenerateFile( cmd.insert(cmd.end(), this->MocIncludes.begin(), this->MocIncludes.end()); // Add definitions - for (std::vector<std::string>::const_iterator it = - this->MocDefinitions.begin(); - it != this->MocDefinitions.end(); ++it) { - cmd.push_back("-D" + (*it)); + for (const std::string& def : this->MocDefinitions) { + cmd.push_back("-D" + def); } // Add options cmd.insert(cmd.end(), this->MocOptions.begin(), this->MocOptions.end()); @@ -1470,7 +1427,11 @@ bool cmQtAutoGenerators::UicFindIncludedFile(std::string& absFile, std::vector<std::string> testFiles; // Collect search paths list { - const std::string searchFileFull = searchPath + searchFile; + std::string searchFileFull; + if (!searchPath.empty()) { + searchFileFull = searchPath; + searchFileFull += searchFile; + } // Vicinity of the source { const std::string sourcePath = SubDirPrefix(sourceFile); @@ -1481,25 +1442,19 @@ bool cmQtAutoGenerators::UicFindIncludedFile(std::string& absFile, } // AUTOUIC search paths if (!this->UicSearchPaths.empty()) { - for (std::vector<std::string>::const_iterator iit = - this->UicSearchPaths.begin(); - iit != this->UicSearchPaths.end(); ++iit) { - testFiles.push_back(*iit + "/" + searchFile); + for (const std::string& sPath : this->UicSearchPaths) { + testFiles.push_back((sPath + "/").append(searchFile)); } if (!searchPath.empty()) { - for (std::vector<std::string>::const_iterator iit = - this->UicSearchPaths.begin(); - iit != this->UicSearchPaths.end(); ++iit) { - testFiles.push_back(*iit + "/" + searchFileFull); + for (const std::string& sPath : this->UicSearchPaths) { + testFiles.push_back((sPath + "/").append(searchFileFull)); } } } } // Search for the .ui file! - for (std::vector<std::string>::const_iterator iit = testFiles.begin(); - iit != testFiles.end(); ++iit) { - const std::string& testFile = *iit; + for (const std::string& testFile : testFiles) { if (cmsys::SystemTools::FileExists(testFile.c_str())) { absFile = cmsys::SystemTools::GetRealPath(testFile); success = true; @@ -1512,9 +1467,8 @@ bool cmQtAutoGenerators::UicFindIncludedFile(std::string& absFile, std::ostringstream ost; ost << "AutoUic: Error: " << Quoted(sourceFile) << "\n"; ost << "Could not find " << Quoted(searchFile) << " in\n"; - for (std::vector<std::string>::const_iterator iit = testFiles.begin(); - iit != testFiles.end(); ++iit) { - ost << " " << Quoted(*iit) << "\n"; + for (const std::string& testFile : testFiles) { + ost << " " << Quoted(testFile) << "\n"; } this->LogError(ost.str()); } @@ -1542,16 +1496,18 @@ bool cmQtAutoGenerators::UicGenerateAll( const std::vector<std::string>& sourceIncs(sit->second); // insert new source/destination map std::map<std::string, std::string>& uiGenMap = sourceGenMap[source]; - for (std::vector<std::string>::const_iterator uit = sourceIncs.begin(); - uit != sourceIncs.end(); ++uit) { + for (const std::string& inc : sourceIncs) { // Remove ui_ from the begin filename by substr() - const std::string uiBasePath = SubDirPrefix(*uit); + const std::string uiBasePath = SubDirPrefix(inc); const std::string uiBaseName = - cmsys::SystemTools::GetFilenameWithoutLastExtension(*uit).substr(3); + cmsys::SystemTools::GetFilenameWithoutLastExtension(inc).substr(3); const std::string uiFileName = uiBaseName + ".ui"; std::string uiInputFile; if (UicFindIncludedFile(uiInputFile, source, uiBasePath, uiFileName)) { - std::string uiOutputFile = uiBasePath + "ui_" + uiBaseName + ".h"; + std::string uiOutputFile = uiBasePath; + uiOutputFile += "ui_"; + uiOutputFile += uiBaseName; + uiOutputFile += ".h"; cmSystemTools::ReplaceString(uiOutputFile, "..", "__"); uiGenMap[uiInputFile] = uiOutputFile; testMap[uiInputFile] = uiOutputFile; @@ -1575,14 +1531,9 @@ bool cmQtAutoGenerators::UicGenerateAll( } // generate ui files - for (std::map<std::string, - std::map<std::string, std::string>>::const_iterator it = - sourceGenMap.begin(); - it != sourceGenMap.end(); ++it) { - for (std::map<std::string, std::string>::const_iterator sit = - it->second.begin(); - sit != it->second.end(); ++sit) { - if (!this->UicGenerateFile(it->first, sit->first, sit->second)) { + for (const auto& srcItem : sourceGenMap) { + for (const auto& item : srcItem.second) { + if (!this->UicGenerateFile(srcItem.first, item.first, item.second)) { if (this->UicRunFailed) { return false; } @@ -1618,7 +1569,7 @@ bool cmQtAutoGenerators::UicGenerateFile(const std::string& realName, } // Make sure the parent directory exists - if (this->MakeParentDirectory("AutoUic", uicFileAbs)) { + if (this->MakeParentDirectory(cmQtAutoGen::UIC, uicFileAbs)) { // Compose uic command std::vector<std::string> cmd; cmd.push_back(this->UicExecutable); @@ -1674,14 +1625,8 @@ bool cmQtAutoGenerators::RccGenerateAll() { const std::string qrcPrefix = "qrc_"; const std::string qrcSuffix = this->ConfigSuffix + ".cpp"; - for (std::vector<std::string>::const_iterator si = - this->RccSources.begin(); - si != this->RccSources.end(); ++si) { - const std::string ext = - cmsys::SystemTools::GetFilenameLastExtension(*si); - if (ext == ".qrc") { - qrcGenMap[*si] = this->ChecksumedPath(*si, qrcPrefix, qrcSuffix); - } + for (const std::string& src : this->RccSources) { + qrcGenMap[src] = this->ChecksumedPath(src, qrcPrefix, qrcSuffix); } } @@ -1699,11 +1644,9 @@ bool cmQtAutoGenerators::RccGenerateAll() } // generate qrc files - for (std::map<std::string, std::string>::const_iterator si = - qrcGenMap.begin(); - si != qrcGenMap.end(); ++si) { - bool unique = FileNameIsUnique(si->first, qrcGenMap); - if (!this->RccGenerateFile(si->first, si->second, unique)) { + for (const auto& item : qrcGenMap) { + bool unique = FileNameIsUnique(item.first, qrcGenMap); + if (!this->RccGenerateFile(item.first, item.second, unique)) { if (this->RccRunFailed) { return false; } @@ -1735,9 +1678,9 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, if (files->empty()) { // Read input file list from qrc file std::string error; - if (cmQtAutoGeneratorCommon::RccListInputs( - this->QtMajorVersion, this->RccExecutable, rccInputFile, - readFiles, &error)) { + if (cmQtAutoGen::RccListInputs(this->QtMajorVersion, + this->RccExecutable, rccInputFile, + readFiles, &error)) { files = &readFiles; } else { files = nullptr; @@ -1747,9 +1690,8 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, } // Test if any input file is newer than the build file if (files != nullptr) { - for (std::vector<std::string>::const_iterator it = files->begin(); - it != files->end(); ++it) { - if (FileAbsentOrOlder(rccBuildFile, *it)) { + for (const std::string& file : *files) { + if (FileAbsentOrOlder(rccBuildFile, file)) { generateRcc = true; break; } @@ -1765,7 +1707,7 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, } // Make sure the parent directory exists - if (this->MakeParentDirectory("AutoRcc", rccBuildFile)) { + if (this->MakeParentDirectory(cmQtAutoGen::RCC, rccBuildFile)) { // Compose symbol name std::string symbolName = cmsys::SystemTools::GetFilenameWithoutLastExtension(rccInputFile); @@ -1836,7 +1778,7 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, if (this->Verbose) { this->LogBold("Generating RCC wrapper " + wrapperFileRel); } - if (!this->FileWrite("AutoRcc", wrapperFileAbs, content)) { + if (!this->FileWrite(cmQtAutoGen::RCC, wrapperFileAbs, content)) { // Error rccGenerated = false; this->RccRunFailed = true; @@ -1857,8 +1799,6 @@ void cmQtAutoGenerators::LogErrorNameCollision( const std::string& message, const std::multimap<std::string, std::string>& collisions) const { - typedef std::multimap<std::string, std::string>::const_iterator Iter; - std::ostringstream ost; // Add message if (!message.empty()) { @@ -1868,8 +1808,8 @@ void cmQtAutoGenerators::LogErrorNameCollision( } } // Append collision list - for (Iter it = collisions.begin(); it != collisions.end(); ++it) { - ost << it->first << " : " << it->second << '\n'; + for (const auto& item : collisions) { + ost << " " << item.first << " : " << item.second << '\n'; } this->LogError(ost.str()); } @@ -1968,15 +1908,15 @@ std::string cmQtAutoGenerators::ChecksumedPath( * @brief Generates the parent directory of the given file on demand * @return True on success */ -bool cmQtAutoGenerators::MakeParentDirectory(const char* logPrefix, - const std::string& filename) const +bool cmQtAutoGenerators::MakeParentDirectory( + cmQtAutoGen::GeneratorType genType, const std::string& filename) const { bool success = true; const std::string dirName = cmSystemTools::GetFilenamePath(filename); if (!dirName.empty()) { success = cmsys::SystemTools::MakeDirectory(dirName); if (!success) { - std::string error = logPrefix; + std::string error = cmQtAutoGen::GeneratorName(genType); error += ": Error: Parent directory creation failed for "; error += Quoted(filename); this->LogError(error); @@ -1998,26 +1938,28 @@ bool cmQtAutoGenerators::FileDiffers(const std::string& filename, return differs; } -bool cmQtAutoGenerators::FileWrite(const char* logPrefix, +bool cmQtAutoGenerators::FileWrite(cmQtAutoGen::GeneratorType genType, const std::string& filename, const std::string& content) { std::string error; // Make sure the parent directory exists - if (this->MakeParentDirectory(logPrefix, filename)) { + if (this->MakeParentDirectory(genType, filename)) { cmsys::ofstream outfile; outfile.open(filename.c_str(), std::ios::trunc); if (outfile) { outfile << content; // Check for write errors if (!outfile.good()) { - error = logPrefix; - error += ": Error writing "; + error = cmQtAutoGen::GeneratorName(genType); + error += ": Error: File writing failed\n"; + error += " "; error += Quoted(filename); } } else { - error = logPrefix; - error = ": Error opening "; + error = cmQtAutoGen::GeneratorName(genType); + error += ": Error: Opening file for writing failed\n"; + error += " "; error += Quoted(filename); } } @@ -2055,12 +1997,10 @@ bool cmQtAutoGenerators::RunCommand(const std::vector<std::string>& command, bool cmQtAutoGenerators::FindHeader(std::string& header, const std::string& testBasePath) const { - for (std::vector<std::string>::const_iterator ext = - this->HeaderExtensions.begin(); - ext != this->HeaderExtensions.end(); ++ext) { + for (const std::string& ext : this->HeaderExtensions) { std::string testFilePath(testBasePath); - testFilePath += '.'; - testFilePath += (*ext); + testFilePath.push_back('.'); + testFilePath += ext; if (cmsys::SystemTools::FileExists(testFilePath.c_str())) { header = testFilePath; return true; @@ -2076,10 +2016,10 @@ std::string cmQtAutoGenerators::MocFindHeader( // Search in vicinity of the source if (!this->FindHeader(header, sourcePath + includeBase)) { // Search in include directories - for (std::vector<std::string>::const_iterator iit = - this->MocIncludePaths.begin(); - iit != this->MocIncludePaths.end(); ++iit) { - const std::string fullPath = ((*iit) + '/' + includeBase); + for (const std::string& path : this->MocIncludePaths) { + std::string fullPath = path; + fullPath.push_back('/'); + fullPath += includeBase; if (FindHeader(header, fullPath)) { break; } @@ -2108,10 +2048,10 @@ bool cmQtAutoGenerators::MocFindIncludedFile( } // Search in include directories if (!success) { - for (std::vector<std::string>::const_iterator iit = - this->MocIncludePaths.begin(); - iit != this->MocIncludePaths.end(); ++iit) { - const std::string fullPath = ((*iit) + '/' + includeString); + for (const std::string& path : this->MocIncludePaths) { + std::string fullPath = path; + fullPath.push_back('/'); + fullPath += includeString; if (cmsys::SystemTools::FileExists(fullPath.c_str())) { absFile = cmsys::SystemTools::GetRealPath(fullPath); success = true; diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index 5cb3d9f..5421408 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -6,6 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmFilePathChecksum.h" +#include "cmQtAutoGen.h" #include "cmsys/RegularExpression.hxx" #include <map> @@ -142,11 +143,11 @@ private: std::string ChecksumedPath(const std::string& sourceFile, const std::string& basePrefix, const std::string& baseSuffix) const; - bool MakeParentDirectory(const char* logPrefix, + bool MakeParentDirectory(cmQtAutoGen::GeneratorType genType, const std::string& filename) const; bool FileDiffers(const std::string& filename, const std::string& content); - bool FileWrite(const char* logPrefix, const std::string& filename, - const std::string& content); + bool FileWrite(cmQtAutoGen::GeneratorType genType, + const std::string& filename, const std::string& content); bool RunCommand(const std::vector<std::string>& command, std::string& output, bool verbose = true) const; |