Autogen: Add support for response files for moc predef targets

Add support for response files for moc predef targets and make the limit when
to use response files for autogen targets configurable.
This commit is contained in:
tophoo
2023-11-08 16:34:19 +01:00
parent 7eb5ab2c63
commit 7a07887055
11 changed files with 88 additions and 1 deletions

View File

@@ -70,6 +70,7 @@ syn keyword cmakeProperty contained
\ ATTACHED_FILES
\ ATTACHED_FILES_ON_FAIL
\ AUTOGEN_BUILD_DIR
\ AUTOGEN_COMMAND_LINE_LENGTH_MAX
\ AUTOGEN_ORIGIN_DEPENDS
\ AUTOGEN_PARALLEL
\ AUTOGEN_SOURCE_GROUP
@@ -764,6 +765,7 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_STANDARD_REQUIRED
\ CMAKE_ASM_SUPPORTED
\ CMAKE_ASM_VISIBILITY_PRESET
\ CMAKE_AUTOGEN_COMMAND_LINE_LENGTH_MAX
\ CMAKE_AUTOGEN_ORIGIN_DEPENDS
\ CMAKE_AUTOGEN_PARALLEL
\ CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE

View File

@@ -130,6 +130,7 @@ Properties on Targets
/prop_tgt/ARCHIVE_OUTPUT_NAME
/prop_tgt/ARCHIVE_OUTPUT_NAME_CONFIG
/prop_tgt/AUTOGEN_BUILD_DIR
/prop_tgt/AUTOGEN_COMMAND_LINE_LENGTH_MAX
/prop_tgt/AUTOGEN_ORIGIN_DEPENDS
/prop_tgt/AUTOGEN_PARALLEL
/prop_tgt/AUTOGEN_TARGET_DEPENDS

View File

@@ -400,6 +400,7 @@ Variables that Control the Build
/variable/CMAKE_APPLE_SILICON_PROCESSOR
/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY
/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG
/variable/CMAKE_AUTOGEN_COMMAND_LINE_LENGTH_MAX
/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS
/variable/CMAKE_AUTOGEN_PARALLEL
/variable/CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE

View File

@@ -0,0 +1,18 @@
AUTOGEN_COMMAND_LINE_LENGTH_MAX
-------------------------------
.. versionadded:: 3.29
Command line length limit for autogen targets, i.e. ``moc`` or ``uic``,
that triggers the use of response files on Windows instead of passing all
arguments to the command line.
- An empty (or unset) value sets the limit to 32000
- A positive non zero integer value sets the exact command line length
limit.
By default ``AUTOGEN_COMMAND_LINE_LENGTH_MAX`` is initialized from
:variable:`CMAKE_AUTOGEN_COMMAND_LINE_LENGTH_MAX`.
See the :manual:`cmake-qt(7)` manual for more information on using CMake
with Qt.

View File

@@ -247,5 +247,9 @@ will be generated when this variable is ``ON``.
This target property controls the number of ``moc`` or ``uic`` processes to
start in parallel during builds.
:prop_tgt:`AUTOGEN_COMMAND_LINE_LENGTH_MAX`:
This target property controls the limit when to use response files for
``moc`` or ``uic`` processes on Windows.
See the :manual:`cmake-qt(7)` manual for more information on using CMake
with Qt.

View File

@@ -81,5 +81,9 @@ will be generated when this variable is ``ON``.
This target property controls the number of ``moc`` or ``uic`` processes to
start in parallel during builds.
:prop_tgt:`AUTOGEN_COMMAND_LINE_LENGTH_MAX`:
This target property controls the limit when to use response files for
``moc`` or ``uic`` processes on Windows.
See the :manual:`cmake-qt(7)` manual for more information on using CMake
with Qt.

View File

