Restore support for TARGET_OBJECTS in link interfaces with unity builds

This was broken by commit df08c37a42 (cmGlobalGenerator: Add unity/pch
sources after computing compile features, 2024-02-02, v3.28.3~1^2~1^2),
and 3.28.2's commit 76b5383123 (cmGlobalGenerator: add unity sources
after computing target compile features, 2024-01-01, v3.28.2~17^2~1).

The problem is very similar to that fixed by commit 4e8f24e977 (PCH:
Clear link interface cache when adding PCH object to it, 2022-01-24,
v3.23.0-rc1~44^2~9).  Generalize that fix.

Fixes: #25696
This commit is contained in:
Brad King
2024-02-21 16:00:42 -05:00
parent 1313c78a9c
commit 5b8e9e068f
8 changed files with 44 additions and 6 deletions

View File

@@ -721,7 +721,10 @@ public:
*/
void ClearSourcesCache();
// Do not use. This is only for a specific call site with a FIXME comment.
/**
* Clears cached evaluations of INTERFACE_LINK_LIBRARIES.
* They will be recomputed on demand.
*/
void ClearLinkInterfaceCache();
void AddSource(const std::string& src, bool before = false);

View File

@@ -1897,9 +1897,13 @@ bool cmGlobalGenerator::AddAutomaticSources()
// Clear the source list and classification cache (KindedSources) of all
// targets so that it will be recomputed correctly by the generators later
// now that the above transformations are done for all targets.
// Also clear the link interface cache to support $<TARGET_OBJECTS:objlib>
// in INTERFACE_LINK_LIBRARIES because the list of object files may have
// been changed by conversion to a unity build or addition of a PCH source.
for (const auto& lg : this->LocalGenerators) {
for (const auto& gt : lg->GetGeneratorTargets()) {
gt->ClearSourcesCache();
gt->ClearLinkInterfaceCache();
}
}
return true;

View File

@@ -2831,15 +2831,10 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
cm::nullopt, true);
} else if (reuseTarget->GetType() ==
cmStateEnums::OBJECT_LIBRARY) {
// FIXME: This can propagate more than one level, unlike
// the rest of the object files in an object library.
// Find another way to do this.
target->Target->AppendProperty(
"INTERFACE_LINK_LIBRARIES",
cmStrCat("$<$<CONFIG:", config,
">:$<LINK_ONLY:", pchSourceObj, ">>"));
// We updated the link interface, so ensure it is recomputed.
target->ClearLinkInterfaceCache();
}
}
} else {

View File

@@ -6,3 +6,11 @@ run_cmake(NotObjlibTarget)
if(RunCMake_GENERATOR STREQUAL "Xcode" AND "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]")
run_cmake(XcodeVariableNoGenexExpansion)
endif()
function(run_cmake_and_build case)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
run_cmake(${case})
set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(${case}-build ${CMAKE_COMMAND} --build .)
endfunction()
run_cmake_and_build(Unity)

View File

@@ -0,0 +1,13 @@
enable_language(C)
# Test transforming the set of object files provided by an object library.
set(CMAKE_UNITY_BUILD 1)
add_library(UnityObj1 OBJECT UnityObj1.c)
add_library(UnityObj2 OBJECT UnityObj2.c)
add_library(UnityObj2Iface INTERFACE)
target_link_libraries(UnityObj2Iface INTERFACE $<TARGET_OBJECTS:UnityObj2>)
add_executable(UnityMain UnityMain.c)
target_link_libraries(UnityMain PRIVATE UnityObj1 UnityObj2Iface)

View File

@@ -0,0 +1,7 @@
extern int UnityObj1(void);
extern int UnityObj2(void);
int main(void)
{
return UnityObj1() + UnityObj2();
}

View File

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

View File

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