Ninja Multi-Config: Run POST_BUILD when BYPRODUCTS don't overlap
Fixes: #21252
This commit is contained in:
parent
1c9b61c23e
commit
98805a11ce
@ -130,3 +130,34 @@ output config using the ``Release`` command config. The ``Release`` build of
|
|||||||
the ``generator`` target is called with ``Debug.txt Debug Release`` as
|
the ``generator`` target is called with ``Debug.txt Debug Release`` as
|
||||||
arguments. The command depends on the ``Release`` builds of ``tgt1`` and
|
arguments. The command depends on the ``Release`` builds of ``tgt1`` and
|
||||||
``tgt4``, and the ``Debug`` builds of ``tgt2`` and ``tgt3``.
|
``tgt4``, and the ``Debug`` builds of ``tgt2`` and ``tgt3``.
|
||||||
|
|
||||||
|
``PRE_BUILD``, ``PRE_LINK``, and ``POST_BUILD`` custom commands for targets
|
||||||
|
only get run in their "native" configuration (the ``Release`` configuration in
|
||||||
|
the ``build-Release.ninja`` file) unless they have no ``BYPRODUCTS`` or their
|
||||||
|
``BYPRODUCTS`` are unique per config. Consider the following example:
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
add_executable(exe main.c)
|
||||||
|
add_custom_command(
|
||||||
|
TARGET exe
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "Running no-byproduct command"
|
||||||
|
)
|
||||||
|
add_custom_command(
|
||||||
|
TARGET exe
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "Running separate-byproduct command for $<CONFIG>"
|
||||||
|
BYPRODUCTS $<CONFIG>.txt
|
||||||
|
)
|
||||||
|
add_custom_command(
|
||||||
|
TARGET exe
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "Running common-byproduct command for $<CONFIG>"
|
||||||
|
BYPRODUCTS exe.txt
|
||||||
|
)
|
||||||
|
|
||||||
|
In this example, if you build ``exe:Debug`` in ``build-Release.ninja``, the
|
||||||
|
first and second custom commands get run, since their byproducts are unique
|
||||||
|
per-config, but the last custom command does not. However, if you build
|
||||||
|
``exe:Release`` in ``build-Release.ninja``, all three custom commands get run.
|
||||||
|
@ -693,13 +693,11 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
bool cmLocalNinjaGenerator::HasUniqueByproducts(
|
||||||
bool HasUniqueByproducts(cmLocalGenerator& lg,
|
std::vector<std::string> const& byproducts, cmListFileBacktrace const& bt)
|
||||||
std::vector<std::string> const& byproducts,
|
|
||||||
cmListFileBacktrace const& bt)
|
|
||||||
{
|
{
|
||||||
std::vector<std::string> configs =
|
std::vector<std::string> configs =
|
||||||
lg.GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
|
this->GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
|
||||||
cmGeneratorExpression ge(bt);
|
cmGeneratorExpression ge(bt);
|
||||||
for (std::string const& p : byproducts) {
|
for (std::string const& p : byproducts) {
|
||||||
if (cmGeneratorExpression::Find(p) == std::string::npos) {
|
if (cmGeneratorExpression::Find(p) == std::string::npos) {
|
||||||
@ -709,7 +707,7 @@ bool HasUniqueByproducts(cmLocalGenerator& lg,
|
|||||||
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(p);
|
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(p);
|
||||||
for (std::string const& config : configs) {
|
for (std::string const& config : configs) {
|
||||||
for (std::string const& b :
|
for (std::string const& b :
|
||||||
lg.ExpandCustomCommandOutputPaths(*cge, config)) {
|
this->ExpandCustomCommandOutputPaths(*cge, config)) {
|
||||||
if (!seen.insert(b).second) {
|
if (!seen.insert(b).second) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -719,6 +717,7 @@ bool HasUniqueByproducts(cmLocalGenerator& lg,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
bool HasUniqueOutputs(std::vector<cmCustomCommandGenerator> const& ccgs)
|
bool HasUniqueOutputs(std::vector<cmCustomCommandGenerator> const& ccgs)
|
||||||
{
|
{
|
||||||
std::set<std::string> allOutputs;
|
std::set<std::string> allOutputs;
|
||||||
@ -746,7 +745,7 @@ std::string cmLocalNinjaGenerator::CreateUtilityOutput(
|
|||||||
// In Ninja Multi-Config, we can only produce cross-config utility
|
// In Ninja Multi-Config, we can only produce cross-config utility
|
||||||
// commands if all byproducts are per-config.
|
// commands if all byproducts are per-config.
|
||||||
if (!this->GetGlobalGenerator()->IsMultiConfig() ||
|
if (!this->GetGlobalGenerator()->IsMultiConfig() ||
|
||||||
!HasUniqueByproducts(*this, byproducts, bt)) {
|
!this->HasUniqueByproducts(byproducts, bt)) {
|
||||||
return this->cmLocalGenerator::CreateUtilityOutput(targetName, byproducts,
|
return this->cmLocalGenerator::CreateUtilityOutput(targetName, byproducts,
|
||||||
bt);
|
bt);
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,9 @@ public:
|
|||||||
cmNinjaDeps& ninjaDeps,
|
cmNinjaDeps& ninjaDeps,
|
||||||
const std::string& config);
|
const std::string& config);
|
||||||
|
|
||||||
|
bool HasUniqueByproducts(std::vector<std::string> const& byproducts,
|
||||||
|
cmListFileBacktrace const& bt);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string ConvertToIncludeReference(
|
std::string ConvertToIncludeReference(
|
||||||
std::string const& path,
|
std::string const& path,
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <cm/memory>
|
#include <cm/memory>
|
||||||
|
#include <cm/optional>
|
||||||
#include <cm/vector>
|
#include <cm/vector>
|
||||||
|
|
||||||
#include "cmComputeLinkInformation.h"
|
#include "cmComputeLinkInformation.h"
|
||||||
@ -1238,14 +1239,17 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
|
|||||||
std::vector<std::string> preLinkCmdLines;
|
std::vector<std::string> preLinkCmdLines;
|
||||||
std::vector<std::string> postBuildCmdLines;
|
std::vector<std::string> postBuildCmdLines;
|
||||||
|
|
||||||
if (config == fileConfig) {
|
std::vector<std::string>* cmdLineLists[3] = { &preLinkCmdLines,
|
||||||
std::vector<std::string>* cmdLineLists[3] = { &preLinkCmdLines,
|
&preLinkCmdLines,
|
||||||
&preLinkCmdLines,
|
&postBuildCmdLines };
|
||||||
&postBuildCmdLines };
|
|
||||||
|
|
||||||
for (unsigned i = 0; i != 3; ++i) {
|
for (unsigned i = 0; i != 3; ++i) {
|
||||||
for (cmCustomCommand const& cc : *cmdLists[i]) {
|
for (cmCustomCommand const& cc : *cmdLists[i]) {
|
||||||
cmCustomCommandGenerator ccg(cc, config, this->GetLocalGenerator());
|
if (config == fileConfig ||
|
||||||
|
this->GetLocalGenerator()->HasUniqueByproducts(cc.GetByproducts(),
|
||||||
|
cc.GetBacktrace())) {
|
||||||
|
cmCustomCommandGenerator ccg(cc, fileConfig, this->GetLocalGenerator(),
|
||||||
|
true, config);
|
||||||
localGen.AppendCustomCommandLines(ccg, *cmdLineLists[i]);
|
localGen.AppendCustomCommandLines(ccg, *cmdLineLists[i]);
|
||||||
std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
|
std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
|
||||||
std::transform(ccByproducts.begin(), ccByproducts.end(),
|
std::transform(ccByproducts.begin(), ccByproducts.end(),
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
Running post-build command with Debug
|
||||||
|
Generating Debug\.txt
|
@ -0,0 +1,3 @@
|
|||||||
|
Running post-build command with Release
|
||||||
|
Generating out\.txt with Release
|
||||||
|
Generating Release\.txt
|
6
Tests/RunCMake/NinjaMultiConfig/PostBuild.cmake
Normal file
6
Tests/RunCMake/NinjaMultiConfig/PostBuild.cmake
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
enable_language(C)
|
||||||
|
|
||||||
|
add_executable(Exe main.c)
|
||||||
|
add_custom_command(TARGET Exe POST_BUILD COMMAND ${CMAKE_COMMAND} -E echo "Running post-build command with $<CONFIG>")
|
||||||
|
add_custom_command(TARGET Exe POST_BUILD COMMAND ${CMAKE_COMMAND} -E echo "Generating out.txt with $<CONFIG>" BYPRODUCTS out.txt)
|
||||||
|
add_custom_command(TARGET Exe POST_BUILD COMMAND ${CMAKE_COMMAND} -E echo "Generating $<CONFIG>.txt" BYPRODUCTS $<CONFIG>.txt)
|
@ -187,6 +187,12 @@ run_ninja(SimpleCrossConfigs clean-all-in-release-graph build-Release.ninja clea
|
|||||||
run_cmake_build(SimpleCrossConfigs all-all-in-release-graph Release all:all)
|
run_cmake_build(SimpleCrossConfigs all-all-in-release-graph Release all:all)
|
||||||
run_cmake_build(SimpleCrossConfigs all-relwithdebinfo-in-release-graph Release all:RelWithDebInfo)
|
run_cmake_build(SimpleCrossConfigs all-relwithdebinfo-in-release-graph Release all:RelWithDebInfo)
|
||||||
|
|
||||||
|
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/PostBuild-build)
|
||||||
|
set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
|
||||||
|
run_cmake_configure(PostBuild)
|
||||||
|
run_cmake_build(PostBuild release Release Exe)
|
||||||
|
run_cmake_build(PostBuild debug-in-release-graph Release Exe:Debug)
|
||||||
|
|
||||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Framework-build)
|
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Framework-build)
|
||||||
set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
|
set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
|
||||||
run_cmake_configure(Framework)
|
run_cmake_configure(Framework)
|
||||||
|
Loading…
Reference in New Issue
Block a user