summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2017-09-08 13:44:46 (GMT)
committerKitware Robot <kwrobot@kitware.com>2017-09-08 13:45:07 (GMT)
commite5c1a7dfb3ca419967511ac471c91ebc2c5d76a1 (patch)
treed77daf590097eba6f265c231cfbb94743c0861b9 /Source
parent90b6186cbdf4e1deeeaa60eaae00e8461136ea6a (diff)
parent6739a12571bfa8b97b00740981e9f6eb5195529f (diff)
downloadCMake-e5c1a7dfb3ca419967511ac471c91ebc2c5d76a1.zip
CMake-e5c1a7dfb3ca419967511ac471c91ebc2c5d76a1.tar.gz
CMake-e5c1a7dfb3ca419967511ac471c91ebc2c5d76a1.tar.bz2
Merge topic 'autogen-digests'
6739a125 Autogen: Doc: Add Visual Studio PRE_BUILD note to cmake-qt.rst 2be0acb7 Autogen: Tests: Add AUTOGEN_TARGET_DEPENDS test to mocDepends tests 734d236c Autogen: Smarter target dependency computation 2e4dab08 Autogen: Set CM_DISABLE_COPY in cmQtAutoGenerators c330d641 Autogen: Replace CM_AUTO_PTR with std::unique_ptr 9468e926 Autogen: Refactor logging 2ba1b281 Autogen: More use of scoped lambdas 0f9080e2 Autogen: More use of scoped lambdas ... Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !1198
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt5
-rw-r--r--Source/cmGlobalGenerator.cxx74
-rw-r--r--Source/cmGlobalGenerator.h4
-rw-r--r--Source/cmQtAutoGen.cxx (renamed from Source/cmQtAutoGeneratorCommon.cxx)140
-rw-r--r--Source/cmQtAutoGen.h (renamed from Source/cmQtAutoGeneratorCommon.h)28
-rw-r--r--Source/cmQtAutoGenDigest.h64
-rw-r--r--Source/cmQtAutoGeneratorInitializer.cxx948
-rw-r--r--Source/cmQtAutoGeneratorInitializer.h13
-rw-r--r--Source/cmQtAutoGenerators.cxx1410
-rw-r--r--Source/cmQtAutoGenerators.h92
10 files changed, 1458 insertions, 1320 deletions
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..95cd122 100644
--- a/Source/cmQtAutoGeneratorCommon.cxx
+++ b/Source/cmQtAutoGen.cxx
@@ -1,17 +1,79 @@
/* 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"
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
+#include <algorithm>
#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
+/// @brief Merges newOpts into baseOpts
+/// @arg valueOpts list of options that accept a value
+void MergeOptions(std::vector<std::string>& baseOpts,
+ const std::vector<std::string>& newOpts,
+ const std::vector<std::string>& valueOpts, bool isQt5)
+{
+ typedef std::vector<std::string>::iterator Iter;
+ typedef std::vector<std::string>::const_iterator CIter;
+ if (newOpts.empty()) {
+ return;
+ }
+ if (baseOpts.empty()) {
+ baseOpts = newOpts;
+ return;
+ }
+
+ std::vector<std::string> extraOpts;
+ for (CIter fit = newOpts.begin(), fitEnd = newOpts.end(); fit != fitEnd;
+ ++fit) {
+ const std::string& newOpt = *fit;
+ Iter existIt = std::find(baseOpts.begin(), baseOpts.end(), newOpt);
+ if (existIt != baseOpts.end()) {
+ if (newOpt.size() >= 2) {
+ // Acquire the option name
+ std::string optName;
+ {
+ auto oit = newOpt.begin();
+ if (*oit == '-') {
+ ++oit;
+ if (isQt5 && (*oit == '-')) {
+ ++oit;
+ }
+ optName.assign(oit, newOpt.end());
+ }
+ }
+ // Test if this is a value option and change the existing value
+ if (!optName.empty() && (std::find(valueOpts.begin(), valueOpts.end(),
+ optName) != valueOpts.end())) {
+ const Iter existItNext(existIt + 1);
+ const CIter fitNext(fit + 1);
+ if ((existItNext != baseOpts.end()) && (fitNext != fitEnd)) {
+ *existItNext = *fitNext;
+ ++fit;
+ }
+ }
+ }
+ } else {
+ extraOpts.push_back(newOpt);
+ }
+ }
+ // Append options
+ baseOpts.insert(baseOpts.end(), extraOpts.begin(), extraOpts.end());
+}
+
static std::string utilStripCR(std::string const& line)
{
// Strip CR characters rcc may have printed (possibly more than one!).
@@ -40,8 +102,8 @@ static bool RccListInputsQt4(const std::string& fileName,
} else {
if (errorMessage != nullptr) {
std::ostringstream ost;
- ost << "AutoRcc: Error: Rcc file not readable:\n"
- << cmQtAutoGeneratorCommon::Quoted(fileName) << "\n";
+ ost << "rcc file not readable:\n"
+ << " " << cmQtAutoGen::Quoted(fileName) << "\n";
*errorMessage = ost.str();
}
allGood = false;
@@ -49,7 +111,7 @@ static bool RccListInputsQt4(const std::string& fileName,
}
if (allGood) {
// qrc file directory
- std::string qrcDir(cmsys::SystemTools::GetFilenamePath(fileName));
+ std::string qrcDir(cmSystemTools::GetFilenamePath(fileName));
if (!qrcDir.empty()) {
qrcDir += '/';
}
@@ -83,7 +145,7 @@ static bool RccListInputsQt5(const std::string& rccCommand,
std::string* errorMessage)
{
if (rccCommand.empty()) {
- cmSystemTools::Error("AutoRcc: Error: rcc executable not available\n");
+ cmSystemTools::Error("rcc executable not available");
return false;
}
@@ -122,7 +184,7 @@ static bool RccListInputsQt5(const std::string& rccCommand,
if (!result || retVal) {
if (errorMessage != nullptr) {
std::ostringstream ost;
- ost << "AutoRcc: Error: Rcc list process for " << fileName
+ ost << "rcc list process for " << cmQtAutoGen::Quoted(fileName)
<< " failed:\n"
<< rccStdOut << "\n"
<< rccStdErr << "\n";
@@ -155,8 +217,8 @@ static bool RccListInputsQt5(const std::string& rccCommand,
if (pos == std::string::npos) {
if (errorMessage != nullptr) {
std::ostringstream ost;
- ost << "AutoRcc: Error: Rcc lists unparsable output:\n"
- << cmQtAutoGeneratorCommon::Quoted(eline) << "\n";
+ ost << "rcc lists unparsable output:\n"
+ << cmQtAutoGen::Quoted(eline) << "\n";
*errorMessage = ost.str();
}
return false;
@@ -173,9 +235,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,14 +273,36 @@ 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)
+void cmQtAutoGen::UicMergeOptions(std::vector<std::string>& baseOpts,
+ const std::vector<std::string>& newOpts,
+ bool isQt5)
+{
+ static const std::vector<std::string> valueOpts = {
+ "tr", "translate", "postfix", "generator",
+ "include", // Since Qt 5.3
+ "g"
+ };
+ MergeOptions(baseOpts, newOpts, valueOpts, isQt5);
+}
+
+void cmQtAutoGen::RccMergeOptions(std::vector<std::string>& baseOpts,
+ const std::vector<std::string>& newOpts,
+ bool isQt5)
+{
+ static const std::vector<std::string> valueOpts = { "name", "root",
+ "compress",
+ "threshold" };
+ MergeOptions(baseOpts, newOpts, valueOpts, isQt5);
+}
+
+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())) {
+ if (cmSystemTools::FileExists(fileName.c_str())) {
if (qtMajorVersion == "4") {
allGood = RccListInputsQt4(fileName, files, errorMessage);
} else {
@@ -207,8 +311,8 @@ bool cmQtAutoGeneratorCommon::RccListInputs(const std::string& qtMajorVersion,
} else {
if (errorMessage != nullptr) {
std::ostringstream ost;
- ost << "AutoRcc: Error: Rcc file does not exist:\n"
- << cmQtAutoGeneratorCommon::Quoted(fileName) << "\n";
+ ost << "rcc file does not exist:\n"
+ << " " << cmQtAutoGen::Quoted(fileName) << "\n";
*errorMessage = ost.str();
}
}
diff --git a/Source/cmQtAutoGeneratorCommon.h b/Source/cmQtAutoGen.h
index 23a882a..4cd5e32 100644
--- a/Source/cmQtAutoGeneratorCommon.h
+++ b/Source/cmQtAutoGen.h
@@ -1,31 +1,49 @@
/* 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);
+ /// @brief Merges newOpts into baseOpts
+ static void UicMergeOptions(std::vector<std::string>& baseOpts,
+ const std::vector<std::string>& newOpts,
+ bool isQt5);
+
+ /// @brief Merges newOpts into baseOpts
+ static void RccMergeOptions(std::vector<std::string>& baseOpts,
+ const std::vector<std::string>& newOpts,
+ bool isQt5);
+
/// @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
diff --git a/Source/cmQtAutoGenDigest.h b/Source/cmQtAutoGenDigest.h
new file mode 100644
index 0000000..677c397
--- /dev/null
+++ b/Source/cmQtAutoGenDigest.h
@@ -0,0 +1,64 @@
+/* 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)
+ , Unique(false)
+ {
+ }
+
+public:
+ std::string QrcFile;
+ std::string QrcName;
+ std::string PathChecksum;
+ std::string RccFile;
+ bool Generated;
+ bool Unique;
+ 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> Sources;
+ 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..22ac9d2 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,
@@ -126,26 +134,6 @@ static bool QtVersionGreaterOrEqual(const std::string& major,
return false;
}
-static void GetCompileDefinitionsAndDirectories(
- cmGeneratorTarget const* target, const std::string& config,
- std::string& incs, std::string& defs)
-{
- cmLocalGenerator* localGen = target->GetLocalGenerator();
- {
- std::vector<std::string> includeDirs;
- // Get the include dirs for this target, without stripping the implicit
- // include dirs off, see
- // https://gitlab.kitware.com/cmake/cmake/issues/13667
- localGen->GetIncludeDirectories(includeDirs, target, "CXX", config, false);
- incs = cmJoin(includeDirs, ";");
- }
- {
- std::set<std::string> defines;
- localGen->AddCompileDefinitions(defines, target, config, "CXX");
- defs += cmJoin(defines, ";");
- }
-}
-
static std::vector<std::string> GetConfigurations(
cmMakefile* makefile, std::string* config = nullptr)
{
@@ -168,9 +156,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()) {
@@ -200,33 +187,56 @@ static void AddDefinitionEscaped(cmMakefile* makefile, const char* key,
key, cmOutputConverter::EscapeForCMake(cmJoin(values, ";")).c_str());
}
+static void AddDefinitionEscaped(
+ cmMakefile* makefile, const char* key,
+ const std::vector<std::vector<std::string>>& lists)
+{
+ std::vector<std::string> seplist;
+ for (const std::vector<std::string>& list : lists) {
+ std::string blist = "{";
+ blist += cmJoin(list, ";");
+ blist += "}";
+ seplist.push_back(std::move(blist));
+ }
+ makefile->AddDefinition(key, cmOutputConverter::EscapeForCMake(
+ cmJoin(seplist, cmQtAutoGen::listSep))
+ .c_str());
+}
+
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 +252,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 +276,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 +289,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 +316,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);
+ const std::string absFile = cmSystemTools::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,33 +353,49 @@ 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"));
}
// Moc includes and compile definitions
{
+ auto GetCompileDefinitionsAndDirectories = [target, localGen](
+ const std::string& cfg, std::string& incs, std::string& defs) {
+ {
+ std::vector<std::string> includeDirs;
+ // Get the include dirs for this target, without stripping the implicit
+ // include dirs off, see
+ // https://gitlab.kitware.com/cmake/cmake/issues/13667
+ localGen->GetIncludeDirectories(includeDirs, target, "CXX", cfg,
+ false);
+ incs = cmJoin(includeDirs, ";");
+ }
+ {
+ std::set<std::string> defines;
+ localGen->AddCompileDefinitions(defines, target, cfg, "CXX");
+ defs += cmJoin(defines, ";");
+ }
+ };
+
// Default settings
std::string incs;
std::string compileDefs;
- GetCompileDefinitionsAndDirectories(target, config, incs, compileDefs);
+ GetCompileDefinitionsAndDirectories(config, incs, compileDefs);
AddDefinitionEscaped(makefile, "_moc_incs", incs);
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,
- configCompileDefs);
+ GetCompileDefinitionsAndDirectories(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 +405,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(""));
@@ -473,24 +432,15 @@ static void SetupAutoTargetMoc(cmGeneratorTarget const* target,
}
}
-static void UicGetOpts(cmGeneratorTarget const* target,
- const std::string& config, std::string& optString)
-{
- std::vector<std::string> opts;
- target->GetAutoUicOptions(opts, config);
- 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 +450,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);
}
}
}
@@ -510,44 +459,45 @@ static void SetupAutoTargetUic(cmGeneratorTarget const* target,
}
// Uic target options
{
+ auto UicGetOpts = [target](const std::string& cfg) -> std::string {
+ std::vector<std::string> opts;
+ target->GetAutoUicOptions(opts, cfg);
+ return cmJoin(opts, ";");
+ };
+
// Default settings
- std::string uicOpts;
- UicGetOpts(target, config, uicOpts);
+ const std::string uicOpts = UicGetOpts(config);
AddDefinitionEscaped(makefile, "_uic_target_options", uicOpts);
// Configuration specific settings
- for (std::vector<std::string>::const_iterator li = configs.begin();
- li != configs.end(); ++li) {
- std::string configUicOpts;
- UicGetOpts(target, *li, configUicOpts);
+ for (const std::string& cfg : configs) {
+ const std::string configUicOpts = UicGetOpts(cfg);
if (configUicOpts != uicOpts) {
- setup.configUicOptions[*li] = configUicOpts;
+ setup.ConfigUicOptions[cfg] = configUicOpts;
}
}
}
// Uic files options
{
std::vector<std::string> uiFileFiles;
- std::vector<std::string> uiFileOptions;
+ std::vector<std::vector<std::string>> uiFileOptions;
{
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");
+ const std::string uicOpts = GetSafeProperty(sf, "AUTOUIC_OPTIONS");
if (!uicOpts.empty()) {
- const std::string absFile = cmsys::SystemTools::GetRealPath(fPath);
+ const std::string absFile = cmSystemTools::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);
- uiFileOptions.push_back(uicOpts);
+ std::vector<std::string> optsVec;
+ cmSystemTools::ExpandListArgument(uicOpts, optsVec);
+ uiFileOptions.push_back(std::move(optsVec));
}
}
}
@@ -562,14 +512,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(""));
@@ -621,141 +572,48 @@ static std::string RccGetExecutable(cmGeneratorTarget const* target,
return rccExec;
}
-static void RccMergeOptions(std::vector<std::string>& opts,
- const std::vector<std::string>& fileOpts,
- bool isQt5)
+static void SetupAutoTargetRcc(const cmQtAutoGenDigest& digest)
{
- static const char* valueOptions[] = { "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()) {
- const char* optName = fit->c_str();
- if (*optName == '-') {
- ++optName;
- if (isQt5 && *optName == '-') {
- ++optName;
- }
- }
- // Test if this is a value option and change the existing value
- 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;
- ++fit;
- }
- }
- } else {
- extraOpts.push_back(*fit);
- }
- }
- opts.insert(opts.end(), extraOpts.begin(), extraOpts.end());
-}
-
-static void SetupAutoTargetRcc(cmGeneratorTarget const* target,
- const std::string& qtMajorVersion,
- const std::vector<cmSourceFile*>& srcFiles)
-{
- 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));
- }
- }
- }
+ std::vector<std::string> rccBuilds;
+ std::vector<std::vector<std::string>> rccOptions;
+ std::vector<std::vector<std::string>> rccInputs;
+
+ for (const cmQtAutoGenDigestQrc& qrcDigest : digest.Qrcs) {
+ rccFiles.push_back(qrcDigest.QrcFile);
+ rccBuilds.push_back(qrcDigest.RccFile);
+ rccOptions.push_back(qrcDigest.Options);
+ rccInputs.push_back(qrcDigest.Resources);
}
- AddDefinitionEscaped(makefile, "_qt_rcc_executable", rccCommand);
+ cmMakefile* makefile = digest.Target->Target->GetMakefile();
+ AddDefinitionEscaped(makefile, "_qt_rcc_executable",
+ RccGetExecutable(digest.Target, digest.QtVersionMajor));
AddDefinitionEscaped(makefile, "_rcc_files", rccFiles);
+ AddDefinitionEscaped(makefile, "_rcc_builds", rccBuilds);
+ AddDefinitionEscaped(makefile, "_rcc_options", rccOptions);
AddDefinitionEscaped(makefile, "_rcc_inputs", rccInputs);
- AddDefinitionEscaped(makefile, "_rcc_options_files", rccFileFiles);
- AddDefinitionEscaped(makefile, "_rcc_options_options", rccFileOptions);
}
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> autogenDependFiles;
+ std::set<std::string> autogenDependTargets;
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 +621,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 +642,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 +665,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 +680,14 @@ 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;
+ std::vector<std::string> generatedHeaders;
{
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 +695,51 @@ 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 = cmSystemTools::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) {
+ generatedHeaders.push_back(absPath);
+ } else {
+ digest.Headers.push_back(absPath);
+ }
+ } else {
+ if (generated) {
+ generatedSources.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 = cmSystemTools::GetRealPath(fPath);
+ qrcDigest.QrcName =
+ cmSystemTools::GetFilenameWithoutLastExtension(qrcDigest.QrcFile);
+ 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,104 +749,242 @@ 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 (!generatedSources.empty() || !generatedHeaders.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 (!qrcSources.empty()) {
- const std::string qtMajorVersion = GetQtMajorVersion(target);
- const std::string rccCommand = RccGetExecutable(target, qtMajorVersion);
- 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
+ if (policyAccept) {
+ // Accept GENERATED sources
+ for (const std::string& absFile : generatedHeaders) {
+ digest.Headers.push_back(absFile);
+ autogenDependFiles.insert(absFile);
+ }
+ for (const std::string& absFile : generatedSources) {
+ digest.Sources.push_back(absFile);
+ autogenDependFiles.insert(absFile);
+ }
+ } else {
+ if (policyWarn) {
+ std::string msg;
+ msg += cmPolicies::GetPolicyWarning(cmPolicies::CMP0071);
+ msg += "\n";
+ std::string tools;
+ if (digest.MocEnabled) {
+ tools += "AUTOMOC";
+ }
+ if (digest.UicEnabled) {
+ if (!tools.empty()) {
+ tools += ",";
+ }
+ tools += "AUTOUIC";
+ }
+ if (!generatedHeaders.empty()) {
+ msg.append(tools).append(": Ignoring GENERATED header file(s):\n");
+ for (const std::string& absFile : generatedHeaders) {
+ msg.append(" ").append(cmQtAutoGen::Quoted(absFile)).append("\n");
+ }
+ }
+ if (!generatedSources.empty()) {
+ msg.append(tools).append(": Ignoring GENERATED source file(s):\n");
+ for (const std::string& absFile : generatedSources) {
+ msg.append(" ").append(cmQtAutoGen::Quoted(absFile)).append("\n");
+ }
+ }
+ makefile->IssueMessage(cmake::AUTHOR_WARNING, msg);
+ }
+ }
+ }
+ // Sort headers and sources
+ std::sort(digest.Headers.begin(), digest.Headers.end());
+ std::sort(digest.Sources.begin(), digest.Sources.end());
+
+ // Process qrc files
+ if (!digest.Qrcs.empty()) {
+ const bool QtV5 = (digest.QtVersionMajor == "5");
+ const std::string rcc = RccGetExecutable(target, digest.QtVersionMajor);
+ // Target rcc options
+ std::vector<std::string> optionsTarget;
+ cmSystemTools::ExpandListArgument(
+ GetSafeProperty(target, "AUTORCC_OPTIONS"), optionsTarget);
+
+ // Check if file name is unique
+ for (cmQtAutoGenDigestQrc& qrcDigest : digest.Qrcs) {
+ qrcDigest.Unique = true;
+ for (const cmQtAutoGenDigestQrc& qrcDig2 : digest.Qrcs) {
+ if ((&qrcDigest != &qrcDig2) &&
+ (qrcDigest.QrcName == qrcDig2.QrcName)) {
+ qrcDigest.Unique = false;
+ break;
+ }
+ }
+ }
+ // Path checksum
+ {
+ const cmFilePathChecksum fpathCheckSum(makefile);
+ for (cmQtAutoGenDigestQrc& qrcDigest : digest.Qrcs) {
+ qrcDigest.PathChecksum = fpathCheckSum.getPart(qrcDigest.QrcFile);
+ // RCC output file name
+ std::string rccFile = autogenBuildDir + "/";
+ rccFile += qrcDigest.PathChecksum;
+ rccFile += "/qrc_";
+ rccFile += qrcDigest.QrcName;
+ rccFile += ".cpp";
+ qrcDigest.RccFile = std::move(rccFile);
+ }
+ }
+ // RCC options
+ for (cmQtAutoGenDigestQrc& qrcDigest : digest.Qrcs) {
+ // Target options
+ std::vector<std::string> opts = optionsTarget;
+ // Merge computed "-name XYZ" option
{
- 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 name = qrcDigest.QrcName;
+ // Replace '-' with '_'. The former is not valid for symbol names.
+ std::replace(name.begin(), name.end(), '-', '_');
+ if (!qrcDigest.Unique) {
+ name += "_";
+ name += qrcDigest.PathChecksum;
+ }
+ std::vector<std::string> nameOpts;
+ nameOpts.emplace_back("-name");
+ nameOpts.emplace_back(std::move(name));
+ cmQtAutoGen::RccMergeOptions(opts, nameOpts, QtV5);
}
-
- if (it->second) {
- // Add generated qrc file to the dependencies
- autogenDependsSet.insert(absFile);
+ // Merge file option
+ cmQtAutoGen::RccMergeOptions(opts, qrcDigest.Options, QtV5);
+ qrcDigest.Options = std::move(opts);
+ }
+ for (cmQtAutoGenDigestQrc& qrcDigest : digest.Qrcs) {
+ // Register file at target
+ AddGeneratedSource(target, qrcDigest.RccFile, cmQtAutoGen::RCC);
+ autogenProvides.push_back(qrcDigest.RccFile);
+ // Dependencies
+ if (qrcDigest.Generated) {
+ // Add the GENERATED .qrc file to the dependencies
+ autogenDependFiles.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)) {
+ for (const std::string& fileName : qrcDigest.Resources) {
+ autogenDependFiles.insert(fileName);
+ }
} else {
cmSystemTools::Error(error.c_str());
}
}
+ // Run cmake again when .qrc file changes
+ makefile->AddCMakeDependFile(qrcDigest.QrcFile);
}
}
}
- // Convert std::set to std::vector
- const std::vector<std::string> autogenDepends(autogenDependsSet.begin(),
- autogenDependsSet.end());
- // Disable PRE_BUILD on demand
- 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;
+ // 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);
+ for (const std::string& depName : extraDeps) {
+ // Allow target and file dependencies
+ auto* depTarget = makefile->FindTargetToUse(depName);
+ if (depTarget != nullptr) {
+ autogenDependTargets.insert(depTarget->GetName());
+ } else {
+ autogenDependFiles.insert(depName);
}
}
}
}
+
+ // 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) {
+ // Cannot use PRE_BUILD with file depends
+ if (!autogenDependFiles.empty()) {
+ usePRE_BUILD = false;
+ }
+ }
+ // Create the autogen target/command
+ if (usePRE_BUILD) {
+ // Add additional autogen target dependencies to origin target
+ for (const std::string& depTarget : autogenDependTargets) {
+ target->Target->AddUtility(depTarget, makefile);
+ }
+
// 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,
+ //
+ // PRE_BUILD does not support file dependencies!
+ const std::vector<std::string> no_output;
+ const std::vector<std::string> no_deps;
+ cmCustomCommand cc(makefile, no_output, autogenProvides, no_deps,
commandLines, autogenComment.c_str(),
workingDirectory.c_str());
cc.SetEscapeOldStyle(false);
cc.SetEscapeAllowMakeVars(true);
target->Target->AddPreBuildCommand(cc);
} else {
+
+ // Add utility target dependencies to the autogen target dependencies
+ for (const std::string& depTarget : target->Target->GetUtilities()) {
+ autogenDependTargets.insert(depTarget);
+ }
+ // Add link library target dependencies to the autogen target dependencies
+ for (const auto& item : target->Target->GetOriginalLinkLibraries()) {
+ if (makefile->FindTargetToUse(item.first) != nullptr) {
+ autogenDependTargets.insert(item.first);
+ }
+ }
+
+ // Convert file dependencies std::set to std::vector
+ const std::vector<std::string> autogenDepends(autogenDependFiles.begin(),
+ autogenDependFiles.end());
+ // Create autogen target
cmTarget* autogenTarget = makefile->AddUtilityCommand(
autogenTargetName, true, workingDirectory.c_str(),
/*byproducts=*/autogenProvides, autogenDepends, commandLines, false,
autogenComment.c_str());
-
+ // Create autogen generator target
localGen->AddGeneratorTarget(
new cmGeneratorTarget(autogenTarget, localGen));
- // Set autogen target FOLDER
+ // Add additional autogen target dependencies to autogen target
+ for (const std::string& depTarget : autogenDependTargets) {
+ autogenTarget->AddUtility(depTarget, makefile);
+ }
+
+ // Set FOLDER property in autogen target
{
const char* autogenFolder =
makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER");
@@ -1009,7 +994,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);
@@ -1017,13 +1002,14 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
}
// Add autogen target to the origin target dependencies
- target->Target->AddUtility(autogenTargetName);
+ target->Target->AddUtility(autogenTargetName, makefile);
}
}
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 +1023,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 +1063,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;
@@ -1104,39 +1081,22 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(
// Open and write file
cmsys::ofstream ofs(infoFile.c_str(), std::ios::app);
if (ofs) {
+ auto OfsWriteMap = [&ofs](
+ const char* key, const std::map<std::string, std::string>& map) {
+ for (const auto& item : map) {
+ ofs << "set(" << key << "_" << item.first << " "
+ << cmOutputConverter::EscapeForCMake(item.second) << ")\n";
+ }
+ };
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 (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 (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 (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";
- }
+ OfsWriteMap("AM_CONFIG_SUFFIX", configSuffix);
+ OfsWriteMap("AM_MOC_DEFINITIONS", setup.ConfigMocDefines);
+ OfsWriteMap("AM_MOC_INCLUDES", setup.ConfigMocIncludes);
+ OfsWriteMap("AM_UIC_TARGET_OPTIONS", setup.ConfigUicOptions);
} 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..5ede9d5 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -1,15 +1,14 @@
/* 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 <assert.h>
+#include <array>
#include <list>
#include <sstream>
-#include <stdlib.h>
#include <string.h>
#include <utility>
@@ -22,7 +21,6 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmSystemTools.h"
-#include "cm_auto_ptr.hxx"
#include "cmake.h"
#if defined(__APPLE__)
@@ -37,117 +35,33 @@ static const char* SettingsKeyRcc = "AM_RCC_SETTINGS_HASH";
// -- Static functions
-inline static std::string Quoted(const std::string& text)
-{
- return cmQtAutoGeneratorCommon::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 = cmQtAutoGen::Quoted(item);
+ if (item.empty() || (cesc.size() > (item.size() + 2)) ||
(cesc.find(' ') != std::string::npos)) {
res += cesc;
} else {
- res += *cit;
+ res += item;
}
}
return res;
}
-static void InfoGet(cmMakefile* makefile, const char* key, std::string& value)
-{
- value = makefile->GetSafeDefinition(key);
-}
-
-static void InfoGet(cmMakefile* makefile, const char* key, bool& value)
-{
- value = makefile->IsOn(key);
-}
-
-static void InfoGet(cmMakefile* makefile, const char* key,
- std::vector<std::string>& list)
-{
- cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition(key), list);
-}
-
-static void InfoGetConfig(cmMakefile* makefile, const char* key,
- const std::string& config, std::string& value)
-{
- const char* valueConf = nullptr;
- {
- std::string keyConf = key;
- if (!config.empty()) {
- keyConf += "_";
- keyConf += config;
- }
- valueConf = makefile->GetDefinition(keyConf);
- }
- if (valueConf == nullptr) {
- valueConf = makefile->GetSafeDefinition(key);
- }
- value = valueConf;
-}
-
-static void InfoGetConfig(cmMakefile* makefile, const char* key,
- const std::string& config,
- std::vector<std::string>& list)
-{
- std::string value;
- InfoGetConfig(makefile, key, config, value);
- cmSystemTools::ExpandListArgument(value, list);
-}
-
-inline static bool SettingsMatch(cmMakefile* makefile, const char* key,
- const std::string& value)
-{
- return (value == makefile->GetSafeDefinition(key));
-}
-
-static void SettingAppend(std::string& str, const char* key,
- const std::string& value)
-{
- if (!value.empty()) {
- str += "set(";
- str += key;
- str += " ";
- str += cmOutputConverter::EscapeForCMake(value);
- str += ")\n";
- }
-}
-
static std::string SubDirPrefix(const std::string& fileName)
{
- std::string res(cmsys::SystemTools::GetFilenamePath(fileName));
+ std::string res(cmSystemTools::GetFilenamePath(fileName));
if (!res.empty()) {
res += '/';
}
return res;
}
-static bool FileNameIsUnique(const std::string& filePath,
- const std::map<std::string, std::string>& fileMap)
-{
- 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) {
- ++count;
- if (count > 1) {
- return false;
- }
- }
- }
- return true;
-}
-
static bool ReadAll(std::string& content, const std::string& filename)
{
bool success = false;
@@ -172,7 +86,7 @@ static bool FileAbsentOrOlder(const std::string& buildFile,
{
int result = 0;
bool success =
- cmsys::SystemTools::FileTimeCompare(buildFile, sourceFile, &result);
+ cmSystemTools::FileTimeCompare(buildFile, sourceFile, &result);
return (!success || (result <= 0));
}
@@ -182,82 +96,10 @@ static bool ListContains(const std::vector<std::string>& list,
return (std::find(list.begin(), list.end(), entry) != list.end());
}
-static std::string JoinOptionsList(const std::vector<std::string>& opts)
-{
- return cmOutputConverter::EscapeForCMake(cmJoin(opts, ";"));
-}
-
-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;
- }
- result += it->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;
- }
- }
- return result;
-}
-
-static void UicMergeOptions(std::vector<std::string>& opts,
- const std::vector<std::string>& fileOpts,
- bool isQt5)
-{
- static const char* valueOptions[] = { "tr", "translate",
- "postfix", "generator",
- "include", // Since Qt 5.3
- "g" };
- std::vector<std::string> extraOpts;
- for (std::vector<std::string>::const_iterator it = fileOpts.begin();
- it != fileOpts.end(); ++it) {
- std::vector<std::string>::iterator existingIt =
- std::find(opts.begin(), opts.end(), *it);
- if (existingIt != opts.end()) {
- const char* o = it->c_str();
- if (*o == '-') {
- ++o;
- }
- if (isQt5 && *o == '-') {
- ++o;
- }
- if (std::find_if(cmArrayBegin(valueOptions), cmArrayEnd(valueOptions),
- cmStrCmp(*it)) != cmArrayEnd(valueOptions)) {
- assert(existingIt + 1 != opts.end());
- *(existingIt + 1) = *(it + 1);
- ++it;
- }
- } else {
- extraOpts.push_back(*it);
- }
- }
- opts.insert(opts.end(), extraOpts.begin(), extraOpts.end());
-}
-
// -- Class methods
cmQtAutoGenerators::cmQtAutoGenerators()
- : Verbose(cmsys::SystemTools::HasEnv("VERBOSE"))
+ : Verbose(cmSystemTools::HasEnv("VERBOSE"))
, ColorOutput(true)
, MocSettingsChanged(false)
, MocPredefsChanged(false)
@@ -269,7 +111,7 @@ cmQtAutoGenerators::cmQtAutoGenerators()
{
std::string colorEnv;
- cmsys::SystemTools::GetEnv("COLOR", colorEnv);
+ cmSystemTools::GetEnv("COLOR", colorEnv);
if (!colorEnv.empty()) {
if (cmSystemTools::IsOn(colorEnv.c_str())) {
this->ColorOutput = true;
@@ -279,10 +121,10 @@ cmQtAutoGenerators::cmQtAutoGenerators()
}
// Moc macro filters
- this->MocMacroFilters.push_back(
- MocMacroFilter("Q_OBJECT", "[\n][ \t]*{?[ \t]*Q_OBJECT[^a-zA-Z0-9_]"));
- this->MocMacroFilters.push_back(
- MocMacroFilter("Q_GADGET", "[\n][ \t]*{?[ \t]*Q_GADGET[^a-zA-Z0-9_]"));
+ this->MocMacroFilters.emplace_back(
+ "Q_OBJECT", "[\n][ \t]*{?[ \t]*Q_OBJECT[^a-zA-Z0-9_]");
+ this->MocMacroFilters.emplace_back(
+ "Q_GADGET", "[\n][ \t]*{?[ \t]*Q_GADGET[^a-zA-Z0-9_]");
// Precompile regular expressions
this->MocRegExpInclude.compile(
@@ -305,15 +147,15 @@ bool cmQtAutoGenerators::Run(const std::string& targetDirectory,
snapshot.GetDirectory().SetCurrentBinary(targetDirectory);
snapshot.GetDirectory().SetCurrentSource(targetDirectory);
- CM_AUTO_PTR<cmMakefile> mf(new cmMakefile(&gg, snapshot));
- gg.SetCurrentMakefile(mf.get());
+ std::unique_ptr<cmMakefile> makefile(new cmMakefile(&gg, snapshot));
+ gg.SetCurrentMakefile(makefile.get());
bool success = false;
- if (this->ReadAutogenInfoFile(mf.get(), targetDirectory, config)) {
+ if (this->ReadAutogenInfoFile(makefile.get(), targetDirectory, config)) {
// Read old settings
- this->SettingsFileRead(mf.get());
+ this->SettingsFileRead(makefile.get());
// Init and run
- this->Init(mf.get());
+ this->Init(makefile.get());
if (this->RunAutogen()) {
// Write current settings
if (this->SettingsFileWrite()) {
@@ -327,44 +169,114 @@ bool cmQtAutoGenerators::Run(const std::string& targetDirectory,
bool cmQtAutoGenerators::MocDependFilterPush(const std::string& key,
const std::string& regExp)
{
- bool success = false;
+ std::string error;
if (!key.empty()) {
if (!regExp.empty()) {
- MocDependFilter filter;
- filter.key = key;
- if (filter.regExp.compile(regExp)) {
- this->MocDependFilters.push_back(filter);
- success = true;
+ KeyRegExp filter;
+ filter.Key = key;
+ if (filter.RegExp.compile(regExp)) {
+ this->MocDependFilters.push_back(std::move(filter));
} else {
- this->LogError("AutoMoc: Error in AUTOMOC_DEPEND_FILTERS: Compiling "
- "regular expression failed.\nKey: " +
- Quoted(key) + "\nExp.: " + Quoted(regExp));
+ error = "Regular expression compiling failed";
}
} else {
- this->LogError("AutoMoc: Error in AUTOMOC_DEPEND_FILTERS: Regular "
- "expression is empty");
+ error = "Regular expression is empty";
}
} else {
- this->LogError("AutoMoc: Error in AUTOMOC_DEPEND_FILTERS: Key is empty");
+ error = "Key is empty";
}
- return success;
+ if (!error.empty()) {
+ std::string emsg = "AUTOMOC_DEPEND_FILTERS: ";
+ emsg += error;
+ emsg += "\n";
+ emsg += " Key: ";
+ emsg += cmQtAutoGen::Quoted(key);
+ emsg += "\n";
+ emsg += " RegExp: ";
+ emsg += cmQtAutoGen::Quoted(regExp);
+ emsg += "\n";
+ this->LogError(cmQtAutoGen::MOC, emsg);
+ return false;
+ }
+ return true;
}
bool cmQtAutoGenerators::ReadAutogenInfoFile(
cmMakefile* makefile, const std::string& targetDirectory,
const std::string& config)
{
+ // Lambdas
+ auto InfoGet = [makefile](const char* key) {
+ return makefile->GetSafeDefinition(key);
+ };
+ auto InfoGetBool = [makefile](const char* key) {
+ return makefile->IsOn(key);
+ };
+ auto InfoGetList = [makefile](const char* key) -> std::vector<std::string> {
+ std::vector<std::string> list;
+ cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition(key), list);
+ return list;
+ };
+ auto InfoGetLists =
+ [makefile](const char* key) -> std::vector<std::vector<std::string>> {
+ std::vector<std::vector<std::string>> lists;
+ {
+ const std::string value = makefile->GetSafeDefinition(key);
+ std::string::size_type pos = 0;
+ while (pos < value.size()) {
+ std::string::size_type next = value.find(cmQtAutoGen::listSep, pos);
+ std::string::size_type length =
+ (next != std::string::npos) ? next - pos : value.size() - pos;
+ // Remove enclosing braces
+ if (length >= 2) {
+ std::string::const_iterator itBeg = value.begin() + (pos + 1);
+ std::string::const_iterator itEnd = itBeg + (length - 2);
+ {
+ std::string subValue(itBeg, itEnd);
+ std::vector<std::string> list;
+ cmSystemTools::ExpandListArgument(subValue, list);
+ lists.push_back(std::move(list));
+ }
+ }
+ pos += length;
+ pos += cmQtAutoGen::listSep.size();
+ }
+ }
+ return lists;
+ };
+ auto InfoGetConfig = [makefile, &config](const char* key) -> std::string {
+ const char* valueConf = nullptr;
+ {
+ std::string keyConf = key;
+ if (!config.empty()) {
+ keyConf += '_';
+ keyConf += config;
+ }
+ valueConf = makefile->GetDefinition(keyConf);
+ }
+ if (valueConf == nullptr) {
+ valueConf = makefile->GetSafeDefinition(key);
+ }
+ return std::string(valueConf);
+ };
+ auto InfoGetConfigList =
+ [&InfoGetConfig](const char* key) -> std::vector<std::string> {
+ std::vector<std::string> list;
+ cmSystemTools::ExpandListArgument(InfoGetConfig(key), list);
+ return list;
+ };
+
std::string filename(cmSystemTools::CollapseFullPath(targetDirectory));
cmSystemTools::ConvertToUnixSlashes(filename);
filename += "/AutogenInfo.cmake";
if (!makefile->ReadListFile(filename.c_str())) {
- this->LogError("AutoGen: Error processing file: " + filename);
+ this->LogFileError(cmQtAutoGen::GEN, filename, "File processing failed");
return false;
}
// -- Meta
- InfoGetConfig(makefile, "AM_CONFIG_SUFFIX", config, this->ConfigSuffix);
+ this->ConfigSuffix = InfoGetConfig("AM_CONFIG_SUFFIX");
// - Old settings file
{
@@ -376,41 +288,39 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
}
// - Files and directories
- InfoGet(makefile, "AM_CMAKE_SOURCE_DIR", this->ProjectSourceDir);
- InfoGet(makefile, "AM_CMAKE_BINARY_DIR", this->ProjectBinaryDir);
- InfoGet(makefile, "AM_CMAKE_CURRENT_SOURCE_DIR", this->CurrentSourceDir);
- InfoGet(makefile, "AM_CMAKE_CURRENT_BINARY_DIR", this->CurrentBinaryDir);
- InfoGet(makefile, "AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE",
- this->IncludeProjectDirsBefore);
- InfoGet(makefile, "AM_BUILD_DIR", this->AutogenBuildDir);
+ this->ProjectSourceDir = InfoGet("AM_CMAKE_SOURCE_DIR");
+ this->ProjectBinaryDir = InfoGet("AM_CMAKE_BINARY_DIR");
+ this->CurrentSourceDir = InfoGet("AM_CMAKE_CURRENT_SOURCE_DIR");
+ this->CurrentBinaryDir = InfoGet("AM_CMAKE_CURRENT_BINARY_DIR");
+ this->IncludeProjectDirsBefore =
+ InfoGetBool("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE");
+ this->AutogenBuildDir = InfoGet("AM_BUILD_DIR");
if (this->AutogenBuildDir.empty()) {
- this->LogError("AutoGen: Error: Missing autogen build directory ");
+ this->LogFileError(cmQtAutoGen::GEN, filename,
+ "Autogen build directory missing");
return false;
}
- InfoGet(makefile, "AM_SOURCES", this->Sources);
- InfoGet(makefile, "AM_HEADERS", this->Headers);
+ this->Sources = InfoGetList("AM_SOURCES");
+ this->Headers = InfoGetList("AM_HEADERS");
// - Qt environment
- InfoGet(makefile, "AM_QT_VERSION_MAJOR", this->QtMajorVersion);
- if (this->QtMajorVersion.empty()) {
- InfoGet(makefile, "AM_Qt5Core_VERSION_MAJOR", this->QtMajorVersion);
- }
- InfoGet(makefile, "AM_QT_MOC_EXECUTABLE", this->MocExecutable);
- InfoGet(makefile, "AM_QT_UIC_EXECUTABLE", this->UicExecutable);
- InfoGet(makefile, "AM_QT_RCC_EXECUTABLE", this->RccExecutable);
+ this->QtMajorVersion = InfoGet("AM_QT_VERSION_MAJOR");
+ this->QtMinorVersion = InfoGet("AM_QT_VERSION_MINOR");
+ this->MocExecutable = InfoGet("AM_QT_MOC_EXECUTABLE");
+ this->UicExecutable = InfoGet("AM_QT_UIC_EXECUTABLE");
+ this->RccExecutable = InfoGet("AM_QT_RCC_EXECUTABLE");
// Check Qt version
if ((this->QtMajorVersion != "4") && (this->QtMajorVersion != "5")) {
- this->LogError("AutoGen: Error: Unsupported Qt version: " +
- Quoted(this->QtMajorVersion));
+ this->LogFileError(cmQtAutoGen::GEN, filename, "Unsupported Qt version: " +
+ cmQtAutoGen::Quoted(this->QtMajorVersion));
return false;
}
// - Moc
if (this->MocEnabled()) {
- InfoGet(makefile, "AM_MOC_SKIP", this->MocSkipList);
- InfoGetConfig(makefile, "AM_MOC_DEFINITIONS", config,
- this->MocDefinitions);
+ this->MocSkipList = InfoGetList("AM_MOC_SKIP");
+ this->MocDefinitions = InfoGetConfigList("AM_MOC_DEFINITIONS");
#ifdef _WIN32
{
const std::string win32("WIN32");
@@ -419,22 +329,20 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
}
}
#endif
- InfoGetConfig(makefile, "AM_MOC_INCLUDES", config, this->MocIncludePaths);
- InfoGet(makefile, "AM_MOC_OPTIONS", this->MocOptions);
- InfoGet(makefile, "AM_MOC_RELAXED_MODE", this->MocRelaxedMode);
+ this->MocIncludePaths = InfoGetConfigList("AM_MOC_INCLUDES");
+ this->MocOptions = InfoGetList("AM_MOC_OPTIONS");
+ this->MocRelaxedMode = InfoGetBool("AM_MOC_RELAXED_MODE");
{
- 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_]"));
+ const std::vector<std::string> MocMacroNames =
+ InfoGetList("AM_MOC_MACRO_NAMES");
+ for (const std::string& item : MocMacroNames) {
+ this->MocMacroFilters.emplace_back(
+ item, ("[^a-zA-Z0-9_]" + item).append("[^a-zA-Z0-9_]"));
}
}
{
- std::vector<std::string> mocDependFilters;
- InfoGet(makefile, "AM_MOC_DEPEND_FILTERS", mocDependFilters);
+ const std::vector<std::string> mocDependFilters =
+ InfoGetList("AM_MOC_DEPEND_FILTERS");
// Insert Q_PLUGIN_METADATA dependency filter
if (this->QtMajorVersion != "4") {
this->MocDependFilterPush("Q_PLUGIN_METADATA",
@@ -443,49 +351,47 @@ 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;
}
}
} else {
- this->LogError(
- "AutoMoc: Error: AUTOMOC_DEPEND_FILTERS list size is not "
- "a multiple of 2 in:\n" +
- Quoted(filename));
+ this->LogFileError(
+ cmQtAutoGen::MOC, filename,
+ "AUTOMOC_DEPEND_FILTERS list size is not a multiple of 2");
return false;
}
}
- InfoGet(makefile, "AM_MOC_PREDEFS_CMD", this->MocPredefsCmd);
+ this->MocPredefsCmd = InfoGetList("AM_MOC_PREDEFS_CMD");
}
// - Uic
if (this->UicEnabled()) {
- InfoGet(makefile, "AM_UIC_SKIP", this->UicSkipList);
- InfoGet(makefile, "AM_UIC_SEARCH_PATHS", this->UicSearchPaths);
- InfoGetConfig(makefile, "AM_UIC_TARGET_OPTIONS", config,
- this->UicTargetOptions);
+ this->UicSkipList = InfoGetList("AM_UIC_SKIP");
+ this->UicSearchPaths = InfoGetList("AM_UIC_SEARCH_PATHS");
+ this->UicTargetOptions = InfoGetConfigList("AM_UIC_TARGET_OPTIONS");
{
- std::vector<std::string> uicFilesVec;
- std::vector<std::string> uicOptionsVec;
- InfoGet(makefile, "AM_UIC_OPTIONS_FILES", uicFilesVec);
- InfoGet(makefile, "AM_UIC_OPTIONS_OPTIONS", uicOptionsVec);
+ auto sources = InfoGetList("AM_UIC_OPTIONS_FILES");
+ auto options = InfoGetLists("AM_UIC_OPTIONS_OPTIONS");
// Compare list sizes
- if (uicFilesVec.size() == uicOptionsVec.size()) {
- for (std::vector<std::string>::iterator
- fileIt = uicFilesVec.begin(),
- optionIt = uicOptionsVec.begin();
- fileIt != uicFilesVec.end(); ++fileIt, ++optionIt) {
- cmSystemTools::ReplaceString(*optionIt,
- cmQtAutoGeneratorCommon::listSep, ";");
- this->UicOptions[*fileIt] = *optionIt;
+ if (sources.size() == options.size()) {
+ auto fitEnd = sources.cend();
+ auto fit = sources.begin();
+ auto oit = options.begin();
+ while (fit != fitEnd) {
+ this->UicOptions[*fit] = std::move(*oit);
+ ++fit;
+ ++oit;
}
} else {
- this->LogError(
- "AutoGen: Error: Uic files/options lists size missmatch in:\n" +
- Quoted(filename));
+ std::ostringstream ost;
+ ost << "files/options lists sizes missmatch (" << sources.size() << "/"
+ << options.size() << ")";
+ this->LogFileError(cmQtAutoGen::UIC, filename, ost.str());
return false;
}
}
@@ -493,53 +399,48 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
// - Rcc
if (this->RccEnabled()) {
- InfoGet(makefile, "AM_RCC_SOURCES", this->RccSources);
- // File options
- {
- std::vector<std::string> rccFilesVec;
- std::vector<std::string> rccOptionsVec;
- InfoGet(makefile, "AM_RCC_OPTIONS_FILES", rccFilesVec);
- InfoGet(makefile, "AM_RCC_OPTIONS_OPTIONS", rccOptionsVec);
- if (rccFilesVec.size() == rccOptionsVec.size()) {
- for (std::vector<std::string>::iterator
- fileIt = rccFilesVec.begin(),
- optionIt = rccOptionsVec.begin();
- fileIt != rccFilesVec.end(); ++fileIt, ++optionIt) {
- // Replace item separator
- cmSystemTools::ReplaceString(*optionIt,
- cmQtAutoGeneratorCommon::listSep, ";");
- this->RccOptions[*fileIt] = *optionIt;
- }
- } else {
- this->LogError(
- "AutoGen: Error: RCC files/options lists size missmatch in:\n" +
- Quoted(filename));
- return false;
- }
- }
// File lists
+ auto sources = InfoGetList("AM_RCC_SOURCES");
+ auto builds = InfoGetList("AM_RCC_BUILDS");
+ auto options = InfoGetLists("AM_RCC_OPTIONS");
+ auto inputs = InfoGetLists("AM_RCC_INPUTS");
+
+ if (sources.size() != builds.size()) {
+ std::ostringstream ost;
+ ost << "sources, builds lists sizes missmatch (" << sources.size() << "/"
+ << builds.size() << ")";
+ this->LogFileError(cmQtAutoGen::RCC, filename, ost.str());
+ return false;
+ }
+ if (sources.size() != options.size()) {
+ std::ostringstream ost;
+ ost << "sources, options lists sizes missmatch (" << sources.size()
+ << "/" << options.size() << ")";
+ this->LogFileError(cmQtAutoGen::RCC, filename, ost.str());
+ return false;
+ }
+ if (sources.size() != inputs.size()) {
+ std::ostringstream ost;
+ ost << "sources, inputs lists sizes missmatch (" << sources.size() << "/"
+ << inputs.size() << ")";
+ this->LogFileError(cmQtAutoGen::RCC, filename, ost.str());
+ return false;
+ }
+
{
- std::vector<std::string> rccInputLists;
- InfoGet(makefile, "AM_RCC_INPUTS", rccInputLists);
- if (this->RccSources.size() == rccInputLists.size()) {
- for (std::vector<std::string>::iterator
- fileIt = this->RccSources.begin(),
- inputIt = rccInputLists.begin();
- fileIt != this->RccSources.end(); ++fileIt, ++inputIt) {
- // Remove braces
- *inputIt = inputIt->substr(1, inputIt->size() - 2);
- // Replace item separator
- cmSystemTools::ReplaceString(*inputIt,
- cmQtAutoGeneratorCommon::listSep, ";");
- std::vector<std::string> rccInputFiles;
- cmSystemTools::ExpandListArgument(*inputIt, rccInputFiles);
- this->RccInputs[*fileIt] = rccInputFiles;
- }
- } else {
- this->LogError(
- "AutoGen: Error: RCC sources/inputs lists size missmatch in:\n" +
- Quoted(filename));
- return false;
+ auto srcItEnd = sources.end();
+ auto srcIt = sources.begin();
+ auto bldIt = builds.begin();
+ auto optIt = options.begin();
+ auto inpIt = inputs.begin();
+ while (srcIt != srcItEnd) {
+ this->RccJobs.push_back(RccJob{ std::move(*srcIt), std::move(*bldIt),
+ std::move(*optIt),
+ std::move(*inpIt) });
+ ++srcIt;
+ ++bldIt;
+ ++optIt;
+ ++inpIt;
}
}
}
@@ -557,15 +458,15 @@ void cmQtAutoGenerators::SettingsFileRead(cmMakefile* makefile)
std::string str;
str += this->MocExecutable;
str += sep;
- str += JoinOptionsList(this->MocDefinitions);
+ str += cmJoin(this->MocDefinitions, ";");
str += sep;
- str += JoinOptionsList(this->MocIncludePaths);
+ str += cmJoin(this->MocIncludePaths, ";");
str += sep;
- str += JoinOptionsList(this->MocOptions);
+ str += cmJoin(this->MocOptions, ";");
str += sep;
str += this->IncludeProjectDirsBefore ? "TRUE" : "FALSE";
str += sep;
- str += JoinOptionsList(this->MocPredefsCmd);
+ str += cmJoin(this->MocPredefsCmd, ";");
str += sep;
this->SettingsStringMoc = crypt.HashString(str);
}
@@ -573,17 +474,27 @@ void cmQtAutoGenerators::SettingsFileRead(cmMakefile* makefile)
std::string str;
str += this->UicExecutable;
str += sep;
- str += JoinOptionsList(this->UicTargetOptions);
- str += sep;
- str += JoinOptionsMap(this->UicOptions);
+ str += cmJoin(this->UicTargetOptions, ";");
+ for (const auto& item : this->UicOptions) {
+ str += sep;
+ str += item.first;
+ str += sep;
+ str += cmJoin(item.second, ";");
+ }
str += sep;
this->SettingsStringUic = crypt.HashString(str);
}
if (this->RccEnabled()) {
std::string str;
str += this->RccExecutable;
- str += sep;
- str += JoinOptionsMap(this->RccOptions);
+ for (const RccJob& rccJob : this->RccJobs) {
+ str += sep;
+ str += rccJob.QrcFile;
+ str += sep;
+ str += rccJob.RccFile;
+ str += sep;
+ str += cmJoin(rccJob.Options, ";");
+ }
str += sep;
this->SettingsStringRcc = crypt.HashString(str);
}
@@ -591,14 +502,19 @@ void cmQtAutoGenerators::SettingsFileRead(cmMakefile* makefile)
// Read old settings
if (makefile->ReadListFile(this->SettingsFile.c_str())) {
- if (!SettingsMatch(makefile, SettingsKeyMoc, this->SettingsStringMoc)) {
- this->MocSettingsChanged = true;
- }
- if (!SettingsMatch(makefile, SettingsKeyUic, this->SettingsStringUic)) {
- this->UicSettingsChanged = true;
- }
- if (!SettingsMatch(makefile, SettingsKeyRcc, this->SettingsStringRcc)) {
- this->RccSettingsChanged = true;
+ {
+ auto SMatch = [makefile](const char* key, const std::string& value) {
+ return (value == makefile->GetSafeDefinition(key));
+ };
+ if (!SMatch(SettingsKeyMoc, this->SettingsStringMoc)) {
+ this->MocSettingsChanged = true;
+ }
+ if (!SMatch(SettingsKeyUic, this->SettingsStringUic)) {
+ this->UicSettingsChanged = true;
+ }
+ if (!SMatch(SettingsKeyRcc, this->SettingsStringRcc)) {
+ this->RccSettingsChanged = true;
+ }
}
// In case any setting changed remove the old settings file.
// This triggers a full rebuild on the next run if the current
@@ -620,18 +536,28 @@ bool cmQtAutoGenerators::SettingsFileWrite()
// Only write if any setting changed
if (this->AnySettingsChanged()) {
if (this->Verbose) {
- this->LogInfo("AutoGen: Writing settings file " +
- Quoted(this->SettingsFile));
+ this->LogInfo(cmQtAutoGen::GEN, "Writing settings file " +
+ cmQtAutoGen::Quoted(this->SettingsFile));
}
// Compose settings file content
std::string settings;
- SettingAppend(settings, SettingsKeyMoc, this->SettingsStringMoc);
- SettingAppend(settings, SettingsKeyUic, this->SettingsStringUic);
- SettingAppend(settings, SettingsKeyRcc, this->SettingsStringRcc);
+ {
+ auto SettingAppend = [&settings](const char* key,
+ const std::string& value) {
+ settings += "set(";
+ settings += key;
+ settings += " ";
+ settings += cmOutputConverter::EscapeForCMake(value);
+ settings += ")\n";
+ };
+ SettingAppend(SettingsKeyMoc, this->SettingsStringMoc);
+ SettingAppend(SettingsKeyUic, this->SettingsStringUic);
+ SettingAppend(SettingsKeyRcc, this->SettingsStringRcc);
+ }
// Write settings file
- if (!this->FileWrite("AutoGen", this->SettingsFile, settings)) {
- this->LogError("AutoGen: Error: Could not write old settings file " +
- Quoted(this->SettingsFile));
+ if (!this->FileWrite(cmQtAutoGen::GEN, this->SettingsFile, settings)) {
+ this->LogFileError(cmQtAutoGen::GEN, this->SettingsFile,
+ "File writing failed");
// Remove old settings file to trigger a full rebuild on the next run
cmSystemTools::RemoveFile(this->SettingsFile);
success = false;
@@ -679,14 +605,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,26 +628,22 @@ 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")) {
// Go up twice to get to the framework root
std::vector<std::string> pathComponents;
- cmsys::SystemTools::SplitPath(path, pathComponents);
- std::string frameworkPath = cmsys::SystemTools::JoinPath(
+ cmSystemTools::SplitPath(path, pathComponents);
+ std::string frameworkPath = cmSystemTools::JoinPath(
pathComponents.begin(), pathComponents.end() - 2);
frameworkPaths.insert(frameworkPath);
}
}
// 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);
}
}
}
@@ -740,9 +662,9 @@ bool cmQtAutoGenerators::RunAutogen()
{
const std::string incDirAbs = cmSystemTools::CollapseCombinedPath(
this->AutogenBuildDir, this->AutogenIncludeDir);
- if (!cmsys::SystemTools::MakeDirectory(incDirAbs)) {
- this->LogError("AutoGen: Error: Could not create include directory " +
- Quoted(incDirAbs));
+ if (!cmSystemTools::MakeDirectory(incDirAbs)) {
+ this->LogFileError(cmQtAutoGen::GEN, incDirAbs,
+ "Could not create directory");
return false;
}
}
@@ -757,28 +679,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,17 +724,14 @@ 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 (KeyRegExp& filter : this->MocMacroFilters) {
// Run a simple find string operation before the expensive
// regular expression check
- if (contentText.find(filter.first) != std::string::npos) {
- if (filter.second.find(contentText)) {
+ if (contentText.find(filter.Key) != std::string::npos) {
+ if (filter.RegExp.find(contentText)) {
// Return macro name on demand
if (macroName != nullptr) {
- *macroName = filter.first;
+ *macroName = filter.Key;
}
return true;
}
@@ -830,35 +744,33 @@ 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 (KeyRegExp& filter : this->MocDependFilters) {
// Run a simple find string operation before the expensive
// regular expression check
- if (contentText.find(filter.key) != std::string::npos) {
+ if (contentText.find(filter.Key) != std::string::npos) {
// Run regular expression check loop
const std::string sourcePath = SubDirPrefix(absFilename);
const char* contentChars = contentText.c_str();
- while (filter.regExp.find(contentChars)) {
+ while (filter.RegExp.find(contentChars)) {
// Evaluate match
- const std::string match = filter.regExp.match(1);
+ const std::string match = filter.RegExp.match(1);
if (!match.empty()) {
// Find the dependency file
std::string incFile;
if (this->MocFindIncludedFile(incFile, sourcePath, match)) {
mocDepends[absFilename].insert(incFile);
if (this->Verbose) {
- this->LogInfo("AutoMoc: Found dependency:\n " +
- Quoted(absFilename) + "\n " + Quoted(incFile));
+ this->LogInfo(cmQtAutoGen::MOC, "Found dependency:\n " +
+ cmQtAutoGen::Quoted(absFilename) + "\n " +
+ cmQtAutoGen::Quoted(incFile));
}
} else {
- this->LogWarning("AutoMoc: Warning: " + Quoted(absFilename) +
- "\n" + "Could not find dependency file " +
- Quoted(match));
+ this->LogFileWarning(cmQtAutoGen::MOC, absFilename,
+ "Could not find dependency file " +
+ cmQtAutoGen::Quoted(match));
}
}
- contentChars += filter.regExp.end();
+ contentChars += filter.RegExp.end();
}
}
}
@@ -916,15 +828,10 @@ bool cmQtAutoGenerators::ParseSourceFile(
this->UicParseContent(absFilename, contentText, uisIncluded);
}
} else {
- std::ostringstream ost;
- ost << "AutoGen: Warning: The file is empty:\n"
- << Quoted(absFilename) << "\n";
- this->LogWarning(ost.str());
+ this->LogFileWarning(cmQtAutoGen::GEN, absFilename, "The file is empty");
}
} else {
- std::ostringstream ost;
- ost << "AutoGen: Error: Could not read file:\n" << Quoted(absFilename);
- this->LogError(ost.str());
+ this->LogFileError(cmQtAutoGen::GEN, absFilename, "Could not read file");
}
return success;
}
@@ -934,7 +841,7 @@ void cmQtAutoGenerators::UicParseContent(
std::map<std::string, std::vector<std::string>>& uisIncluded)
{
if (this->Verbose) {
- this->LogInfo("AutoUic: Checking " + absFilename);
+ this->LogInfo(cmQtAutoGen::UIC, "Checking " + absFilename);
}
const char* contentChars = contentText.c_str();
@@ -946,6 +853,36 @@ void cmQtAutoGenerators::UicParseContent(
}
}
+std::string cmQtAutoGenerators::MocMacroNamesString() const
+{
+ std::string res;
+ const auto itB = this->MocMacroFilters.cbegin();
+ const auto itE = this->MocMacroFilters.cend();
+ const auto itL = itE - 1;
+ auto itC = itB;
+ for (; itC != itE; ++itC) {
+ // Separator
+ if (itC != itB) {
+ if (itC != itL) {
+ res += ", ";
+ } else {
+ res += " or ";
+ }
+ }
+ // Key
+ res += itC->Key;
+ }
+ return res;
+}
+
+std::string cmQtAutoGenerators::MocHeaderSuffixesString() const
+{
+ std::string res = ".{";
+ res += cmJoin(this->HeaderExtensions, ",");
+ res += "}";
+ return res;
+}
+
/**
* @return True on success
*/
@@ -955,15 +892,15 @@ bool cmQtAutoGenerators::MocParseSourceContent(
std::map<std::string, std::set<std::string>>& mocDepends, bool relaxed)
{
if (this->Verbose) {
- this->LogInfo("AutoMoc: Checking " + absFilename);
+ this->LogInfo(cmQtAutoGen::MOC, "Checking " + absFilename);
}
- const std::string scannedFileAbsPath = SubDirPrefix(absFilename);
- const std::string scannedFileBasename =
- cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename);
+ const std::string scanFileDir = SubDirPrefix(absFilename);
+ const std::string scanFileBase =
+ cmSystemTools::GetFilenameWithoutLastExtension(absFilename);
- std::string macroName;
- const bool requiresMoc = this->MocRequired(contentText, &macroName);
+ std::string selfMacroName;
+ const bool selfRequiresMoc = this->MocRequired(contentText, &selfMacroName);
bool ownDotMocIncluded = false;
std::string ownMocUnderscoreInclude;
std::string ownMocUnderscoreHeader;
@@ -977,120 +914,132 @@ bool cmQtAutoGenerators::MocParseSourceContent(
while (this->MocRegExpInclude.find(contentChars)) {
const std::string incString = this->MocRegExpInclude.match(1);
// Basename of the moc include
- const std::string incSubDir(SubDirPrefix(incString));
- const std::string incBasename =
- cmsys::SystemTools::GetFilenameWithoutLastExtension(incString);
+ const std::string incDir(SubDirPrefix(incString));
+ const std::string incBase =
+ cmSystemTools::GetFilenameWithoutLastExtension(incString);
// If the moc include is of the moc_foo.cpp style we expect
// the Q_OBJECT class declaration in a header file.
// If the moc include is of the foo.moc style we need to look for
// a Q_OBJECT macro in the current source file, if it contains the
// macro we generate the moc file from the source file.
- if (cmHasLiteralPrefix(incBasename, "moc_")) {
+ if (cmHasLiteralPrefix(incBase, "moc_")) {
// Include: moc_FOO.cxx
// Remove the moc_ part
- const std::string incRealBasename = incBasename.substr(4);
+ const std::string incRealBase = incBase.substr(4);
const std::string headerToMoc =
- this->MocFindHeader(scannedFileAbsPath, incSubDir + incRealBasename);
+ this->MocFindHeader(scanFileDir, incDir + incRealBase);
if (!headerToMoc.empty()) {
if (!this->MocSkip(headerToMoc)) {
// Register moc job
mocsIncluded[headerToMoc] = incString;
this->MocFindDepends(headerToMoc, contentText, mocDepends);
// Store meta information for relaxed mode
- if (relaxed && (incRealBasename == scannedFileBasename)) {
+ if (relaxed && (incRealBase == scanFileBase)) {
ownMocUnderscoreInclude = incString;
ownMocUnderscoreHeader = headerToMoc;
}
}
} else {
std::ostringstream ost;
- ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n"
- << "The file includes the moc file " << Quoted(incString)
- << ", but could not find header "
- << Quoted(incRealBasename + "{" +
- JoinExts(this->HeaderExtensions) + "}");
- ;
- this->LogError(ost.str());
+ ost << "The file includes the moc file "
+ << cmQtAutoGen::Quoted(incString)
+ << ", but could not find header ";
+ ost << cmQtAutoGen::Quoted(incRealBase +
+ this->MocHeaderSuffixesString());
+ this->LogFileError(cmQtAutoGen::MOC, absFilename, ost.str());
return false;
}
} else {
// Include: FOO.moc
+ bool ownDotMoc = (incBase == scanFileBase);
std::string fileToMoc;
if (relaxed) {
// Mode: Relaxed
- if (requiresMoc && (incBasename == scannedFileBasename)) {
+ if (selfRequiresMoc && ownDotMoc) {
// Include self
fileToMoc = absFilename;
ownDotMocIncluded = true;
} else {
// In relaxed mode try to find a header instead but issue a warning
const std::string headerToMoc =
- this->MocFindHeader(scannedFileAbsPath, incSubDir + incBasename);
+ this->MocFindHeader(scanFileDir, incDir + incBase);
if (!headerToMoc.empty()) {
if (!this->MocSkip(headerToMoc)) {
// This is for KDE4 compatibility:
fileToMoc = headerToMoc;
- if (!requiresMoc && (incBasename == scannedFileBasename)) {
- std::ostringstream ost;
- ost
- << "AutoMoc: Warning: " << Quoted(absFilename) << "\n"
- << "The file includes the moc file " << Quoted(incString)
- << ", but does not contain a Q_OBJECT or Q_GADGET macro.\n"
- << "Running moc on " << Quoted(headerToMoc) << "!\n"
- << "Include " << Quoted("moc_" + incBasename + ".cpp")
- << " for a compatibility with strict mode (see "
- "CMAKE_AUTOMOC_RELAXED_MODE).\n";
- this->LogWarning(ost.str());
+
+ auto quoted_inc = cmQtAutoGen::Quoted(incString);
+ auto quoted_header = cmQtAutoGen::Quoted(headerToMoc);
+ auto quoted_base =
+ cmQtAutoGen::Quoted("moc_" + incBase + ".cpp");
+ if (!selfRequiresMoc) {
+ if (ownDotMoc) {
+ std::ostringstream ost;
+ ost << "The file includes the moc file " << quoted_inc
+ << ", but does not contain a "
+ << this->MocMacroNamesString() << " macro.\n"
+ << "Running moc on\n"
+ << " " << quoted_header << "!\n"
+ << "Better include " << quoted_base
+ << " for a compatibility with strict mode.\n"
+ "(CMAKE_AUTOMOC_RELAXED_MODE warning)\n";
+ this->LogFileWarning(cmQtAutoGen::MOC, absFilename,
+ ost.str());
+ } else if (!ownDotMoc) {
+ std::ostringstream ost;
+ ost << "The file includes the moc file " << quoted_inc
+ << " instead of " << quoted_base << ".\n";
+ ost << "Running moc on\n"
+ << " " << quoted_header << "!\n"
+ << "Better include " << quoted_base
+ << " for compatibility with strict mode.\n"
+ "(CMAKE_AUTOMOC_RELAXED_MODE warning)\n";
+ this->LogFileWarning(cmQtAutoGen::MOC, absFilename,
+ ost.str());
+ }
} else {
- std::ostringstream ost;
- ost << "AutoMoc: Warning: " << Quoted(absFilename) << "\n"
- << "The file includes the moc file " << Quoted(incString)
- << " instead of "
- << Quoted("moc_" + incBasename + ".cpp") << ".\n"
- << "Running moc on " << Quoted(headerToMoc) << "!\n"
- << "Include " << Quoted("moc_" + incBasename + ".cpp")
- << " for compatibility with strict mode (see "
- "CMAKE_AUTOMOC_RELAXED_MODE).\n";
- this->LogWarning(ost.str());
+ if (!ownDotMoc) {
+ // Handled further down
+ }
}
}
} else {
std::ostringstream ost;
- ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n"
- << "The file includes the moc file " << Quoted(incString)
+ ost << "The file includes the moc file "
+ << cmQtAutoGen::Quoted(incString)
<< ", which seems to be the moc file from a different "
"source file. CMake also could not find a matching "
"header.";
- this->LogError(ost.str());
+ this->LogFileError(cmQtAutoGen::MOC, absFilename, ost.str());
return false;
}
}
} else {
// Mode: Strict
- if (incBasename == scannedFileBasename) {
+ if (ownDotMoc) {
// Include self
fileToMoc = absFilename;
ownDotMocIncluded = true;
// Accept but issue a warning if moc isn't required
- if (!requiresMoc) {
+ if (!selfRequiresMoc) {
std::ostringstream ost;
- ost << "AutoMoc: Warning: " << Quoted(absFilename) << "\n"
- << "The file includes the moc file " << Quoted(incString)
- << ", but does not contain a Q_OBJECT or Q_GADGET "
- "macro.";
- this->LogWarning(ost.str());
+ ost << "The file includes the moc file "
+ << cmQtAutoGen::Quoted(incString)
+ << ", but does not contain a " << this->MocMacroNamesString()
+ << " macro.";
+ this->LogFileWarning(cmQtAutoGen::MOC, absFilename, ost.str());
}
} else {
// Don't allow FOO.moc include other than self in strict mode
std::ostringstream ost;
- ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n"
- << "The file includes the moc file " << Quoted(incString)
+ ost << "The file includes the moc file "
+ << cmQtAutoGen::Quoted(incString)
<< ", which seems to be the moc file from a different "
"source file. This is not supported. Include "
- << Quoted(scannedFileBasename + ".moc")
+ << cmQtAutoGen::Quoted(scanFileBase + ".moc")
<< " to run moc on this source file.";
- this->LogError(ost.str());
+ this->LogFileError(cmQtAutoGen::MOC, absFilename, ost.str());
return false;
}
}
@@ -1104,24 +1053,26 @@ bool cmQtAutoGenerators::MocParseSourceContent(
}
}
- if (requiresMoc && !ownDotMocIncluded) {
- // In this case, check whether the scanned file itself contains a Q_OBJECT.
+ if (selfRequiresMoc && !ownDotMocIncluded) {
+ // In this case, check whether the scanned file itself contains a
+ // Q_OBJECT.
// If this is the case, the moc_foo.cpp should probably be generated from
// foo.cpp instead of foo.h, because otherwise it won't build.
// But warn, since this is not how it is supposed to be used.
if (relaxed && !ownMocUnderscoreInclude.empty()) {
// This is for KDE4 compatibility:
std::ostringstream ost;
- ost << "AutoMoc: Warning: " << Quoted(absFilename) << "\n"
- << "The file contains a " << macroName
+ ost << "The file contains a " << selfMacroName
<< " macro, but does not include "
- << Quoted(scannedFileBasename + ".moc") << ", but instead includes "
- << Quoted(ownMocUnderscoreInclude) << ".\n"
- << "Running moc on " << Quoted(absFilename) << "!\n"
- << "Better include " << Quoted(scannedFileBasename + ".moc")
- << " for compatibility with strict mode (see "
- "CMAKE_AUTOMOC_RELAXED_MODE).";
- this->LogWarning(ost.str());
+ << cmQtAutoGen::Quoted(scanFileBase + ".moc")
+ << ". Instead it includes "
+ << cmQtAutoGen::Quoted(ownMocUnderscoreInclude) << ".\n"
+ << "Running moc on\n"
+ << " " << cmQtAutoGen::Quoted(absFilename) << "!\n"
+ << "Better include " << cmQtAutoGen::Quoted(scanFileBase + ".moc")
+ << " for compatibility with strict mode.\n"
+ "(CMAKE_AUTOMOC_RELAXED_MODE warning)";
+ this->LogFileWarning(cmQtAutoGen::MOC, absFilename, ost.str());
// Use scanned source file instead of scanned header file as moc source
mocsIncluded[absFilename] = ownMocUnderscoreInclude;
@@ -1131,13 +1082,12 @@ bool cmQtAutoGenerators::MocParseSourceContent(
} else {
// Otherwise always error out since it will not compile:
std::ostringstream ost;
- ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n"
- << "The file contains a " << macroName
+ ost << "The file contains a " << selfMacroName
<< " macro, but does not include "
- << Quoted(scannedFileBasename + ".moc") << "!\n"
+ << cmQtAutoGen::Quoted(scanFileBase + ".moc") << "!\n"
<< "Consider adding the include or enabling SKIP_AUTOMOC for this "
"file.";
- this->LogError(ost.str());
+ this->LogFileError(cmQtAutoGen::MOC, absFilename, ost.str());
return false;
}
}
@@ -1152,7 +1102,7 @@ void cmQtAutoGenerators::MocParseHeaderContent(
{
// Log
if (this->Verbose) {
- this->LogInfo("AutoMoc: Checking " + absFilename);
+ this->LogInfo(cmQtAutoGen::MOC, "Checking " + absFilename);
}
if (this->MocRequired(contentText)) {
// Register moc job
@@ -1166,19 +1116,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);
+ bpath += cmSystemTools::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 +1155,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
@@ -1221,10 +1169,8 @@ bool cmQtAutoGenerators::ParseHeaders(
this->UicParseContent(headerName, contentText, uisIncluded);
}
} else {
- std::ostringstream ost;
- ost << "AutoGen: Error: Could not read header file:\n"
- << Quoted(headerName);
- this->LogError(ost.str());
+ this->LogFileError(cmQtAutoGen::GEN, headerName,
+ "Could not read header file");
success = false;
break;
}
@@ -1248,14 +1194,12 @@ bool cmQtAutoGenerators::MocGenerateAll(
std::map<std::string, std::string> mergedMocs(mocsIncluded);
mergedMocs.insert(mocsNotIncluded.begin(), mocsNotIncluded.end());
if (this->NameCollisionTest(mergedMocs, collisions)) {
- std::ostringstream ost;
- ost << "AutoMoc: Error: "
- "The same moc file will be generated "
- "from different sources.\n"
- "To avoid this error either\n"
- "- rename the source files or\n"
- "- do not include the (moc_NAME.cpp|NAME.moc) file";
- this->LogErrorNameCollision(ost.str(), collisions);
+ std::string msg = "The same moc file will be generated "
+ "from different sources.\n"
+ "To avoid this error either\n"
+ " - rename the source files or\n"
+ " - do not include the (moc_NAME.cpp|NAME.moc) file";
+ this->LogNameCollisionError(cmQtAutoGen::MOC, msg, collisions);
return false;
}
}
@@ -1276,33 +1220,35 @@ 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(),
this->MocOptions.end());
// Execute command
- if (!this->RunCommand(cmd, output, false)) {
- {
- std::ostringstream ost;
- ost << "AutoMoc: Error: moc predefs generation command failed\n";
- ost << "AutoMoc: Command:\n" << QuotedCommand(cmd) << "\n";
- ost << "AutoMoc: Command output:\n" << output << "\n";
- this->LogError(ost.str());
- }
+ if (!this->RunCommand(cmd, output)) {
+ this->LogCommandError(cmQtAutoGen::MOC,
+ "moc_predefs generation failed", cmd, output);
return false;
}
}
+
// (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;
}
+ } else {
+ // Touch to update the time stamp
+ if (this->Verbose) {
+ this->LogInfo(cmQtAutoGen::MOC,
+ "Touching moc_predefs " + this->MocPredefsFileRel);
+ }
+ cmSystemTools::Touch(this->MocPredefsFileAbs, false);
}
}
}
@@ -1356,13 +1302,15 @@ 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) {
// Only touch mocs compilation file
if (this->Verbose) {
- this->LogInfo("Touching MOC compilation " + this->MocCompFileRel);
+ this->LogInfo(cmQtAutoGen::MOC,
+ "Touching mocs compilation " + this->MocCompFileRel);
}
cmSystemTools::Touch(this->MocCompFileAbs, false);
}
@@ -1411,7 +1359,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 +1367,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());
@@ -1441,15 +1387,9 @@ bool cmQtAutoGenerators::MocGenerateFile(
// Success
mocGenerated = true;
} else {
- // Command failed
- {
- std::ostringstream ost;
- ost << "AutoMoc: Error: moc process failed for\n";
- ost << Quoted(mocFileRel) << "\n";
- ost << "AutoMoc: Command:\n" << QuotedCommand(cmd) << "\n";
- ost << "AutoMoc: Command output:\n" << output << "\n";
- this->LogError(ost.str());
- }
+ this->LogCommandError(cmQtAutoGen::MOC, "moc failed for\n " +
+ cmQtAutoGen::Quoted(sourceFile),
+ cmd, output);
cmSystemTools::RemoveFile(mocFileAbs);
this->MocRunFailed = true;
}
@@ -1470,7 +1410,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,27 +1425,21 @@ 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;
- if (cmsys::SystemTools::FileExists(testFile.c_str())) {
- absFile = cmsys::SystemTools::GetRealPath(testFile);
+ for (const std::string& testFile : testFiles) {
+ if (cmSystemTools::FileExists(testFile.c_str())) {
+ absFile = cmSystemTools::GetRealPath(testFile);
success = true;
break;
}
@@ -1510,13 +1448,11 @@ bool cmQtAutoGenerators::UicFindIncludedFile(std::string& absFile,
// Log error
if (!success) {
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";
+ ost << "Could not find " << cmQtAutoGen::Quoted(searchFile) << " in\n";
+ for (const std::string& testFile : testFiles) {
+ ost << " " << cmQtAutoGen::Quoted(testFile) << "\n";
}
- this->LogError(ost.str());
+ this->LogFileError(cmQtAutoGen::UIC, sourceFile, ost.str());
}
return success;
@@ -1542,16 +1478,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);
+ cmSystemTools::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;
@@ -1564,25 +1502,19 @@ bool cmQtAutoGenerators::UicGenerateAll(
{
std::multimap<std::string, std::string> collisions;
if (this->NameCollisionTest(testMap, collisions)) {
- std::ostringstream ost;
- ost << "AutoUic: Error: The same ui_NAME.h file will be generated "
- "from different sources.\n"
- "To avoid this error rename the source files.\n";
- this->LogErrorNameCollision(ost.str(), collisions);
+ std::string msg = "The same ui_NAME.h file will be generated "
+ "from different sources.\n"
+ "To avoid this error rename the source files.\n";
+ this->LogNameCollisionError(cmQtAutoGen::UIC, msg, collisions);
return false;
}
}
}
// 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,18 +1550,16 @@ 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);
{
std::vector<std::string> allOpts = this->UicTargetOptions;
- std::map<std::string, std::string>::const_iterator optionIt =
- this->UicOptions.find(uiInputFile);
+ auto optionIt = this->UicOptions.find(uiInputFile);
if (optionIt != this->UicOptions.end()) {
- std::vector<std::string> fileOpts;
- cmSystemTools::ExpandListArgument(optionIt->second, fileOpts);
- UicMergeOptions(allOpts, fileOpts, (this->QtMajorVersion == "5"));
+ cmQtAutoGen::UicMergeOptions(allOpts, optionIt->second,
+ (this->QtMajorVersion == "5"));
}
cmd.insert(cmd.end(), allOpts.begin(), allOpts.end());
}
@@ -1645,12 +1575,11 @@ bool cmQtAutoGenerators::UicGenerateFile(const std::string& realName,
// Command failed
{
std::ostringstream ost;
- ost << "AutoUic: Error: uic process failed for\n";
- ost << Quoted(uicFileRel) << " needed by\n";
- ost << Quoted(realName) << "\n";
- ost << "AutoUic: Command:\n" << QuotedCommand(cmd) << "\n";
- ost << "AutoUic: Command output:\n" << output << "\n";
- this->LogError(ost.str());
+ ost << "uic failed for\n"
+ << " " << cmQtAutoGen::Quoted(uiInputFile) << "\n"
+ << "needed by\n"
+ << " " << cmQtAutoGen::Quoted(realName);
+ this->LogCommandError(cmQtAutoGen::UIC, ost.str(), cmd, output);
}
cmSystemTools::RemoveFile(uicFileAbs);
this->UicRunFailed = true;
@@ -1669,41 +1598,9 @@ bool cmQtAutoGenerators::RccGenerateAll()
return true;
}
- // generate single map with input / output names
- std::map<std::string, std::string> qrcGenMap;
- {
- 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);
- }
- }
- }
-
- // look for name collisions
- {
- std::multimap<std::string, std::string> collisions;
- if (this->NameCollisionTest(qrcGenMap, collisions)) {
- std::ostringstream ost;
- ost << "AutoRcc: Error: The same qrc_NAME.cpp file"
- " will be generated from different sources.\n"
- "To avoid this error rename the source .qrc files.\n";
- this->LogErrorNameCollision(ost.str(), collisions);
- return false;
- }
- }
-
- // 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)) {
+ // Generate qrc files
+ for (const RccJob& rccJob : this->RccJobs) {
+ if (!this->RccGenerateFile(rccJob)) {
if (this->RccRunFailed) {
return false;
}
@@ -1715,41 +1612,49 @@ bool cmQtAutoGenerators::RccGenerateAll()
/**
* @return True if a rcc file was created. False may indicate an error.
*/
-bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile,
- const std::string& rccOutputFile,
- bool unique_n)
+bool cmQtAutoGenerators::RccGenerateFile(const RccJob& rccJob)
{
bool rccGenerated = false;
bool generateRcc = this->RccSettingsChanged;
- const std::string rccBuildFile =
- cmSystemTools::CollapseCombinedPath(this->AutogenBuildDir, rccOutputFile);
+
+ std::string rccFileAbs;
+ if (this->ConfigSuffix.empty()) {
+ rccFileAbs = rccJob.RccFile;
+ } else {
+ rccFileAbs = SubDirPrefix(rccJob.RccFile);
+ rccFileAbs +=
+ cmSystemTools::GetFilenameWithoutLastExtension(rccJob.RccFile);
+ rccFileAbs += this->ConfigSuffix;
+ rccFileAbs += cmSystemTools::GetFilenameLastExtension(rccJob.RccFile);
+ }
+ const std::string rccFileRel = cmSystemTools::RelativePath(
+ this->AutogenBuildDir.c_str(), rccFileAbs.c_str());
// Check if regeneration is required
if (!generateRcc) {
// Test if the resources list file is newer than build file
- generateRcc = FileAbsentOrOlder(rccBuildFile, rccInputFile);
+ generateRcc = FileAbsentOrOlder(rccFileAbs, rccJob.QrcFile);
if (!generateRcc) {
// Acquire input file list
std::vector<std::string> readFiles;
- const std::vector<std::string>* files = &this->RccInputs[rccInputFile];
+ const std::vector<std::string>* files = &rccJob.Inputs;
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, rccJob.QrcFile,
+ readFiles, &error)) {
files = &readFiles;
} else {
files = nullptr;
- this->LogError(error);
+ this->LogFileError(cmQtAutoGen::RCC, rccJob.QrcFile, error);
this->RccRunFailed = true;
}
}
// 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(rccFileAbs, file)) {
generateRcc = true;
break;
}
@@ -1761,53 +1666,28 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile,
if (generateRcc) {
// Log
if (this->Verbose) {
- this->LogBold("Generating RCC source " + rccOutputFile);
+ this->LogBold("Generating RCC source " + rccFileRel);
}
// Make sure the parent directory exists
- if (this->MakeParentDirectory("AutoRcc", rccBuildFile)) {
- // Compose symbol name
- std::string symbolName =
- cmsys::SystemTools::GetFilenameWithoutLastExtension(rccInputFile);
- if (!unique_n) {
- symbolName += "_";
- symbolName += FPathChecksum.getPart(rccInputFile);
- }
- // Replace '-' with '_'. The former is valid for
- // file names but not for symbol names.
- std::replace(symbolName.begin(), symbolName.end(), '-', '_');
-
+ if (this->MakeParentDirectory(cmQtAutoGen::RCC, rccFileAbs)) {
// Compose rcc command
std::vector<std::string> cmd;
cmd.push_back(this->RccExecutable);
- {
- std::map<std::string, std::string>::const_iterator optionIt =
- this->RccOptions.find(rccInputFile);
- if (optionIt != this->RccOptions.end()) {
- cmSystemTools::ExpandListArgument(optionIt->second, cmd);
- }
- }
- cmd.push_back("-name");
- cmd.push_back(symbolName);
+ cmd.insert(cmd.end(), rccJob.Options.begin(), rccJob.Options.end());
cmd.push_back("-o");
- cmd.push_back(rccBuildFile);
- cmd.push_back(rccInputFile);
+ cmd.push_back(rccFileAbs);
+ cmd.push_back(rccJob.QrcFile);
std::string output;
if (this->RunCommand(cmd, output)) {
// Success
rccGenerated = true;
} else {
- // Command failed
- {
- std::ostringstream ost;
- ost << "AutoRcc: Error: rcc process failed for\n";
- ost << Quoted(rccOutputFile) << "\n";
- ost << "AutoRcc: Command:\n" << QuotedCommand(cmd) << "\n";
- ost << "AutoRcc: Command output:\n" << output << "\n";
- this->LogError(ost.str());
- }
- cmSystemTools::RemoveFile(rccBuildFile);
+ this->LogCommandError(cmQtAutoGen::RCC, "rcc failed for\n " +
+ cmQtAutoGen::Quoted(rccJob.QrcFile),
+ cmd, output);
+ cmSystemTools::RemoveFile(rccFileAbs);
this->RccRunFailed = true;
}
} else {
@@ -1818,17 +1698,14 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile,
// For a multi configuration generator generate a wrapper file
if (!this->ConfigSuffix.empty() && !this->RccRunFailed) {
// Wrapper file name
- const std::string cppSuffix = ".cpp";
- const size_t suffixLength = this->ConfigSuffix.size() + cppSuffix.size();
- const std::string wrapperFileRel =
- rccOutputFile.substr(0, rccOutputFile.size() - suffixLength) + cppSuffix;
- const std::string wrapperFileAbs = cmSystemTools::CollapseCombinedPath(
- this->AutogenBuildDir, wrapperFileRel);
+ const std::string& wrapperFileAbs = rccJob.RccFile;
+ const std::string wrapperFileRel = cmSystemTools::RelativePath(
+ this->AutogenBuildDir.c_str(), wrapperFileAbs.c_str());
// Wrapper file content
- std::string content =
- "// This is an autogenerated configuration wrapper file. Do not edit.\n"
- "#include \"";
- content += cmsys::SystemTools::GetFilenameName(rccBuildFile);
+ std::string content = "// This is an autogenerated configuration "
+ "wrapper file. Do not edit.\n"
+ "#include \"";
+ content += cmSystemTools::GetFilenameName(rccFileRel);
content += "\"\n";
// Write content to file
if (this->FileDiffers(wrapperFileAbs, content)) {
@@ -1836,7 +1713,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;
@@ -1844,7 +1721,8 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile,
} else if (rccGenerated) {
// Only touch wrapper file if the content matches
if (this->Verbose) {
- this->LogInfo("Touching RCC wrapper " + wrapperFileRel);
+ this->LogInfo(cmQtAutoGen::RCC,
+ "Touching RCC wrapper " + wrapperFileRel);
}
cmSystemTools::Touch(wrapperFileAbs, false);
}
@@ -1853,69 +1731,144 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile,
return rccGenerated;
}
-void cmQtAutoGenerators::LogErrorNameCollision(
- const std::string& message,
- const std::multimap<std::string, std::string>& collisions) const
+void cmQtAutoGenerators::LogBold(const std::string& message) const
{
- typedef std::multimap<std::string, std::string>::const_iterator Iter;
+ cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue |
+ cmsysTerminal_Color_ForegroundBold,
+ message.c_str(), true, this->ColorOutput);
+}
- std::ostringstream ost;
- // Add message
- if (!message.empty()) {
- ost << message;
- if (message[message.size() - 1] != '\n') {
- ost << '\n';
- }
+void cmQtAutoGenerators::LogInfo(cmQtAutoGen::GeneratorType genType,
+ const std::string& message) const
+{
+ std::string msg = cmQtAutoGen::GeneratorName(genType);
+ msg += ": ";
+ msg += message;
+ if (msg.back() != '\n') {
+ msg.push_back('\n');
}
- // Append collision list
- for (Iter it = collisions.begin(); it != collisions.end(); ++it) {
- ost << it->first << " : " << it->second << '\n';
+ cmSystemTools::Stdout(msg.c_str(), msg.size());
+}
+
+void cmQtAutoGenerators::LogWarning(cmQtAutoGen::GeneratorType genType,
+ const std::string& message) const
+{
+ std::string msg = cmQtAutoGen::GeneratorName(genType);
+ msg += " warning:";
+ if (message.find('\n') == std::string::npos) {
+ // Single line message
+ msg.push_back(' ');
+ } else {
+ // Multi line message
+ msg.push_back('\n');
+ }
+ // Message
+ msg += message;
+ if (msg.back() != '\n') {
+ msg.push_back('\n');
}
- this->LogError(ost.str());
+ msg += "\n";
+ cmSystemTools::Stdout(msg.c_str(), msg.size());
}
-void cmQtAutoGenerators::LogBold(const std::string& message) const
+void cmQtAutoGenerators::LogFileWarning(cmQtAutoGen::GeneratorType genType,
+ const std::string& filename,
+ const std::string& message) const
{
- cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue |
- cmsysTerminal_Color_ForegroundBold,
- message.c_str(), true, this->ColorOutput);
+ std::string emsg = " ";
+ emsg += cmQtAutoGen::Quoted(filename);
+ emsg += "\n";
+ // Message
+ emsg += message;
+ this->LogWarning(genType, emsg);
}
-void cmQtAutoGenerators::LogInfo(const std::string& message) const
+void cmQtAutoGenerators::LogError(cmQtAutoGen::GeneratorType genType,
+ const std::string& message) const
{
- std::string msg(message);
- if (!msg.empty()) {
- if (msg[msg.size() - 1] != '\n') {
- msg.push_back('\n');
- }
- cmSystemTools::Stdout(msg.c_str(), msg.size());
+ std::string msg;
+ msg.push_back('\n');
+ msg = cmQtAutoGen::GeneratorName(genType);
+ msg += " error:";
+ if (message.find('\n') == std::string::npos) {
+ // Single line message
+ msg.push_back(' ');
+ } else {
+ // Multi line message
+ msg.push_back('\n');
+ }
+ // Message
+ msg += message;
+ if (msg.back() != '\n') {
+ msg.push_back('\n');
}
+ msg += "\n";
+ cmSystemTools::Stderr(msg.c_str(), msg.size());
}
-void cmQtAutoGenerators::LogWarning(const std::string& message) const
+void cmQtAutoGenerators::LogFileError(cmQtAutoGen::GeneratorType genType,
+ const std::string& filename,
+ const std::string& message) const
{
- std::string msg(message);
- if (!msg.empty()) {
- if (msg[msg.size() - 1] != '\n') {
- msg.push_back('\n');
+ std::string emsg = " ";
+ emsg += cmQtAutoGen::Quoted(filename);
+ emsg += "\n";
+ // Message
+ emsg += message;
+ this->LogError(genType, emsg);
+}
+
+void cmQtAutoGenerators::LogNameCollisionError(
+ cmQtAutoGen::GeneratorType genType, const std::string& message,
+ const std::multimap<std::string, std::string>& collisions) const
+{
+ std::string emsg;
+ // Add message
+ if (!message.empty()) {
+ emsg += message;
+ if (emsg.back() != '\n') {
+ emsg.push_back('\n');
}
- // Append empty line
- msg.push_back('\n');
- cmSystemTools::Stdout(msg.c_str(), msg.size());
}
+ // Append collision list
+ for (const auto& item : collisions) {
+ emsg += " ";
+ emsg += item.first;
+ emsg += " -> ";
+ emsg += item.second;
+ emsg += "\n";
+ }
+ this->LogError(genType, emsg);
}
-void cmQtAutoGenerators::LogError(const std::string& message) const
+void cmQtAutoGenerators::LogCommandError(
+ cmQtAutoGen::GeneratorType genType, const std::string& message,
+ const std::vector<std::string>& command, const std::string& output) const
{
- std::string msg(message);
- if (!msg.empty()) {
- if (msg[msg.size() - 1] != '\n') {
- msg.push_back('\n');
- }
- // Append empty line
+ std::string msg;
+ msg.push_back('\n');
+ msg += cmQtAutoGen::GeneratorName(genType);
+ msg += " subprocess error: ";
+ msg += message;
+ if (msg.back() != '\n') {
+ msg.push_back('\n');
+ }
+ msg.push_back('\n');
+ msg += "Command\n";
+ msg += "-------\n";
+ msg += QuotedCommand(command);
+ if (msg.back() != '\n') {
+ msg.push_back('\n');
+ }
+ msg.push_back('\n');
+ msg += "Output\n";
+ msg += "------\n";
+ msg += output;
+ if (msg.back() != '\n') {
msg.push_back('\n');
- cmSystemTools::Stderr(msg.c_str(), msg.size());
}
+ msg += "\n";
+ cmSystemTools::Stderr(msg.c_str(), msg.size());
}
/**
@@ -1959,7 +1912,7 @@ std::string cmQtAutoGenerators::ChecksumedPath(
std::string res = FPathChecksum.getPart(sourceFile);
res += "/";
res += basePrefix;
- res += cmsys::SystemTools::GetFilenameWithoutLastExtension(sourceFile);
+ res += cmSystemTools::GetFilenameWithoutLastExtension(sourceFile);
res += baseSuffix;
return res;
}
@@ -1968,18 +1921,16 @@ 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);
+ success = cmSystemTools::MakeDirectory(dirName);
if (!success) {
- std::string error = logPrefix;
- error += ": Error: Parent directory creation failed for ";
- error += Quoted(filename);
- this->LogError(error);
+ this->LogFileError(genType, filename,
+ "Could not create parent directory");
}
}
return success;
@@ -1998,31 +1949,27 @@ 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 += Quoted(filename);
+ error = "File writing failed";
}
} else {
- error = logPrefix;
- error = ": Error opening ";
- error += Quoted(filename);
+ error = "Opening file for writing failed";
}
}
if (!error.empty()) {
- this->LogError(error);
+ this->LogFileError(genType, filename, error);
return false;
}
return true;
@@ -2033,17 +1980,18 @@ bool cmQtAutoGenerators::FileWrite(const char* logPrefix,
* @return True on success
*/
bool cmQtAutoGenerators::RunCommand(const std::vector<std::string>& command,
- std::string& output, bool verbose) const
+ std::string& output) const
{
// Log command
if (this->Verbose) {
- this->LogInfo(QuotedCommand(command));
+ std::string qcmd = QuotedCommand(command);
+ qcmd.push_back('\n');
+ cmSystemTools::Stdout(qcmd.c_str(), qcmd.size());
}
// Execute command
int retVal = 0;
bool res = cmSystemTools::RunSingleCommand(
- command, &output, &output, &retVal, nullptr,
- verbose ? cmSystemTools::OUTPUT_MERGE : cmSystemTools::OUTPUT_NONE);
+ command, &output, &output, &retVal, nullptr, cmSystemTools::OUTPUT_NONE);
return (res && (retVal == 0));
}
@@ -2055,13 +2003,11 @@ 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);
- if (cmsys::SystemTools::FileExists(testFilePath.c_str())) {
+ testFilePath.push_back('.');
+ testFilePath += ext;
+ if (cmSystemTools::FileExists(testFilePath.c_str())) {
header = testFilePath;
return true;
}
@@ -2076,10 +2022,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;
}
@@ -2087,7 +2033,7 @@ std::string cmQtAutoGenerators::MocFindHeader(
}
// Sanitize
if (!header.empty()) {
- header = cmsys::SystemTools::GetRealPath(header);
+ header = cmSystemTools::GetRealPath(header);
}
return header;
}
@@ -2101,19 +2047,19 @@ bool cmQtAutoGenerators::MocFindIncludedFile(
{
std::string testPath = sourcePath;
testPath += includeString;
- if (cmsys::SystemTools::FileExists(testPath.c_str())) {
- absFile = cmsys::SystemTools::GetRealPath(testPath);
+ if (cmSystemTools::FileExists(testPath.c_str())) {
+ absFile = cmSystemTools::GetRealPath(testPath);
success = true;
}
}
// 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);
- if (cmsys::SystemTools::FileExists(fullPath.c_str())) {
- absFile = cmsys::SystemTools::GetRealPath(fullPath);
+ for (const std::string& path : this->MocIncludePaths) {
+ std::string fullPath = path;
+ fullPath.push_back('/');
+ fullPath += includeString;
+ if (cmSystemTools::FileExists(fullPath.c_str())) {
+ absFile = cmSystemTools::GetRealPath(fullPath);
success = true;
break;
}
diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h
index 5cb3d9f..5d3ad74 100644
--- a/Source/cmQtAutoGenerators.h
+++ b/Source/cmQtAutoGenerators.h
@@ -6,18 +6,19 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include "cmFilePathChecksum.h"
+#include "cmQtAutoGen.h"
#include "cmsys/RegularExpression.hxx"
#include <map>
#include <set>
#include <string>
-#include <utility>
#include <vector>
class cmMakefile;
class cmQtAutoGenerators
{
+ CM_DISABLE_COPY(cmQtAutoGenerators)
public:
cmQtAutoGenerators();
bool Run(const std::string& targetDirectory, const std::string& config);
@@ -25,13 +26,35 @@ public:
private:
// -- Types
- /// @brief Used to extract additional dependencies from content text
- struct MocDependFilter
+ /// @brief Search key plus regular expression pair
+ struct KeyRegExp
{
- std::string key;
- cmsys::RegularExpression regExp;
+ KeyRegExp() = default;
+
+ KeyRegExp(const char* key, const char* regExp)
+ : Key(key)
+ , RegExp(regExp)
+ {
+ }
+
+ KeyRegExp(const std::string& key, const std::string& regExp)
+ : Key(key)
+ , RegExp(regExp)
+ {
+ }
+
+ std::string Key;
+ cmsys::RegularExpression RegExp;
+ };
+
+ /// @brief RCC job
+ struct RccJob
+ {
+ std::string QrcFile;
+ std::string RccFile;
+ std::vector<std::string> Options;
+ std::vector<std::string> Inputs;
};
- typedef std::pair<std::string, cmsys::RegularExpression> MocMacroFilter;
// -- Configuration
bool MocDependFilterPush(const std::string& key, const std::string& regExp);
@@ -90,6 +113,9 @@ private:
const std::string& fileName, const std::string& contentText,
std::map<std::string, std::vector<std::string>>& includedUis);
+ std::string MocMacroNamesString() const;
+ std::string MocHeaderSuffixesString() const;
+
bool MocParseSourceContent(
const std::string& absFilename, const std::string& contentText,
std::map<std::string, std::string>& mocsIncluded,
@@ -122,18 +148,31 @@ private:
// -- Rcc file generation
bool RccGenerateAll();
- bool RccGenerateFile(const std::string& qrcInputFile,
- const std::string& qrcOutputFile, bool unique_n);
+ bool RccGenerateFile(const RccJob& rccJob);
- // -- Logging
- void LogErrorNameCollision(
- const std::string& message,
- const std::multimap<std::string, std::string>& collisions) const;
+ // -- Log info
void LogBold(const std::string& message) const;
- void LogInfo(const std::string& message) const;
- void LogWarning(const std::string& message) const;
- void LogError(const std::string& message) const;
- void LogCommand(const std::vector<std::string>& command) const;
+ void LogInfo(cmQtAutoGen::GeneratorType genType,
+ const std::string& message) const;
+ // -- Log warning
+ void LogWarning(cmQtAutoGen::GeneratorType genType,
+ const std::string& message) const;
+ void LogFileWarning(cmQtAutoGen::GeneratorType genType,
+ const std::string& filename,
+ const std::string& message) const;
+ // -- Log error
+ void LogError(cmQtAutoGen::GeneratorType genType,
+ const std::string& message) const;
+ void LogFileError(cmQtAutoGen::GeneratorType genType,
+ const std::string& filename,
+ const std::string& message) const;
+ void LogCommandError(cmQtAutoGen::GeneratorType genType,
+ const std::string& message,
+ const std::vector<std::string>& command,
+ const std::string& output) const;
+ void LogNameCollisionError(
+ cmQtAutoGen::GeneratorType genType, const std::string& message,
+ const std::multimap<std::string, std::string>& collisions) const;
// -- Utility
bool NameCollisionTest(
@@ -142,14 +181,14 @@ 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;
+ bool RunCommand(const std::vector<std::string>& command,
+ std::string& output) const;
bool FindHeader(std::string& header, const std::string& testBasePath) const;
@@ -169,6 +208,7 @@ private:
std::string AutogenIncludeDir;
// -- Qt environment
std::string QtMajorVersion;
+ std::string QtMinorVersion;
std::string MocExecutable;
std::string UicExecutable;
std::string RccExecutable;
@@ -200,23 +240,21 @@ private:
std::vector<std::string> MocDefinitions;
std::vector<std::string> MocOptions;
std::vector<std::string> MocPredefsCmd;
- std::vector<MocDependFilter> MocDependFilters;
- std::vector<MocMacroFilter> MocMacroFilters;
+ std::vector<KeyRegExp> MocDependFilters;
+ std::vector<KeyRegExp> MocMacroFilters;
cmsys::RegularExpression MocRegExpInclude;
// -- Uic
bool UicSettingsChanged;
bool UicRunFailed;
std::vector<std::string> UicSkipList;
std::vector<std::string> UicTargetOptions;
- std::map<std::string, std::string> UicOptions;
+ std::map<std::string, std::vector<std::string>> UicOptions;
std::vector<std::string> UicSearchPaths;
cmsys::RegularExpression UicRegExpInclude;
// -- Rcc
bool RccSettingsChanged;
bool RccRunFailed;
- std::vector<std::string> RccSources;
- std::map<std::string, std::string> RccOptions;
- std::map<std::string, std::vector<std::string>> RccInputs;
+ std::vector<RccJob> RccJobs;
};
#endif