diff options
Diffstat (limited to 'Source/cmQtAutoMocUic.cxx')
-rw-r--r-- | Source/cmQtAutoMocUic.cxx | 116 |
1 files changed, 64 insertions, 52 deletions
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx index ece657d..a49125e 100644 --- a/Source/cmQtAutoMocUic.cxx +++ b/Source/cmQtAutoMocUic.cxx @@ -5,6 +5,7 @@ #include <algorithm> #include <atomic> #include <cstddef> +#include <limits> #include <map> #include <mutex> #include <set> @@ -172,6 +173,8 @@ public: bool MultiConfig = false; IntegerVersion QtVersion = { 4, 0 }; unsigned int ThreadCount = 0; + unsigned int MaxCommandLineLength = + std::numeric_limits<unsigned int>::max(); // - Directories std::string AutogenBuildDir; std::string AutogenIncludeDir; @@ -190,7 +193,7 @@ public: { public: // -- Parse Cache - std::atomic<bool> ParseCacheChanged = ATOMIC_VAR_INIT(false); + std::atomic<bool> ParseCacheChanged{ false }; cmFileTime ParseCacheTime; ParseCacheT ParseCache; @@ -333,6 +336,13 @@ public: std::vector<std::string> const& command, std::string const& output) const; + /* + * Check if command line exceeds maximum length supported by OS + * (if on Windows) and switch to using a response file instead. + */ + void MaybeWriteResponseFile(std::string const& outputFile, + std::vector<std::string>& cmd) const; + /** @brief Run an external process. Use only during Process() call! */ bool RunProcess(GenT genType, cmWorkerPool::ProcessResultT& result, std::vector<std::string> const& command, @@ -498,10 +508,6 @@ public: protected: ParseCacheT::FileHandleT CacheEntry; - - private: - void MaybeWriteMocResponseFile(std::string const& outputFile, - std::vector<std::string>& cmd) const; }; /** uic compiles a file. */ @@ -583,7 +589,7 @@ private: std::string SettingsStringMoc_; std::string SettingsStringUic_; // -- Worker thread pool - std::atomic<bool> JobError_ = ATOMIC_VAR_INIT(false); + std::atomic<bool> JobError_{ false }; cmWorkerPool WorkerPool_; // -- Concurrent processing mutable std::mutex CMakeLibMutex_; @@ -795,6 +801,51 @@ void cmQtAutoMocUicT::JobT::LogCommandError( this->Gen()->Log().ErrorCommand(genType, message, command, output); } +/* + * Check if command line exceeds maximum length supported by OS + * (if on Windows) and switch to using a response file instead. + */ +void cmQtAutoMocUicT::JobT::MaybeWriteResponseFile( + 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 >= this->BaseConst().MaxCommandLineLength) { + // 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.emplace_back(cmStrCat('@', responseFile)); + } +#else + static_cast<void>(outputFile); + static_cast<void>(cmd); +#endif +} + bool cmQtAutoMocUicT::JobT::RunProcess(GenT genType, cmWorkerPool::ProcessResultT& result, std::vector<std::string> const& command, @@ -836,6 +887,8 @@ void cmQtAutoMocUicT::JobMocPredefsT::Process() cm::append(cmd, this->MocConst().OptionsDefinitions); // Add includes cm::append(cmd, this->MocConst().OptionsIncludes); + // Check if response file is necessary + MaybeWriteResponseFile(this->MocConst().PredefsFileAbs, cmd); // Execute command if (!this->RunProcess(GenT::MOC, result, cmd, reason.get())) { this->LogCommandError(GenT::MOC, @@ -2034,7 +2087,7 @@ void cmQtAutoMocUicT::JobCompileMocT::Process() // Add source file cmd.push_back(sourceFile); - MaybeWriteMocResponseFile(outputFile, cmd); + MaybeWriteResponseFile(outputFile, cmd); } // Execute moc command @@ -2080,51 +2133,6 @@ 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.emplace_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; @@ -2377,6 +2385,10 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info) !info.GetUInt("QT_VERSION_MINOR", this->BaseConst_.QtVersion.Minor, true) || !info.GetUInt("PARALLEL", this->BaseConst_.ThreadCount, false) || +#ifdef _WIN32 + !info.GetUInt("AUTOGEN_COMMAND_LINE_LENGTH_MAX", + this->BaseConst_.MaxCommandLineLength, false) || +#endif !info.GetString("BUILD_DIR", this->BaseConst_.AutogenBuildDir, true) || !info.GetStringConfig("INCLUDE_DIR", this->BaseConst_.AutogenIncludeDir, true) || |