diff options
author | Brad King <brad.king@kitware.com> | 2023-03-10 11:47:24 -0500 |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2023-03-12 07:51:58 -0400 |
commit | d6353e74b4dc53b98943d5d66ab5ffb0bef04d08 (patch) | |
tree | 34aefc9b5c0bc8cba575968d9a245efd93330e5c | |
parent | 9db40bec4e1004baa8b397c8b52c248d8de71f67 (diff) | |
download | cmake-d6353e74b4dc53b98943d5d66ab5ffb0bef04d08.tar.gz |
VS: Add policy to build custom commands concurrently
In commit 33c15ae2b9 (VS: Build custom commands concurrently when
possible, 2023-01-19, v3.26.0-rc1~56^2) we added `BuildInParallel` to
custom commands in `.vcxproj` files, but that had to be reverted by
commit abb1c12162 (VS: Revert "Build custom commands concurrently when
possible", 2023-03-07, v3.26.0-rc6~3^2) because some projects may have
custom commands that accidentally rely on serial execution in MSBuild.
Add a policy to use `BuildInParallel` for custom commands in projects
that have been updated to set the policy to `NEW`.
Fixes: #18405
-rw-r--r-- | Help/manual/cmake-policies.7.rst | 1 | ||||
-rw-r--r-- | Help/policy/CMP0147.rst | 24 | ||||
-rw-r--r-- | Help/release/dev/vs-BuildInParallel.rst | 5 | ||||
-rw-r--r-- | Source/cmPolicies.h | 9 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 9 | ||||
-rw-r--r-- | Tests/RunCMake/VS10Project/CustomCommandParallel-check.cmake | 40 | ||||
-rw-r--r-- | Tests/RunCMake/VS10Project/CustomCommandParallel.cmake | 5 | ||||
-rw-r--r-- | Tests/RunCMake/VS10Project/RunCMakeTest.cmake | 3 |
8 files changed, 92 insertions, 4 deletions
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 811547baa1..a37a45c8c5 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -57,6 +57,7 @@ Policies Introduced by CMake 3.27 .. toctree:: :maxdepth: 1 + CMP0147: Visual Studio generators build custom commands in parallel. </policy/CMP0147> CMP0146: The FindCUDA module is removed. </policy/CMP0146> CMP0145: The Dart and FindDart modules are removed. </policy/CMP0145> CMP0144: find_package uses upper-case PACKAGENAME_ROOT variables. </policy/CMP0144> diff --git a/Help/policy/CMP0147.rst b/Help/policy/CMP0147.rst new file mode 100644 index 0000000000..0f25096633 --- /dev/null +++ b/Help/policy/CMP0147.rst @@ -0,0 +1,24 @@ +CMP0147 +------- + +.. versionadded:: 3.27 + +:ref:`Visual Studio Generators` build custom commands in parallel. + +Visual Studio 15.8 (2017) and newer support building custom commands in +parallel. CMake 3.27 and above prefer to enable this behavior by adding +a ``BuildInParallel`` setting to custom commands in ``.vcxproj`` files. +This policy provides compatibility for projects that have not been updated +to expect this, e.g., because their custom commands were accidentally +relying on serial execution by MSBuild. + +The ``OLD`` behavior for this policy is to not add ``BuildInParallel``. +The ``NEW`` behavior for this policy is to add ``BuildInParallel`` for +VS 15.8 and newer. + +This policy was introduced in CMake version 3.27. Use the +:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly. +Unlike many policies, CMake version |release| does *not* warn +when this policy is not set and simply uses ``OLD`` behavior. + +.. include:: DEPRECATED.txt diff --git a/Help/release/dev/vs-BuildInParallel.rst b/Help/release/dev/vs-BuildInParallel.rst new file mode 100644 index 0000000000..ef344c7135 --- /dev/null +++ b/Help/release/dev/vs-BuildInParallel.rst @@ -0,0 +1,5 @@ +vs-BuildInParallel +------------------ + +* :ref:`Visual Studio Generators`, for VS 15.8 (2017) and newer, now + build custom commands in parallel. See policy :policy:`CMP0147`. diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 06ac21ea21..52993b8708 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -441,7 +441,10 @@ class cmMakefile; SELECT(POLICY, CMP0145, "The Dart and FindDart modules are removed.", 3, \ 27, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0146, "The FindCUDA module is removed.", 3, 27, 0, \ - cmPolicies::WARN) + cmPolicies::WARN) \ + SELECT(POLICY, CMP0147, \ + "Visual Studio generators build custom commands in parallel.", 3, \ + 27, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ @@ -481,7 +484,9 @@ class cmMakefile; F(CMP0131) \ F(CMP0142) -#define CM_FOR_EACH_CUSTOM_COMMAND_POLICY(F) F(CMP0116) +#define CM_FOR_EACH_CUSTOM_COMMAND_POLICY(F) \ + F(CMP0116) \ + F(CMP0147) /** \class cmPolicies * \brief Handles changes in CMake behavior and policies diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index a669152b24..ef0fcf3162 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1810,10 +1810,15 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( this->WriteCustomRuleCSharp(e0, c, name, script, additional_inputs.str(), outputs.str(), comment, ccg); } else { - // FIXME(#18405): Enable BuildInParallel::Yes via an option or policy. + BuildInParallel buildInParallel = BuildInParallel::No; + if (command.GetCMP0147Status() == cmPolicies::NEW && + !command.GetUsesTerminal() && + !(command.HasMainDependency() && source->GetIsGenerated())) { + buildInParallel = BuildInParallel::Yes; + } this->WriteCustomRuleCpp(*spe2, c, script, additional_inputs.str(), outputs.str(), comment, ccg, symbolic, - BuildInParallel::No); + buildInParallel); } } } diff --git a/Tests/RunCMake/VS10Project/CustomCommandParallel-check.cmake b/Tests/RunCMake/VS10Project/CustomCommandParallel-check.cmake new file mode 100644 index 0000000000..87e2f704d2 --- /dev/null +++ b/Tests/RunCMake/VS10Project/CustomCommandParallel-check.cmake @@ -0,0 +1,40 @@ +set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj") +if(NOT EXISTS "${vcProjectFile}") + set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.") + return() +endif() + +set(found_CustomBuild_cmp0147_new 0) +set(found_CustomBuild_cmp0147_old 0) +set(found_BuildInParallel_cmp0147_new 0) +set(found_BuildInParallel_cmp0147_old 0) +set(in_CustomBuild_cmp0147 "") +file(STRINGS "${vcProjectFile}" lines) +foreach(line IN LISTS lines) + if(line MATCHES [[<CustomBuild Include=".*\\cmp0147-old\.txt\.rule">]]) + set(found_CustomBuild_cmp0147_old 1) + set(in_CustomBuild_cmp0147 "old") + endif() + if(line MATCHES [[<CustomBuild Include=".*\\cmp0147-new\.txt\.rule">]]) + set(found_CustomBuild_cmp0147_new 1) + set(in_CustomBuild_cmp0147 "new") + endif() + if(line MATCHES [[</CustomBuild>]]) + set(in_CustomBuild_cmp0147 "") + endif() + if(line MATCHES [[<BuildInParallel .*>true</BuildInParallel>]] AND in_CustomBuild_cmp0147) + set(found_BuildInParallel_cmp0147_${in_CustomBuild_cmp0147} 1) + endif() +endforeach() +if(NOT found_CustomBuild_cmp0147_new) + string(APPEND RunCMake_TEST_FAILED "CustomBuild for cmp0147-new.txt.rule not found in\n ${vcProjectFile}\n") +endif() +if(NOT found_CustomBuild_cmp0147_old) + string(APPEND RunCMake_TEST_FAILED "CustomBuild for cmp0147-old.txt.rule not found in\n ${vcProjectFile}\n") +endif() +if(NOT found_BuildInParallel_cmp0147_new) + string(APPEND RunCMake_TEST_FAILED "BuildInParallel for cmp0147-new.txt.rule not found in\n ${vcProjectFile}\n") +endif() +if(found_BuildInParallel_cmp0147_old) + string(APPEND RunCMake_TEST_FAILED "BuildInParallel for cmp0147-old.txt.rule incorrectly found in\n ${vcProjectFile}\n") +endif() diff --git a/Tests/RunCMake/VS10Project/CustomCommandParallel.cmake b/Tests/RunCMake/VS10Project/CustomCommandParallel.cmake new file mode 100644 index 0000000000..784fc685b5 --- /dev/null +++ b/Tests/RunCMake/VS10Project/CustomCommandParallel.cmake @@ -0,0 +1,5 @@ +cmake_policy(VERSION 3.26) # CMP0147 left unset +add_custom_command(OUTPUT "cmp0147-old.txt" COMMAND echo) +cmake_policy(SET CMP0147 NEW) +add_custom_command(OUTPUT "cmp0147-new.txt" COMMAND echo) +add_custom_target(foo DEPENDS "cmp0147-old.txt" "cmp0147-new.txt") diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake index ed74896370..669049a737 100644 --- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake +++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake @@ -8,6 +8,9 @@ if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND CMAKE_C_COMPILER_VERSION VERSION_GREA endif() run_cmake(CustomCommandGenex) +if(NOT RunCMake_GENERATOR MATCHES "^Visual Studio 1[1-5] ") + run_cmake(CustomCommandParallel) +endif() run_cmake(VsCsharpSourceGroup) run_cmake(VsCSharpCompilerOpts) run_cmake(ExplicitCMakeLists) |