Sfoglia il codice sorgente

Ninja: Add support for per-source JOB_POOL_COMPILE property

This commit allows to override a global or target-wide 'job pool'
property on a per-source basis.

It modifies the Ninja generator to first look into the source's
properties, and only use the target properties as a fallback.

The new `source` parameter to
`cmNinjaTargetGenerator::addPoolNinjaVariable` may be null, e.g. when
the function is called in context where there is no source (e.g. a
linking task).

Closes: #23994
Bastien Montagne 4 mesi fa
parent
commit
3a9d56d2c7

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

@@ -580,6 +580,7 @@ Properties on Source Files
    /prop_sf/MACOSX_PACKAGE_LOCATION
    /prop_sf/OBJECT_DEPENDS
    /prop_sf/OBJECT_OUTPUTS
+   /prop_sf/JOB_POOL_COMPILE
    /prop_sf/SKIP_AUTOGEN
    /prop_sf/SKIP_AUTOMOC
    /prop_sf/SKIP_AUTORCC

+ 3 - 0
Help/prop_gbl/JOB_POOLS.rst

@@ -23,6 +23,9 @@ Defined pools can be used at different levels:
 * :command:`Custom commands <add_custom_command>` and
   :command:`custom targets <add_custom_target>` can specify pools using the
   option ``JOB_POOL``.
+* Per-source, by setting the source file property :prop_sf:`JOB_POOL_COMPILE`,
+  in case some specific source files require to override their global or
+  target assigned pool.
 
 Using a pool that is not defined by ``JOB_POOLS`` causes an error by ninja
 at build time.

+ 19 - 0
Help/prop_sf/JOB_POOL_COMPILE.rst

@@ -0,0 +1,19 @@
+JOB_POOL_COMPILE
+----------------
+
+Ninja only: Pool used for compiling.
+
+The number of parallel compile processes could be limited by defining
+pools with the global :prop_gbl:`JOB_POOLS`
+property and then specifying here the pool name.
+
+This allows to override the :prop_tgt:`JOB_POOL_COMPILE`
+value for specific source files within a same target.
+
+For instance:
+
+.. code-block:: cmake
+
+  set_property(SOURCE main.cc PROPERTY JOB_POOL_COMPILE two_jobs)
+
+This property is undefined by default.

+ 5 - 0
Help/release/dev/ninja-per-source-job-pool.rst

@@ -0,0 +1,5 @@
+ninja-per-source-job-pool
+-------------------------
+
+* The :prop_sf:`JOB_POOL_COMPILE` source file property was added
+  to assign individual source compilations to :prop_gbl:`JOB_POOLS`.

+ 2 - 2
Source/cmNinjaNormalTargetGenerator.cxx

@@ -1032,7 +1032,7 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement(
                               vars["LINK_FLAGS"], frameworkPath, linkPath,
                               genTarget);
 
-  this->addPoolNinjaVariable("JOB_POOL_LINK", genTarget, vars);
+  this->addPoolNinjaVariable("JOB_POOL_LINK", genTarget, nullptr, vars);
 
   vars["MANIFESTS"] = this->GetManifests(config);
 
@@ -1318,7 +1318,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
                            this->TargetLinkLanguage(config), "CURRENT", false);
   }
 
-  this->addPoolNinjaVariable("JOB_POOL_LINK", gt, vars);
+  this->addPoolNinjaVariable("JOB_POOL_LINK", gt, nullptr, vars);
 
   this->UseLWYU = this->GetLocalGenerator()->AppendLWYUFlags(
     vars["LINK_FLAGS"], this->GetGeneratorTarget(),

+ 16 - 7
Source/cmNinjaTargetGenerator.cxx

@@ -1606,7 +1606,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
     }
 
     this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
-                               ppBuild.Variables);
+                               source, ppBuild.Variables);
 
     this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
                                            ppBuild, commandLineLengthLimit);
@@ -1639,13 +1639,13 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
     objectFileDir, cmOutputConverter::SHELL);
 
   this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
-                             vars);
+                             source, vars);
 
   if (!pchSources.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
     auto pchIt = pchSources.find(source->GetFullPath());
     if (pchIt != pchSources.end()) {
       this->addPoolNinjaVariable("JOB_POOL_PRECOMPILE_HEADER",
-                                 this->GetGeneratorTarget(), vars);
+                                 this->GetGeneratorTarget(), nullptr, vars);
     }
   }
 
@@ -1836,7 +1836,7 @@ void cmNinjaTargetGenerator::WriteCxxModuleBmiBuildStatement(
     }
 
     this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
