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 `<LANG>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.
This commit is contained in:
Ben Boeckel
2023-01-31 22:13:56 -05:00
parent d19648a928
commit 837f7c113a
4 changed files with 9 additions and 4 deletions

View File

@@ -6,6 +6,9 @@
#include <sstream>
#include <utility>
#include <cm/string_view>
#include <cmext/string_view>
#include "cmComputeLinkInformation.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalCommonGenerator.h"
@@ -157,7 +160,7 @@ std::string cmCommonTargetGenerator::GetIncludes(std::string const& l,
}
std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories(
const std::string& config) const
const std::string& lang, const std::string& config) const
{
std::vector<std::string> dirs;
std::set<cmGeneratorTarget const*> emitted;
@@ -172,6 +175,8 @@ std::vector<std::string> 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(), '/',

View File

@@ -65,7 +65,7 @@ protected:
std::string GetAIXExports(std::string const& config);
std::vector<std::string> 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);

View File

@@ -1498,7 +1498,7 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
"set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES\n";
/* clang-format on */
std::vector<std::string> dirs =
this->GetLinkedTargetDirectories(this->GetConfigName());
this->GetLinkedTargetDirectories("Fortran", this->GetConfigName());
for (std::string const& d : dirs) {
*this->InfoFileStream << " \"" << d << "/DependInfo.cmake\"\n";
}

View File

@@ -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);
}