OPTIMIZE_DEPENDENCIES: Skip order-only deps for non-linking targets

Fixes: #21517
This commit is contained in:
Craig Scott
2023-08-04 16:34:35 +10:00
parent 21edd5af1f
commit 84eae7aeda
11 changed files with 76 additions and 3 deletions

View File

@@ -1224,6 +1224,11 @@ bool cmGeneratorTarget::IsNormal() const
return this->Target->IsNormal();
}
bool cmGeneratorTarget::IsRuntimeBinary() const
{
return this->Target->IsRuntimeBinary();
}
bool cmGeneratorTarget::IsSynthetic() const
{
return this->Target->IsSynthetic();

View File

@@ -51,6 +51,7 @@ public:
bool IsInBuildSystem() const;
bool IsNormal() const;
bool IsRuntimeBinary() const;
bool IsSynthetic() const;
bool IsImported() const;
bool IsImportedGloballyVisible() const;

View File

@@ -1469,9 +1469,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
gt, linkBuild.OrderOnlyDeps, config, fileConfig, DependOnTargetArtifact);
// Add order-only dependencies on versioning symlinks of shared libs we link.
if (!this->GeneratorTarget->IsDLLPlatform()) {
if (cmComputeLinkInformation* cli =
this->GeneratorTarget->GetLinkInformation(config)) {
// If our target is not producing a runtime binary, it doesn't need the
// symlinks (anything that links to the target might, but that consumer will
// get its own order-only dependency).
if (!gt->IsDLLPlatform() && gt->IsRuntimeBinary()) {
if (cmComputeLinkInformation* cli = gt->GetLinkInformation(config)) {
for (auto const& item : cli->GetItems()) {
if (item.Target &&
item.Target->GetType() == cmStateEnums::SHARED_LIBRARY &&

View File

@@ -2652,6 +2652,24 @@ bool cmTarget::IsPerConfig() const
return this->impl->PerConfig;
}
bool cmTarget::IsRuntimeBinary() const
{
switch (this->GetType()) {
case cmStateEnums::EXECUTABLE:
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
return true;
case cmStateEnums::OBJECT_LIBRARY:
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::UTILITY:
case cmStateEnums::INTERFACE_LIBRARY:
case cmStateEnums::GLOBAL_TARGET:
case cmStateEnums::UNKNOWN_LIBRARY:
break;
}
return false;
}
bool cmTarget::CanCompileSources() const
{
if (this->IsImported()) {

View File

@@ -212,6 +212,7 @@ public:
bool IsImported() const;
bool IsImportedGloballyVisible() const;
bool IsPerConfig() const;
bool IsRuntimeBinary() const;
bool CanCompileSources() const;
bool GetMappedConfig(std::string const& desired_config, cmValue& loc,

View File

@@ -59,3 +59,5 @@ run_optimize_test(OptimizeStatic StaticTop)
if(CMAKE_Fortran_COMPILER)
run_optimize_test(OptimizeFortran FortranTop)
endif()
run_cmake_build(RuntimeTargets mylib SharedTop)

View File

@@ -0,0 +1,18 @@
enable_language(C)
set(CMAKE_OPTIMIZE_DEPENDENCIES TRUE)
add_library(mylib STATIC mylib.c)
add_library(neverbuild SHARED neverbuild.c)
# Building mylib should not require building neverbuild
target_link_libraries(mylib PRIVATE neverbuild)
set_target_properties(neverbuild PROPERTIES EXCLUDE_FROM_ALL YES)
# Building SharedTop should require SharedBottom to be built
add_library(SharedTop SHARED top.c)
add_library(StaticMiddle STATIC middle.c)
add_library(SharedBottom SHARED bottom.c)
target_link_libraries(SharedTop PRIVATE StaticMiddle)
target_link_libraries(StaticMiddle PRIVATE SharedBottom)
set_target_properties(StaticMiddle SharedBottom PROPERTIES EXCLUDE_FROM_ALL YES)
set_target_properties(StaticMiddle PROPERTIES POSITION_INDEPENDENT_CODE YES)

View File

@@ -0,0 +1,7 @@
#ifdef _WIN32
__declspec(dllexport)
#endif
int bottom(void)
{
return 23;
}

View File

@@ -0,0 +1,9 @@
#ifdef _WIN32
__declspec(dllimport)
#endif
int bottom(void);
int middle(void)
{
return bottom() + 19;
}

View File

@@ -0,0 +1 @@
#error I should not be built

View File

@@ -0,0 +1,9 @@
int middle(void);
#ifdef _WIN32
__declspec(dllexport)
#endif
int top(void)
{
return middle() + 2;
}