summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorDaniel Gehriger <dgehriger@globusmedical.com>2022-04-25 10:17:53 (GMT)
committerDaniel Gehriger <dgehriger@globusmedical.com>2022-04-26 18:43:00 (GMT)
commit1c9cead051be019bcaa46f15d3587ca23214805b (patch)
tree33ba7bd2a7197e8a6c278b135102518e8ce19b2f /Source
parentf109faf450f04fe045e2b5328092684038dd68e1 (diff)
downloadCMake-1c9cead051be019bcaa46f15d3587ca23214805b.zip
CMake-1c9cead051be019bcaa46f15d3587ca23214805b.tar.gz
CMake-1c9cead051be019bcaa46f15d3587ca23214805b.tar.bz2
AUTOMOC: Automatically use options file for moc compiler
Diffstat (limited to 'Source')
-rw-r--r--Source/cmQtAutoGen.cxx7
-rw-r--r--Source/cmQtAutoGen.h5
-rw-r--r--Source/cmQtAutoMocUic.cxx51
3 files changed, 63 insertions, 0 deletions
diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx
index 0a394b5..adbdba8 100644
--- a/Source/cmQtAutoGen.cxx
+++ b/Source/cmQtAutoGen.cxx
@@ -76,6 +76,13 @@ static void MergeOptions(std::vector<std::string>& baseOpts,
unsigned int const cmQtAutoGen::ParallelMax = 64;
+#ifdef _WIN32
+// Actually 32767 (see
+// https://devblogs.microsoft.com/oldnewthing/20031210-00/?p=41553) but we
+// allow for a small margin
+size_t const cmQtAutoGen::CommandLineLengthMax = 32000;
+#endif
+
cm::string_view cmQtAutoGen::GeneratorName(GenT genType)
{
switch (genType) {
diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h
index 5a23ae9..d111422 100644
--- a/Source/cmQtAutoGen.h
+++ b/Source/cmQtAutoGen.h
@@ -64,6 +64,11 @@ public:
/// @brief Maximum number of parallel threads/processes in a generator
static unsigned int const ParallelMax;
+#ifdef _WIN32
+ /// @brief Maximum number of characters on command line
+ static size_t const CommandLineLengthMax;
+#endif
+
/// @brief Returns the generator name
static cm::string_view GeneratorName(GenT genType);
/// @brief Returns the generator name in upper case
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index 4ed728e..0d38dfb 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -497,6 +497,10 @@ public:
protected:
ParseCacheT::FileHandleT CacheEntry;
+
+ private:
+ void MaybeWriteMocResponseFile(std::string const& outputFile,
+ std::vector<std::string>& cmd) const;
};
/** uic compiles a file. */
@@ -2025,6 +2029,8 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
cmd.push_back(outputFile);
// Add source file
cmd.push_back(sourceFile);
+
+ MaybeWriteMocResponseFile(outputFile, cmd);
}
// Execute moc command
@@ -2070,6 +2076,51 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
}
}
+/*
+ * Check if command line exceeds maximum length supported by OS
+ * (if on Windows) and switch to using a response file instead.
+ */
+void cmQtAutoMocUicT::JobCompileMocT::MaybeWriteMocResponseFile(
+ std::string const& outputFile, std::vector<std::string>& cmd) const
+{
+#ifdef _WIN32
+ // Ensure cmd is less than CommandLineLengthMax characters
+ size_t commandLineLength = cmd.size(); // account for separating spaces
+ for (std::string const& str : cmd) {
+ commandLineLength += str.length();
+ }
+ if (commandLineLength >= CommandLineLengthMax) {
+ // Command line exceeds maximum size allowed by OS
+ // => create response file
+ std::string const responseFile = cmStrCat(outputFile, ".rsp");
+
+ cmsys::ofstream fout(responseFile.c_str());
+ if (!fout) {
+ this->LogError(
+ GenT::MOC,
+ cmStrCat("AUTOMOC was unable to create a response file at\n ",
+ this->MessagePath(responseFile)));
+ return;
+ }
+
+ auto it = cmd.begin();
+ while (++it != cmd.end()) {
+ fout << *it << "\n";
+ }
+ fout.close();
+
+ // Keep all but executable
+ cmd.resize(1);
+
+ // Specify response file
+ cmd.push_back(cmStrCat('@', responseFile));
+ }
+#else
+ static_cast<void>(outputFile);
+ static_cast<void>(cmd);
+#endif
+}
+
void cmQtAutoMocUicT::JobCompileUicT::Process()
{
std::string const& sourceFile = this->Mapping->SourceFile->FileName;