From d1e5eb849704f73d646f64105d44807f3de50e48 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Sat, 26 Aug 2017 13:59:57 +0200 Subject: Autogen: Iterate source files only once This is a large commit that serves multiple purposes - Iterate source files only once and store all extracted information in a cmQtAutogenDigest class that can be reused. This is brings speed improvements because several properties are only evaluated once. More that that it helps to avoid duplication of code with non trivial files property checks. - Fix the Visual Studio generator to use PRE_BUILD when possible. - Convert `for( ... )` loops to C++11 range base loops where possible (cmQtAutogen*.cxx only). - String concatenation optimizations. --- Modules/AutogenInfo.cmake.in | 3 +- Source/CMakeLists.txt | 5 +- Source/cmGlobalGenerator.cxx | 74 +-- Source/cmGlobalGenerator.h | 4 +- Source/cmQtAutoGen.cxx | 243 ++++++++++ Source/cmQtAutoGen.h | 47 ++ Source/cmQtAutoGenDigest.h | 62 +++ Source/cmQtAutoGeneratorCommon.cxx | 216 --------- Source/cmQtAutoGeneratorCommon.h | 39 -- Source/cmQtAutoGeneratorInitializer.cxx | 784 +++++++++++++++----------------- Source/cmQtAutoGeneratorInitializer.h | 13 +- Source/cmQtAutoGenerators.cxx | 300 +++++------- Source/cmQtAutoGenerators.h | 7 +- 13 files changed, 899 insertions(+), 898 deletions(-) create mode 100644 Source/cmQtAutoGen.cxx create mode 100644 Source/cmQtAutoGen.h create mode 100644 Source/cmQtAutoGenDigest.h delete mode 100644 Source/cmQtAutoGeneratorCommon.cxx delete mode 100644 Source/cmQtAutoGeneratorCommon.h 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 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::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 -cmGlobalGenerator::CreateQtAutoGeneratorsTargets() +cmQtAutoGenDigestUPV cmGlobalGenerator::CreateQtAutoGeneratorsTargets() { - std::vector autogenTargets; + cmQtAutoGenDigestUPV autogenDigests; #ifdef CMAKE_BUILD_WITH_CMAKE - for (std::vector::const_iterator lgit = - this->LocalGenerators.begin(); - lgit != this->LocalGenerators.end(); ++lgit) { - cmLocalGenerator* localGen = *lgit; + for (cmLocalGenerator* localGen : this->LocalGenerators) { const std::vector& targets = localGen->GetGeneratorTargets(); // Find targets that require AUTOGEN processing - std::vector filteredTargets; - filteredTargets.reserve(targets.size()); - for (std::vector::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::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 CreateQtAutoGeneratorsTargets(); + // Qt auto generators + cmQtAutoGenDigestUPV CreateQtAutoGeneratorsTargets(); std::string SelectMakeProgram(const std::string& makeProgram, const std::string& makeDefault = "") const; diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx new file mode 100644 index 0000000..f1453b4 --- /dev/null +++ b/Source/cmQtAutoGen.cxx @@ -0,0 +1,243 @@ +/* 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 "cmAlgorithms.h" +#include "cmSystemTools.h" + +#include "cmsys/FStream.hxx" +#include "cmsys/RegularExpression.hxx" + +#include +#include + +// - 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) +{ + // Strip CR characters rcc may have printed (possibly more than one!). + std::string::size_type cr = line.find('\r'); + if (cr != std::string::npos) { + return line.substr(0, cr); + } + return line; +} + +/// @brief Reads the resource files list from from a .qrc file - Qt4 version +/// @return True if the .qrc file was successfully parsed +static bool RccListInputsQt4(const std::string& fileName, + std::vector& files, + std::string* errorMessage) +{ + bool allGood = true; + // Read qrc file content into string + std::string qrcContents; + { + cmsys::ifstream ifs(fileName.c_str()); + if (ifs) { + std::ostringstream osst; + osst << ifs.rdbuf(); + qrcContents = osst.str(); + } else { + if (errorMessage != nullptr) { + std::ostringstream ost; + ost << "AutoRcc: Error: Rcc file not readable:\n" + << cmQtAutoGen::Quoted(fileName) << "\n"; + *errorMessage = ost.str(); + } + allGood = false; + } + } + if (allGood) { + // qrc file directory + std::string qrcDir(cmsys::SystemTools::GetFilenamePath(fileName)); + if (!qrcDir.empty()) { + qrcDir += '/'; + } + + cmsys::RegularExpression fileMatchRegex("(]*>)"); + + size_t offset = 0; + while (fileMatchRegex.find(qrcContents.c_str() + offset)) { + std::string qrcEntry = fileMatchRegex.match(1); + offset += qrcEntry.size(); + { + fileReplaceRegex.find(qrcEntry); + std::string tag = fileReplaceRegex.match(1); + qrcEntry = qrcEntry.substr(tag.size()); + } + if (!cmSystemTools::FileIsFullPath(qrcEntry.c_str())) { + qrcEntry = qrcDir + qrcEntry; + } + files.push_back(qrcEntry); + } + } + return allGood; +} + +/// @brief Reads the resource files list from from a .qrc file - Qt5 version +/// @return True if the .qrc file was successfully parsed +static bool RccListInputsQt5(const std::string& rccCommand, + const std::string& fileName, + std::vector& files, + std::string* errorMessage) +{ + if (rccCommand.empty()) { + cmSystemTools::Error("AutoRcc: Error: rcc executable not available\n"); + return false; + } + + // Read rcc features + bool hasDashDashList = false; + { + std::vector command; + command.push_back(rccCommand); + command.push_back("--help"); + std::string rccStdOut; + std::string rccStdErr; + int retVal = 0; + bool result = + cmSystemTools::RunSingleCommand(command, &rccStdOut, &rccStdErr, &retVal, + nullptr, cmSystemTools::OUTPUT_NONE); + if (result && retVal == 0 && + rccStdOut.find("--list") != std::string::npos) { + hasDashDashList = true; + } + } + + // Run rcc list command + bool result = false; + int retVal = 0; + std::string rccStdOut; + std::string rccStdErr; + { + std::vector command; + command.push_back(rccCommand); + command.push_back(hasDashDashList ? "--list" : "-list"); + command.push_back(fileName); + result = + cmSystemTools::RunSingleCommand(command, &rccStdOut, &rccStdErr, &retVal, + nullptr, cmSystemTools::OUTPUT_NONE); + } + if (!result || retVal) { + if (errorMessage != nullptr) { + std::ostringstream ost; + ost << "AutoRcc: Error: Rcc list process for " << fileName + << " failed:\n" + << rccStdOut << "\n" + << rccStdErr << "\n"; + *errorMessage = ost.str(); + } + return false; + } + + // Parse rcc std output + { + std::istringstream ostr(rccStdOut); + std::string oline; + while (std::getline(ostr, oline)) { + oline = utilStripCR(oline); + if (!oline.empty()) { + files.push_back(oline); + } + } + } + // Parse rcc error output + { + std::istringstream estr(rccStdErr); + std::string eline; + while (std::getline(estr, eline)) { + eline = utilStripCR(eline); + if (cmHasLiteralPrefix(eline, "RCC: Error in")) { + static std::string searchString = "Cannot find file '"; + + std::string::size_type pos = eline.find(searchString); + if (pos == std::string::npos) { + if (errorMessage != nullptr) { + std::ostringstream ost; + ost << "AutoRcc: Error: Rcc lists unparsable output:\n" + << cmQtAutoGen::Quoted(eline) << "\n"; + *errorMessage = ost.str(); + } + return false; + } + pos += searchString.length(); + std::string::size_type sz = eline.size() - pos - 1; + files.push_back(eline.substr(pos, sz)); + } + } + } + + return true; +} + +// - Class definitions + +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 cmQtAutoGen::Quoted(const std::string& text) +{ + static const char* rep[18] = { "\\", "\\\\", "\"", "\\\"", "\a", "\\a", + "\b", "\\b", "\f", "\\f", "\n", "\\n", + "\r", "\\r", "\t", "\\t", "\v", "\\v" }; + + std::string res = text; + for (const char* const* it = cmArrayBegin(rep); it != cmArrayEnd(rep); + it += 2) { + cmSystemTools::ReplaceString(res, *it, *(it + 1)); + } + res = '"' + res; + res += '"'; + return res; +} + +bool cmQtAutoGen::RccListInputs(const std::string& qtMajorVersion, + const std::string& rccCommand, + const std::string& fileName, + std::vector& files, + std::string* errorMessage) +{ + bool allGood = false; + if (cmsys::SystemTools::FileExists(fileName.c_str())) { + if (qtMajorVersion == "4") { + allGood = RccListInputsQt4(fileName, files, errorMessage); + } else { + allGood = RccListInputsQt5(rccCommand, fileName, files, errorMessage); + } + } else { + if (errorMessage != nullptr) { + std::ostringstream ost; + ost << "AutoRcc: Error: Rcc file does not exist:\n" + << cmQtAutoGen::Quoted(fileName) << "\n"; + *errorMessage = ost.str(); + } + } + return allGood; +} diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h new file mode 100644 index 0000000..88fd0fc --- /dev/null +++ b/Source/cmQtAutoGen.h @@ -0,0 +1,47 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmQtAutoGen_h +#define cmQtAutoGen_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include +#include + +/** \class cmQtAutoGen + * \brief Class used as namespace for QtAutogen related types and functions + */ +class cmQtAutoGen +{ +public: + 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); + + /// @brief Reads the resource files list from from a .qrc file + /// @arg fileName Must be the absolute path of the .qrc file + /// @return True if the rcc file was successfully parsed + static bool RccListInputs(const std::string& qtMajorVersion, + const std::string& rccCommand, + const std::string& fileName, + std::vector& files, + std::string* errorMessage = nullptr); +}; + +#endif 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 +#include +#include + +class cmGeneratorTarget; + +class cmQtAutoGenDigestQrc +{ +public: + cmQtAutoGenDigestQrc() + : Generated(false) + { + } + +public: + std::string QrcFile; + std::string RccFile; + bool Generated; + std::vector Options; + std::vector 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 Headers; + std::vector HeadersGenerated; + std::vector Sources; + std::vector SourcesGenerated; + std::vector Qrcs; +}; + +// Utility types +typedef std::unique_ptr cmQtAutoGenDigestUP; +typedef std::vector cmQtAutoGenDigestUPV; + +#endif diff --git a/Source/cmQtAutoGeneratorCommon.cxx b/Source/cmQtAutoGeneratorCommon.cxx deleted file mode 100644 index a8e6b96..0000000 --- a/Source/cmQtAutoGeneratorCommon.cxx +++ /dev/null @@ -1,216 +0,0 @@ -/* 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 "cmAlgorithms.h" -#include "cmSystemTools.h" - -#include "cmsys/FStream.hxx" -#include "cmsys/RegularExpression.hxx" - -#include -#include - -// - Static functions - -static std::string utilStripCR(std::string const& line) -{ - // Strip CR characters rcc may have printed (possibly more than one!). - std::string::size_type cr = line.find('\r'); - if (cr != std::string::npos) { - return line.substr(0, cr); - } - return line; -} - -/// @brief Reads the resource files list from from a .qrc file - Qt4 version -/// @return True if the .qrc file was successfully parsed -static bool RccListInputsQt4(const std::string& fileName, - std::vector& files, - std::string* errorMessage) -{ - bool allGood = true; - // Read qrc file content into string - std::string qrcContents; - { - cmsys::ifstream ifs(fileName.c_str()); - if (ifs) { - std::ostringstream osst; - osst << ifs.rdbuf(); - qrcContents = osst.str(); - } else { - if (errorMessage != nullptr) { - std::ostringstream ost; - ost << "AutoRcc: Error: Rcc file not readable:\n" - << cmQtAutoGeneratorCommon::Quoted(fileName) << "\n"; - *errorMessage = ost.str(); - } - allGood = false; - } - } - if (allGood) { - // qrc file directory - std::string qrcDir(cmsys::SystemTools::GetFilenamePath(fileName)); - if (!qrcDir.empty()) { - qrcDir += '/'; - } - - cmsys::RegularExpression fileMatchRegex("(]*>)"); - - size_t offset = 0; - while (fileMatchRegex.find(qrcContents.c_str() + offset)) { - std::string qrcEntry = fileMatchRegex.match(1); - offset += qrcEntry.size(); - { - fileReplaceRegex.find(qrcEntry); - std::string tag = fileReplaceRegex.match(1); - qrcEntry = qrcEntry.substr(tag.size()); - } - if (!cmSystemTools::FileIsFullPath(qrcEntry.c_str())) { - qrcEntry = qrcDir + qrcEntry; - } - files.push_back(qrcEntry); - } - } - return allGood; -} - -/// @brief Reads the resource files list from from a .qrc file - Qt5 version -/// @return True if the .qrc file was successfully parsed -static bool RccListInputsQt5(const std::string& rccCommand, - const std::string& fileName, - std::vector& files, - std::string* errorMessage) -{ - if (rccCommand.empty()) { - cmSystemTools::Error("AutoRcc: Error: rcc executable not available\n"); - return false; - } - - // Read rcc features - bool hasDashDashList = false; - { - std::vector command; - command.push_back(rccCommand); - command.push_back("--help"); - std::string rccStdOut; - std::string rccStdErr; - int retVal = 0; - bool result = - cmSystemTools::RunSingleCommand(command, &rccStdOut, &rccStdErr, &retVal, - nullptr, cmSystemTools::OUTPUT_NONE); - if (result && retVal == 0 && - rccStdOut.find("--list") != std::string::npos) { - hasDashDashList = true; - } - } - - // Run rcc list command - bool result = false; - int retVal = 0; - std::string rccStdOut; - std::string rccStdErr; - { - std::vector command; - command.push_back(rccCommand); - command.push_back(hasDashDashList ? "--list" : "-list"); - command.push_back(fileName); - result = - cmSystemTools::RunSingleCommand(command, &rccStdOut, &rccStdErr, &retVal, - nullptr, cmSystemTools::OUTPUT_NONE); - } - if (!result || retVal) { - if (errorMessage != nullptr) { - std::ostringstream ost; - ost << "AutoRcc: Error: Rcc list process for " << fileName - << " failed:\n" - << rccStdOut << "\n" - << rccStdErr << "\n"; - *errorMessage = ost.str(); - } - return false; - } - - // Parse rcc std output - { - std::istringstream ostr(rccStdOut); - std::string oline; - while (std::getline(ostr, oline)) { - oline = utilStripCR(oline); - if (!oline.empty()) { - files.push_back(oline); - } - } - } - // Parse rcc error output - { - std::istringstream estr(rccStdErr); - std::string eline; - while (std::getline(estr, eline)) { - eline = utilStripCR(eline); - if (cmHasLiteralPrefix(eline, "RCC: Error in")) { - static std::string searchString = "Cannot find file '"; - - std::string::size_type pos = eline.find(searchString); - if (pos == std::string::npos) { - if (errorMessage != nullptr) { - std::ostringstream ost; - ost << "AutoRcc: Error: Rcc lists unparsable output:\n" - << cmQtAutoGeneratorCommon::Quoted(eline) << "\n"; - *errorMessage = ost.str(); - } - return false; - } - pos += searchString.length(); - std::string::size_type sz = eline.size() - pos - 1; - files.push_back(eline.substr(pos, sz)); - } - } - } - - return true; -} - -// - Class definitions - -const char* cmQtAutoGeneratorCommon::listSep = "@LSEP@"; - -std::string cmQtAutoGeneratorCommon::Quoted(const std::string& text) -{ - static const char* rep[18] = { "\\", "\\\\", "\"", "\\\"", "\a", "\\a", - "\b", "\\b", "\f", "\\f", "\n", "\\n", - "\r", "\\r", "\t", "\\t", "\v", "\\v" }; - - std::string res = text; - for (const char* const* it = cmArrayBegin(rep); it != cmArrayEnd(rep); - it += 2) { - cmSystemTools::ReplaceString(res, *it, *(it + 1)); - } - res = '"' + res; - res += '"'; - return res; -} - -bool cmQtAutoGeneratorCommon::RccListInputs(const std::string& qtMajorVersion, - const std::string& rccCommand, - const std::string& fileName, - std::vector& files, - std::string* errorMessage) -{ - bool allGood = false; - if (cmsys::SystemTools::FileExists(fileName.c_str())) { - if (qtMajorVersion == "4") { - allGood = RccListInputsQt4(fileName, files, errorMessage); - } else { - allGood = RccListInputsQt5(rccCommand, fileName, files, errorMessage); - } - } else { - if (errorMessage != nullptr) { - std::ostringstream ost; - ost << "AutoRcc: Error: Rcc file does not exist:\n" - << cmQtAutoGeneratorCommon::Quoted(fileName) << "\n"; - *errorMessage = ost.str(); - } - } - return allGood; -} diff --git a/Source/cmQtAutoGeneratorCommon.h b/Source/cmQtAutoGeneratorCommon.h deleted file mode 100644 index 23a882a..0000000 --- a/Source/cmQtAutoGeneratorCommon.h +++ /dev/null @@ -1,39 +0,0 @@ -/* 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 - -#include "cmConfigure.h" // IWYU pragma: keep - -#include -#include - -class cmQtAutoGeneratorCommon -{ - // - Types and statics -public: - static const char* listSep; - - enum GeneratorType - { - MOC, - UIC, - RCC - }; - -public: - /// @brief Returns a the string escaped and enclosed in quotes - /// - static std::string Quoted(const std::string& text); - - /// @brief Reads the resource files list from from a .qrc file - /// @arg fileName Must be the absolute path of the .qrc file - /// @return True if the rcc file was successfully parsed - static bool RccListInputs(const std::string& qtMajorVersion, - const std::string& rccCommand, - const std::string& fileName, - std::vector& files, - std::string* errorMessage = nullptr); -}; - -#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 +#include #include #include #include @@ -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 GetConfigurationSuffixes(cmMakefile* makefile) std::vector suffixes; if (AutogenMultiConfig(makefile->GetGlobalGenerator())) { makefile->GetConfigurations(suffixes); - for (std::vector::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 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 sources; - std::vector headers; + std::set MocSkip; + std::set UicSkip; - std::set mocSkip; - std::set uicSkip; - - std::map configSuffix; - std::map configMocIncludes; - std::map configMocDefines; - std::map configUicOptions; + std::map ConfigMocIncludes; + std::map ConfigMocDefines; + std::map ConfigUicOptions; }; -static void SetupAcquireScanFiles(cmGeneratorTarget const* target, - bool mocEnabled, bool uicEnabled, - const std::vector& srcFiles, - AutogenSetup& setup) +static void SetupAcquireSkipFiles(cmQtAutoGenDigest const& digest, + cmQtAutoGenSetup& setup) { // Read skip files from makefile sources { const std::vector& allSources = - target->Makefile->GetSourceFiles(); - for (std::vector::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::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 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::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 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::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::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& srcFiles = makefile->GetSourceFiles(); - for (std::vector::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& opts, const std::vector& fileOpts, bool isQt5) { - static const char* valueOptions[] = { "name", "root", "compress", - "threshold" }; + typedef std::vector::iterator Iter; + typedef std::vector::const_iterator CIter; + static const char* valueOptions[4] = { "name", "root", "compress", + "threshold" }; + std::vector extraOpts; - for (std::vector::const_iterator fit = fileOpts.begin(); - fit != fileOpts.end(); ++fit) { - std::vector::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& opts, if ((optName != fit->c_str()) && std::find_if(cmArrayBegin(valueOptions), cmArrayEnd(valueOptions), cmStrCmp(optName)) != cmArrayEnd(valueOptions)) { - const std::vector::iterator existValueIt(existingIt + 1); - const std::vector::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& 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& 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 rccFiles; std::vector rccInputs; std::vector rccFileFiles; std::vector rccFileOptions; - std::vector rccOptionsTarget; - - cmSystemTools::ExpandListArgument(GetSafeProperty(target, "AUTORCC_OPTIONS"), - rccOptionsTarget); - - for (std::vector::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 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 rccOptions(rccOptionsTarget); - if (const char* prop = sf->GetProperty("AUTORCC_OPTIONS")) { - std::vector 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 suffixes = GetConfigurationSuffixes(makefile); - std::set autogenDependsSet; + std::set autogenDepends; std::vector 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::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 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 += "_$"; @@ -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 extraDepends; - cmSystemTools::ExpandListArgument(deps, extraDepends); - autogenDependsSet.insert(extraDepends.begin(), extraDepends.end()); - } - } - // Add utility target dependencies to the autogen dependencies - { - const std::set& utils = target->Target->GetUtilities(); - for (std::set::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 generatedSources; - std::vector> qrcSources; { const std::string qrcExt = "qrc"; std::vector srcFiles; target->GetConfigCommonSourceFiles(srcFiles); - for (std::vector::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(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::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>::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 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 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 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 extraDeps; + cmSystemTools::ExpandListArgument(deps, extraDeps); + autogenDepends.insert(extraDeps.begin(), extraDeps.end()); + } + } + // Add utility target dependencies to the autogen target dependencies + { + const std::set& 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 autogenDepends(autogenDependsSet.begin(), - autogenDependsSet.end()); - // Disable PRE_BUILD on demand + const std::vector 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::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 no_output; - cmCustomCommand cc(makefile, no_output, autogenProvides, autogenDepends, + const std::vector 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 configSuffix; if (AutogenMultiConfig(target->GetGlobalGenerator())) { - for (std::vector::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 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::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::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::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::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 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 +#include #include #include #include @@ -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& command) { std::string res; - for (std::vector::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::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& opts) { std::string result; - for (std::map::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& lst) -{ - std::string result; - if (!lst.empty()) { - const std::string separator = ","; - for (std::vector::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 MocMacroNames; InfoGet(makefile, "AM_MOC_MACRO_NAMES", MocMacroNames); - for (std::vector::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::const_iterator dit = - mocDependFilters.begin(); - dit != mocDependFilters.end(); dit += 2) { + for (std::vector::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 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 movePaths = { + { &this->ProjectBinaryDir, &this->ProjectSourceDir } + }; + for (const std::string* ppath : movePaths) { std::list::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 frameworkPaths; - for (std::vector::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::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 uicHeaderFiles; // Parse sources - for (std::vector::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::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::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>& mocDepends) { - for (std::vector::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& mocHeaderFiles, std::set& uicHeaderFiles) const { - std::string basepaths[2]; + std::array 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::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::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 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::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 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::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::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::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::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& sourceIncs(sit->second); // insert new source/destination map std::map& uiGenMap = sourceGenMap[source]; - for (std::vector::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>::const_iterator it = - sourceGenMap.begin(); - it != sourceGenMap.end(); ++it) { - for (std::map::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 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::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::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::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& collisions) const { - typedef std::multimap::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& command, bool cmQtAutoGenerators::FindHeader(std::string& header, const std::string& testBasePath) const { - for (std::vector::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::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::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 @@ -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& command, std::string& output, bool verbose = true) const; -- cgit v0.12