@@ -0,0 +1,10 @@
CMAKE_AUTOGEN_COMMAND_LINE_LENGTH_MAX
-------------------------------------
.. versionadded:: 3.29
Command line length limit for autogen targets, i.e. ``moc`` or ``uic``,
that triggers the use of response files on Windows instead of passing all
arguments to the command line.
By default ``CMAKE_AUTOGEN_COMMAND_LINE_LENGTH_MAX`` is unset.

View File

@@ -485,6 +485,38 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
}
}
#ifdef _WIN32
{
const auto& value =
this->GenTarget->GetProperty("AUTOGEN_COMMAND_LINE_LENGTH_MAX");
if (value.IsSet()) {
using maxCommandLineLengthType =
decltype(this->AutogenTarget.MaxCommandLineLength);
unsigned long propInt = 0;
if (cmStrToULong(value, &propInt) && propInt > 0 &&
propInt <= std::numeric_limits<maxCommandLineLengthType>::max()) {
this->AutogenTarget.MaxCommandLineLength =
static_cast<maxCommandLineLengthType>(propInt);
} else {
// Warn the project author that AUTOGEN_PARALLEL is not valid.
this->Makefile->IssueMessage(
MessageType::AUTHOR_WARNING,
cmStrCat("AUTOGEN_COMMAND_LINE_LENGTH_MAX=\"", *value,
"\" for target \"", this->GenTarget->GetName(),
"\" is not valid. Using no limit for "
"AUTOGEN_COMMAND_LINE_LENGTH_MAX"));
this->AutogenTarget.MaxCommandLineLength =
std::numeric_limits<maxCommandLineLengthType>::max();
}
} else {
// Actually 32767 (see
// https://devblogs.microsoft.com/oldnewthing/20031210-00/?p=41553) but
// we allow for a small margin
this->AutogenTarget.MaxCommandLineLength = 32000;
}
}
#endif
// Autogen target info and settings files
{
// Info file
@@ -1692,6 +1724,10 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
// General
info.SetBool("MULTI_CONFIG", this->MultiConfig);
info.SetUInt("PARALLEL", this->AutogenTarget.Parallel);
#ifdef _WIN32
info.SetUInt("AUTOGEN_COMMAND_LINE_LENGTH_MAX",
this->AutogenTarget.MaxCommandLineLength);
#endif
info.SetUInt("VERBOSITY", this->Verbosity);
// Directories

View File

@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <cstddef>
#include <limits>
#include <memory>
#include <set>
#include <string>
@@ -194,6 +195,8 @@ private:
bool GlobalTarget = false;
// Settings
unsigned int Parallel = 1;
unsigned int MaxCommandLineLength =
std::numeric_limits<unsigned int>::max();
// Configuration files
std::string InfoFile;
ConfigString SettingsFile;

View File

@@ -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;
@@ -811,7 +814,7 @@ void cmQtAutoMocUicT::JobT::MaybeWriteResponseFile(
for (std::string const& str : cmd) {
commandLineLength += str.length();
}
if (commandLineLength >= CommandLineLengthMax) {
if (commandLineLength >= this->BaseConst().MaxCommandLineLength) {
// Command line exceeds maximum size allowed by OS
// => create response file
std::string const responseFile = cmStrCat(outputFile, ".rsp");
@@ -2380,6 +2383,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) ||

View File

@@ -551,6 +551,7 @@ TargetProperty const StaticTargetProperties[] = {
{ "ANDROID_PROCESS_MAX"_s, IC::CanCompileSources },
{ "ANDROID_SKIP_ANT_STEP"_s, IC::CanCompileSources },
// -- Autogen
{ "AUTOGEN_COMMAND_LINE_LENGTH_MAX"_s, IC::CanCompileSources },
{ "AUTOGEN_ORIGIN_DEPENDS"_s, IC::CanCompileSources },
{ "AUTOGEN_PARALLEL"_s, IC::CanCompileSources },
{ "AUTOGEN_USE_SYSTEM_INCLUDE"_s, IC::CanCompileSources },