AUTOMOC: Automatically use options file for moc compiler

This commit is contained in:
Daniel Gehriger
2022-04-25 12:17:53 +02:00
parent f109faf450
commit 1c9cead051
3 changed files with 63 additions and 0 deletions

View File

@@ -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) {

View File

@@ -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

View File

@@ -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;