فهرست منبع

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.
tophoo 2 سال پیش
والد
کامیت
7a07887055

+ 2 - 0
Auxiliary/vim/syntax/cmake.vim

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

+ 1 - 0
Help/manual/cmake-properties.7.rst

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

+ 1 - 0
Help/manual/cmake-variables.7.rst

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

+ 18 - 0
Help/prop_tgt/AUTOGEN_COMMAND_LINE_LENGTH_MAX.rst

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

+ 4 - 0
Help/prop_tgt/AUTOMOC.rst

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

+ 4 - 0
Help/prop_tgt/AUTOUIC.rst

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

+ 10 - 0
Help/variable/CMAKE_AUTOGEN_COMMAND_LINE_LENGTH_MAX.rst

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

+ 36 - 0
Source/cmQtAutoGenInitializer.cxx

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

+ 3 - 0
Source/cmQtAutoGenInitializer.h

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

+ 8 - 1
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;
@@ -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) ||

+ 1 - 0
Source/cmTarget.cxx

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