Autogen: Restore target-ordering dependencies in Makefiles with DEPFILE

In commit aebfbcaa46 (AutoGen: Use depfiles for the XXX_autogen ninja
targets, 2020-01-14, v3.17.0-rc1~58^2) the `_autogen_timestamp_deps`
target was given target ordering dependencies through its custom command
rather than direct target dependencies as on the `_autogen` target.
Then commit 895fa3433f (cmQtAutoGenInitializer: support IMPLIB-only
imported targets, 2021-09-23, v3.22.0-rc1~80^2) converted some
target-level dependencies into file-level dependencies on the custom
command.  This only works with a monolithic build graph like Ninja.

Since commit ebc9e448b3 (Autogen: Add depfile support for Makefiles,
2023-09-07, v3.28.0-rc1~101^2~1) we use the `_autogen_timestamp_deps`
target in Makefile generators too.  This exposed the missing target
ordering dependency.

Fixes: #25766
This commit is contained in:
Brad King 2024-03-13 11:39:02 -04:00
parent 7a9fc8ca06
commit 6193d15556
7 changed files with 35 additions and 16 deletions

View File

@ -1386,27 +1386,19 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
const auto timestampTargetName =
cmStrCat(this->GenTarget->GetName(), "_autogen_timestamp_deps");
// Add additional autogen target dependencies to
// '_autogen_timestamp_deps'.
for (const cmTarget* t : this->AutogenTarget.DependTargets) {
std::string depname = t->GetName();
if (t->IsImported()) {
auto const ttype = t->GetType();
if (ttype == cmStateEnums::TargetType::STATIC_LIBRARY ||
ttype == cmStateEnums::TargetType::SHARED_LIBRARY ||
ttype == cmStateEnums::TargetType::UNKNOWN_LIBRARY) {
depname = cmStrCat("$<TARGET_LINKER_FILE:", t->GetName(), ">");
}
}
dependencies.emplace_back(std::move(depname));
}
auto cc = cm::make_unique<cmCustomCommand>();
cc->SetWorkingDirectory(this->Dir.Work.c_str());
cc->SetDepends(dependencies);
cc->SetEscapeOldStyle(false);
cmTarget* timestampTarget = this->LocalGen->AddUtilityCommand(
timestampTargetName, true, std::move(cc));
// Add additional autogen target dependencies to
// '_autogen_timestamp_deps'.
for (const cmTarget* t : this->AutogenTarget.DependTargets) {
timestampTarget->AddUtility(t->GetName(), false, this->Makefile);
}
auto const isMake =
this->GlobalGen->GetName().find("Make") != std::string::npos;
if (this->AutogenTarget.DependOrigin && isMake) {

View File

@ -8,4 +8,17 @@ add_custom_target(ProjectInfo
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/UpdateProjectInfo.cmake
BYPRODUCTS ${CMAKE_BINARY_DIR}/ProjectInfo.hpp)
set(ext_lib ${CMAKE_CURRENT_BINARY_DIR}/ext-build/${CMAKE_STATIC_LIBRARY_PREFIX}ext${CMAKE_STATIC_LIBRARY_SUFFIX})
include(ExternalProject)
ExternalProject_Add(ext_target
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ext-build"
DOWNLOAD_COMMAND ""
INSTALL_COMMAND ""
BUILD_BYPRODUCTS "${ext_lib}"
)
add_library(ext STATIC IMPORTED)
set_property(TARGET ext PROPERTY IMPORTED_LOCATION "${ext_lib}")
add_dependencies(ext ext_target)
add_subdirectory(src)

View File

@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.28)
project(Ext C)
add_library(ext STATIC ext.c)
set_property(TARGET ext PROPERTY ARCHIVE_OUTPUT_DIRECTORY "$<1:${CMAKE_CURRENT_BINARY_DIR}>")

View File

@ -0,0 +1,4 @@
int ext(void)
{
return 0;
}

View File

@ -2,3 +2,4 @@ add_executable(Exe main.cpp ${CMAKE_BINARY_DIR}/ProjectInfo.hpp)
add_dependencies(Exe ProjectInfo)
target_include_directories(Exe PRIVATE ${CMAKE_BINARY_DIR})
target_link_libraries(Exe PRIVATE ${QT_QTCORE_TARGET})
target_link_libraries(Exe PRIVATE ext)

View File

@ -1,5 +1,6 @@
#include "ProjectInfo.hpp"
extern "C" int ext();
int main(int argc, char* argv[])
{
return 0;
return ext();
}

View File

@ -2,7 +2,11 @@
ADD_AUTOGEN_TEST(AutogenOriginDependsOff autogenOriginDependsOff)
ADD_AUTOGEN_TEST(AutogenOriginDependsOn)
ADD_AUTOGEN_TEST(AutogenTargetDepends)
set(Autogen_CTEST_OPTIONS --build-target Exe)
ADD_AUTOGEN_TEST(AutogenTimestampDeps)
unset(Autogen_CTEST_OPTIONS)
ADD_AUTOGEN_TEST(AutoMocGeneratedFile)
ADD_AUTOGEN_TEST(Complex QtAutogen)
ADD_AUTOGEN_TEST(GlobalAutogenSystemUseInclude)