-                               ppBuild.Variables);
+                               source, ppBuild.Variables);
 
     this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
                                            ppBuild, commandLineLengthLimit);
@@ -1864,7 +1864,7 @@ void cmNinjaTargetGenerator::WriteCxxModuleBmiBuildStatement(
     bmiFileDir, cmOutputConverter::SHELL);
 
   this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
-                             vars);
+                             source, vars);
 
   bmiBuild.RspFile = cmStrCat(bmiFileName, ".rsp");
 
@@ -2494,9 +2494,18 @@ void cmNinjaTargetGenerator::RemoveDepfileBinding(cmNinjaVars& vars) const
 
 void cmNinjaTargetGenerator::addPoolNinjaVariable(
   std::string const& pool_property, cmGeneratorTarget* target,
-  cmNinjaVars& vars)
+  cmSourceFile const* source, cmNinjaVars& vars)
 {
-  cmValue pool = target->GetProperty(pool_property);
+  // First check the current source properties, then if not found, its target
+  // ones. Allows to override a target-wide compile pool with a source-specific
+  // one.
+  cmValue pool = {};
+  if (source) {
+    pool = source->GetProperty(pool_property);
+  }
+  if (!pool) {
+    pool = target->GetProperty(pool_property);
+  }
   if (pool) {
     vars["pool"] = *pool;
   }

+ 3 - 1
Source/cmNinjaTargetGenerator.h

@@ -236,8 +236,10 @@ protected:
   std::unique_ptr<cmOSXBundleGenerator> OSXBundleGenerator;
   std::set<std::string> MacContentFolders;
 
+  /// @param source may be nullptr.
   void addPoolNinjaVariable(std::string const& pool_property,
-                            cmGeneratorTarget* target, cmNinjaVars& vars);
+                            cmGeneratorTarget* target,
+                            cmSourceFile const* source, cmNinjaVars& vars);
 
   bool ForceResponseFile();
 

+ 1 - 0
Tests/RunCMake/Ninja/RunCMakeTest.cmake

@@ -100,6 +100,7 @@ run_cmake_with_options(CustomCommandDepfile -DCMAKE_BUILD_TYPE=Debug)
 run_cmake_with_options(CustomCommandDepfileAsOutput -DCMAKE_BUILD_TYPE=Debug)
 run_cmake_with_options(CustomCommandDepfileAsByproduct -DCMAKE_BUILD_TYPE=Debug)
 run_cmake(CustomCommandJobPool)
+run_cmake(SourceFileJobPool)
 run_cmake(JobPoolUsesTerminal)
 
 run_cmake(RspFileC)

+ 14 - 0
Tests/RunCMake/Ninja/SourceFileJobPool-check.cmake

@@ -0,0 +1,14 @@
+set(log "${RunCMake_BINARY_DIR}/SourceFileJobPool-build/build.ninja")
+file(READ "${log}" build_file)
+if(NOT "${build_file}" MATCHES "pool = source_file_compile_pool")
+  string(CONCAT RunCMake_TEST_FAILED "Log file:\n ${log}\n" "does not have expected line: pool = source_file_compile_pool")
+endif()
+if(NOT "${build_file}" MATCHES "pool = target_link_pool")
+  string(CONCAT RunCMake_TEST_FAILED "Log file:\n ${log}\n" "does not have expected line: pool = target_link_pool")
+endif()
+# Even though `target_compile_pool` was defined as the target's compile jobs pool, since the only sourcefile
+# of the target overrides it with `source_file_compile_pool` pool, the target compile job pool should not
+# exist in the generated Ninja file.
+if("${build_file}" MATCHES "pool = target_compile_pool")
+  string(CONCAT RunCMake_TEST_FAILED "Log file:\n ${log}\n" "have unexpected line: pool = target_compile_pool")
+endif()

+ 11 - 0
Tests/RunCMake/Ninja/SourceFileJobPool.cmake

@@ -0,0 +1,11 @@
+set_property(GLOBAL PROPERTY JOB_POOLS source_file_compile_pool=2 target_compile_pool=4 target_link_pool=1)
+
+enable_language(C)
+
+set_property(SOURCE hello.c PROPERTY JOB_POOL_COMPILE "source_file_compile_pool")
+
+add_executable(hello hello.c)
+set_property(TARGET hello PROPERTY JOB_POOL_COMPILE "target_compile_pool")
+set_property(TARGET hello PROPERTY JOB_POOL_LINK "target_link_pool")
+
+include(CheckNoPrefixSubDir.cmake)