From 837f7c113a9333997304c3b5742c922617da23b5 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Tue, 31 Jan 2023 22:13:56 -0500 Subject: cmCommonTargetGenerator: classify linked target directories by language These directories are used to direct collators for Fortran and C++ modules to consume dependent module information to properly collate. However, the consumption of these files merely checks for existence of the file, not whether they are actually needed anymore. The problem arises when a target has Fortran or C++ modules at point A, a build occurs populating this file, and then the target is updated to no longer have potential modules. The `DependInfo.make` (for `Makefiles`) or `DependInfo.json` (for `Ninja`) files still exist as they are never guaranteed to be cleaned up. This can introduce stale information to the build which may cause a false-positive compilation if a module file happens to still exist and gets found this way. Instead, query the `linked-target-dirs` using the language in question and only add the directory if it contains potential sources for modules coming from the language in question. --- Source/cmCommonTargetGenerator.cxx | 7 ++++++- Source/cmCommonTargetGenerator.h | 2 +- Source/cmMakefileTargetGenerator.cxx | 2 +- Source/cmNinjaTargetGenerator.cxx | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 5fe6756b13..a065ba9499 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -6,6 +6,9 @@ #include #include +#include +#include + #include "cmComputeLinkInformation.h" #include "cmGeneratorTarget.h" #include "cmGlobalCommonGenerator.h" @@ -157,7 +160,7 @@ std::string cmCommonTargetGenerator::GetIncludes(std::string const& l, } std::vector cmCommonTargetGenerator::GetLinkedTargetDirectories( - const std::string& config) const + const std::string& lang, const std::string& config) const { std::vector dirs; std::set emitted; @@ -172,6 +175,8 @@ std::vector cmCommonTargetGenerator::GetLinkedTargetDirectories( // Target->GetLinkInformation already processed their // link interface and they don't have any output themselves. && linkee->GetType() != cmStateEnums::INTERFACE_LIBRARY && + ((lang == "CXX"_s && linkee->HaveCxx20ModuleSources()) || + (lang == "Fortran"_s && linkee->HaveFortranSources(config))) && emitted.insert(linkee).second) { cmLocalGenerator* lg = linkee->GetLocalGenerator(); std::string di = cmStrCat(lg->GetCurrentBinaryDirectory(), '/', diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h index e8c5a19f03..2d23037382 100644 --- a/Source/cmCommonTargetGenerator.h +++ b/Source/cmCommonTargetGenerator.h @@ -65,7 +65,7 @@ protected: std::string GetAIXExports(std::string const& config); std::vector GetLinkedTargetDirectories( - const std::string& config) const; + const std::string& lang, const std::string& config) const; std::string ComputeTargetCompilePDB(const std::string& config) const; std::string GetLinkerLauncher(const std::string& config); diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 4f80edcb5c..c40d6859ae 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -1498,7 +1498,7 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() "set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES\n"; /* clang-format on */ std::vector dirs = - this->GetLinkedTargetDirectories(this->GetConfigName()); + this->GetLinkedTargetDirectories("Fortran", this->GetConfigName()); for (std::string const& d : dirs) { *this->InfoFileStream << " \"" << d << "/DependInfo.cmake\"\n"; } diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 68873765e9..13782b0fa4 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -1675,7 +1675,7 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang, Json::Value& tdi_linked_target_dirs = tdi["linked-target-dirs"] = Json::arrayValue; - for (std::string const& l : this->GetLinkedTargetDirectories(config)) { + for (std::string const& l : this->GetLinkedTargetDirectories(lang, config)) { tdi_linked_target_dirs.append(l); } -- cgit v1.2.1