mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
Ninja: Account for explicit target dependencies via CODEGEN
When a "normal" target (e.g., an executable) depends on a custom target
that is not part of `all`, and that custom target owns the output of a
custom command marked `CODEGEN`, an explicit `add_dependencies` from
the normal to custom target must be incorporated in `codegen`.
Amends commit 197cb419d1 (add_custom_command: Add CODEGEN support,
2024-05-27, v3.31.0-rc1~394^2), which already incorporated such logic
in the Unix Makefile generator, but was not tested nor implemented for
Ninja.
Fixes: #28092
This commit is contained in:
@@ -1558,6 +1558,21 @@ void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
|
||||
outputs.insert(outs.begin(), outs.end());
|
||||
}
|
||||
|
||||
void cmGlobalNinjaGenerator::AppendCodegenTargetDepends(
|
||||
cmGeneratorTarget const* target, cmNinjaDeps& deps,
|
||||
std::string const& config) const
|
||||
{
|
||||
std::set<std::string> const& codegenDeps = target->Target->GetCodegenDeps();
|
||||
for (cmTargetDepend const& targetDep :
|
||||
this->GetTargetDirectDepends(target)) {
|
||||
if (targetDep->IsInBuildSystem() &&
|
||||
codegenDeps.count(targetDep->GetName())) {
|
||||
this->AppendTargetOutputs(targetDep, deps, config,
|
||||
DependOnTargetArtifact);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cmGlobalNinjaGenerator::AddTargetAlias(std::string const& alias,
|
||||
cmGeneratorTarget* target,
|
||||
std::string const& config)
|
||||
@@ -1727,6 +1742,9 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os)
|
||||
if (this->IsExcludedFromAllInConfig(t, config)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this->AppendCodegenTargetDepends(t.GT, build.ExplicitDeps, config);
|
||||
|
||||
std::vector<cmSourceFile const*> customCommandSources;
|
||||
t.GT->GetCustomCommands(customCommandSources, config);
|
||||
for (cmSourceFile const* sf : customCommandSources) {
|
||||
|
||||
@@ -524,6 +524,10 @@ private:
|
||||
void CloseRulesFileStream();
|
||||
void CleanMetaData();
|
||||
|
||||
void AppendCodegenTargetDepends(cmGeneratorTarget const* target,
|
||||
cmNinjaDeps& deps,
|
||||
std::string const& config) const;
|
||||
|
||||
/// Write the common disclaimer text at the top of each build file.
|
||||
void WriteDisclaimer(std::ostream& os) const;
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ run_codegen("min-graph-3")
|
||||
run_codegen("add-dependencies")
|
||||
run_codegen("add-custom-command-depends")
|
||||
run_codegen("byproducts")
|
||||
run_codegen("add-dependencies-not-all")
|
||||
|
||||
# Error handling
|
||||
run_cmake("implicit-depends")
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
set(filename "${RunCMake_TEST_BINARY_DIR}/generated.h")
|
||||
if (NOT EXISTS "${filename}")
|
||||
set(RunCMake_TEST_FAILED "expected file NOT created:\n ${filename}")
|
||||
return()
|
||||
endif()
|
||||
@@ -0,0 +1,17 @@
|
||||
add_executable(main
|
||||
main.c
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT generated.h
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/generated.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/generated.h
|
||||
CODEGEN
|
||||
)
|
||||
|
||||
# N.B. h_creator is *not* added to ALL.
|
||||
add_custom_target(h_creator DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated.h)
|
||||
|
||||
# This test will fail if add_dependencies isn't accounted for in the
|
||||
# codegen build graph
|
||||
add_dependencies(main h_creator)
|
||||
@@ -13,6 +13,6 @@ add_custom_command(
|
||||
|
||||
add_custom_target(hpp_creator ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated.hpp)
|
||||
|
||||
# This test will fail if add_dependencies isn't account for in the
|
||||
# This test will fail if add_dependencies isn't accounted for in the
|
||||
# codegen build graph
|
||||
add_dependencies(hpp_creator foobar)
|
||||
|
||||
Reference in New Issue
Block a user