1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-19 19:43:23 +08:00

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
This commit is contained in:
Bastien Montagne
2025-07-09 11:04:45 +02:00
parent 44bf494fe6
commit 3a9d56d2c7
10 changed files with 75 additions and 10 deletions

View File

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

View File

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

View File

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

View File

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

View File

@@ -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(),

View File

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

View File

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

View File

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

View File

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

View File

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