summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-11-27 13:36:28 (GMT)
committerKitware Robot <kwrobot@kitware.com>2023-11-27 13:36:44 (GMT)
commit4b2960b1f3e214dd30b32925b00eef5f64b99b71 (patch)
tree106a8dc355a73556244ba1701b38faab5181a240
parent66149dd1a93f4f22f68d7465de74b14d7c03f89d (diff)
parentbeb1393f8f29302197b80741bec41a13b7f207c7 (diff)
downloadCMake-4b2960b1f3e214dd30b32925b00eef5f64b99b71.zip
CMake-4b2960b1f3e214dd30b32925b00eef5f64b99b71.tar.gz
CMake-4b2960b1f3e214dd30b32925b00eef5f64b99b71.tar.bz2
Merge topic 'fortran-objects-as-sources-fix' into release-3.28
beb1393f8f Merge branch 'revert-exact-collation-depends-3.27' into fortran-objects-as-sources-fix a033dce326 Makefiles: provide, but do not consume, "forward linked" target dirs 7cd0adab1b cmCommonTargetGenerator: use modules from linked object-referenced targets 1175f1c874 LinkItem: track `cmSourceFile` instances for external objects d2fa56772f Ninja: support "forwarding" modules from other targets ec1e589bec Ninja: Revert exact collation dependencies for 3.27 06df59b930 cmCommonTargetGenerator: return forward linked target dirs too f8729ab366 cmLocalUnixMakefileGenerator3: handle object-referencing Fortran modules ... Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: buildbot <buildbot@kitware.com> Merge-request: !8989
-rw-r--r--Source/cmCommonTargetGenerator.cxx90
-rw-r--r--Source/cmCommonTargetGenerator.h11
-rw-r--r--Source/cmComputeLinkDepends.cxx1
-rw-r--r--Source/cmComputeLinkDepends.h4
-rw-r--r--Source/cmComputeLinkInformation.cxx26
-rw-r--r--Source/cmComputeLinkInformation.h6
-rw-r--r--Source/cmDependsFortran.cxx6
-rw-r--r--Source/cmGeneratorTarget.cxx87
-rw-r--r--Source/cmGeneratorTarget.h5
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx59
-rw-r--r--Source/cmGlobalNinjaGenerator.h1
-rw-r--r--Source/cmLinkItem.h4
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx11
-rw-r--r--Source/cmMakefile.cxx3
-rw-r--r--Source/cmMakefileTargetGenerator.cxx15
-rw-r--r--Source/cmNinjaTargetGenerator.cxx30
-rw-r--r--Tests/FortranModules/CMakeLists.txt6
-rw-r--r--Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/CMakeLists.txt7
-rw-r--r--Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/dummy.f903
-rw-r--r--Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/subdir/CMakeLists.txt1
-rw-r--r--Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/subdir/obj.f9011
-rw-r--r--Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/use.f9013
-rw-r--r--Tests/FortranModules/ModulesViaSubdirTargetObjectsSource/CMakeLists.txt6
-rw-r--r--Tests/FortranModules/ModulesViaSubdirTargetObjectsSource/subdir/CMakeLists.txt1
-rw-r--r--Tests/FortranModules/ModulesViaSubdirTargetObjectsSource/subdir/obj.f9011
-rw-r--r--Tests/FortranModules/ModulesViaSubdirTargetObjectsSource/use.f9013
-rw-r--r--Tests/FortranModules/ModulesViaTargetObjectsLink/CMakeLists.txt5
-rw-r--r--Tests/FortranModules/ModulesViaTargetObjectsLink/dummy.f903
-rw-r--r--Tests/FortranModules/ModulesViaTargetObjectsLink/obj.f9011
-rw-r--r--Tests/FortranModules/ModulesViaTargetObjectsLink/use.f9013
-rw-r--r--Tests/FortranModules/ModulesViaTargetObjectsSource/CMakeLists.txt4
-rw-r--r--Tests/FortranModules/ModulesViaTargetObjectsSource/obj.f9011
-rw-r--r--Tests/FortranModules/ModulesViaTargetObjectsSource/use.f9013
-rw-r--r--Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-private.json1
-rw-r--r--Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-public.json1
-rw-r--r--Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-private.json1
-rw-r--r--Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-public.json1
-rw-r--r--Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-private.json1
-rw-r--r--Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-public.json1
39 files changed, 419 insertions, 78 deletions
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index a29dd76..90f0d55 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -163,43 +163,77 @@ std::string cmCommonTargetGenerator::GetIncludes(std::string const& l,
return i->second;
}
-std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories(
+cmCommonTargetGenerator::LinkedTargetDirs
+cmCommonTargetGenerator::GetLinkedTargetDirectories(
const std::string& lang, const std::string& config) const
{
- std::vector<std::string> dirs;
- std::set<cmGeneratorTarget const*> emitted;
+ LinkedTargetDirs dirs;
+ std::set<cmGeneratorTarget const*> forward_emitted;
+ std::set<cmGeneratorTarget const*> direct_emitted;
cmGlobalCommonGenerator* const gg = this->GlobalCommonGenerator;
+
+ enum class Forwarding
+ {
+ Yes,
+ No
+ };
+
if (cmComputeLinkInformation* cli =
this->GeneratorTarget->GetLinkInformation(config)) {
- auto addLinkedTarget = [this, &lang, &config, &dirs, &emitted,
- gg](cmGeneratorTarget const* linkee) {
- if (linkee &&
- !linkee->IsImported()
- // Skip targets that build after this one in a static lib cycle.
- && gg->TargetOrderIndexLess(linkee, this->GeneratorTarget)
- // We can ignore the INTERFACE_LIBRARY items because
- // Target->GetLinkInformation already processed their
- // link interface and they don't have any output themselves.
- && (linkee->GetType() != cmStateEnums::INTERFACE_LIBRARY
- // Synthesized targets may have relevant rules.
- || linkee->IsSynthetic()) &&
- ((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(), '/',
- lg->GetTargetDirectory(linkee));
- if (lg->GetGlobalGenerator()->IsMultiConfig()) {
- di = cmStrCat(di, '/', config);
+ auto addLinkedTarget =
+ [this, &lang, &config, &dirs, &direct_emitted, &forward_emitted,
+ gg](cmGeneratorTarget const* linkee, Forwarding forward) {
+ if (linkee &&
+ !linkee->IsImported()
+ // Skip targets that build after this one in a static lib cycle.
+ && gg->TargetOrderIndexLess(linkee, this->GeneratorTarget)
+ // We can ignore the INTERFACE_LIBRARY items because
+ // Target->GetLinkInformation already processed their
+ // link interface and they don't have any output themselves.
+ && (linkee->GetType() != cmStateEnums::INTERFACE_LIBRARY
+ // Synthesized targets may have relevant rules.
+ || linkee->IsSynthetic()) &&
+ ((lang == "CXX"_s && linkee->HaveCxx20ModuleSources()) ||
+ (lang == "Fortran"_s && linkee->HaveFortranSources(config)))) {
+ cmLocalGenerator* lg = linkee->GetLocalGenerator();
+ std::string di = cmStrCat(lg->GetCurrentBinaryDirectory(), '/',
+ lg->GetTargetDirectory(linkee));
+ if (lg->GetGlobalGenerator()->IsMultiConfig()) {
+ di = cmStrCat(di, '/', config);
+ }
+ if (forward == Forwarding::Yes &&
+ forward_emitted.insert(linkee).second) {
+ dirs.Forward.push_back(di);
+ }
+ if (direct_emitted.insert(linkee).second) {
+ dirs.Direct.emplace_back(di);
+ }
}
- dirs.push_back(std::move(di));
- }
- };
+ };
for (auto const& item : cli->GetItems()) {
- addLinkedTarget(item.Target);
+ if (item.Target) {
+ addLinkedTarget(item.Target, Forwarding::No);
+ } else if (item.ObjectSource && lang == "Fortran"_s
+ /* Object source files do not have a language associated with
+ them. */
+ /* && item.ObjectSource->GetLanguage() == "Fortran"_s*/) {
+ // Fortran modules provided by `$<TARGET_OBJECTS>` as linked items
+ // should be collated for use in this target.
+ addLinkedTarget(this->LocalCommonGenerator->FindGeneratorTargetToUse(
+ item.ObjectSource->GetObjectLibrary()),
+ Forwarding::Yes);
+ }
}
for (cmGeneratorTarget const* target : cli->GetExternalObjectTargets()) {
- addLinkedTarget(target);
+ addLinkedTarget(target, Forwarding::No);
+ }
+ if (lang == "Fortran"_s) {
+ // Fortran modules provided by `$<TARGET_OBJECTS>` as sources should be
+ // collated for use in this target.
+ for (cmGeneratorTarget const* target :
+ this->GeneratorTarget->GetSourceObjectLibraries(config)) {
+ addLinkedTarget(target, Forwarding::Yes);
+ }
}
}
return dirs;
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index c9886d0..0452649 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -74,8 +74,15 @@ protected:
std::string GetCompilerLauncher(std::string const& lang,
std::string const& config);
- std::vector<std::string> GetLinkedTargetDirectories(
- const std::string& lang, const std::string& config) const;
+
+ struct LinkedTargetDirs
+ {
+ std::vector<std::string> Direct;
+ std::vector<std::string> Forward;
+ };
+
+ LinkedTargetDirs GetLinkedTargetDirectories(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/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 1b1f640..320c57c 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -515,6 +515,7 @@ void cmComputeLinkDepends::AddLinkObject(cmLinkItem const& item)
LinkEntry& entry = this->EntryList[index];
entry.Item = BT<std::string>(item.AsStr(), item.Backtrace);
entry.Kind = LinkEntry::Object;
+ entry.ObjectSource = item.ObjectSource;
// Record explicitly linked object files separately.
this->ObjectEntries.emplace_back(index);
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index 22c4e2a..3233217 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -22,6 +22,7 @@
class cmGeneratorTarget;
class cmGlobalGenerator;
class cmMakefile;
+class cmSourceFile;
class cmake;
/** \class cmComputeLinkDepends
@@ -63,6 +64,9 @@ public:
BT<std::string> Item;
cmGeneratorTarget const* Target = nullptr;
+ // The source file representing the external object (used when linking
+ // `$<TARGET_OBJECTS>`)
+ cmSourceFile const* ObjectSource = nullptr;
EntryKind Kind = Library;
// The following member is for the management of items specified
// through genex $<LINK_LIBRARY:...>
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 297ae1d..c58dc68 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -1176,7 +1176,7 @@ void cmComputeLinkInformation::AddItem(LinkEntry const& entry)
: cmStateEnums::RuntimeBinaryArtifact;
std::string exe = tgt->GetFullPath(config, artifact, true);
this->Items.emplace_back(
- BT<std::string>(exe, item.Backtrace), ItemIsPath::Yes, tgt,
+ BT<std::string>(exe, item.Backtrace), ItemIsPath::Yes, tgt, nullptr,
this->FindLibraryFeature(entry.Feature == DEFAULT
? "__CMAKE_LINK_EXECUTABLE"
: entry.Feature));
@@ -1197,7 +1197,7 @@ void cmComputeLinkInformation::AddItem(LinkEntry const& entry)
} else if (this->GlobalGenerator->IsXcode() &&
!tgt->GetImportedXcFrameworkPath(config).empty()) {
this->Items.emplace_back(
- tgt->GetImportedXcFrameworkPath(config), ItemIsPath::Yes, tgt,
+ tgt->GetImportedXcFrameworkPath(config), ItemIsPath::Yes, tgt, nullptr,
this->FindLibraryFeature(entry.Feature == DEFAULT
? "__CMAKE_LINK_XCFRAMEWORK"
: entry.Feature));
@@ -1679,15 +1679,15 @@ void cmComputeLinkInformation::AddTargetItem(LinkEntry const& entry)
if (isImportedFrameworkFolderOnApple) {
if (entry.Feature == DEFAULT) {
this->AddLibraryFeature("FRAMEWORK");
- this->Items.emplace_back(item, ItemIsPath::Yes, target,
+ this->Items.emplace_back(item, ItemIsPath::Yes, target, nullptr,
this->FindLibraryFeature("FRAMEWORK"));
} else {
- this->Items.emplace_back(item, ItemIsPath::Yes, target,
+ this->Items.emplace_back(item, ItemIsPath::Yes, target, nullptr,
this->FindLibraryFeature(entry.Feature));
}
} else {
this->Items.emplace_back(
- item, ItemIsPath::Yes, target,
+ item, ItemIsPath::Yes, target, nullptr,
this->FindLibraryFeature(entry.Feature == DEFAULT
? "__CMAKE_LINK_FRAMEWORK"
: entry.Feature));
@@ -1695,17 +1695,17 @@ void cmComputeLinkInformation::AddTargetItem(LinkEntry const& entry)
} else {
if (cmHasSuffix(entry.Feature, "FRAMEWORK"_s)) {
this->Items.emplace_back(fwDescriptor->GetLinkName(), ItemIsPath::Yes,
- target,
+ target, nullptr,
this->FindLibraryFeature(entry.Feature));
} else if (entry.Feature == DEFAULT &&
isImportedFrameworkFolderOnApple) {
this->AddLibraryFeature("FRAMEWORK");
this->Items.emplace_back(fwDescriptor->GetLinkName(), ItemIsPath::Yes,
- target,
+ target, nullptr,
this->FindLibraryFeature("FRAMEWORK"));
} else {
this->Items.emplace_back(
- item, ItemIsPath::Yes, target,
+ item, ItemIsPath::Yes, target, nullptr,
this->FindLibraryFeature(entry.Feature == DEFAULT
? "__CMAKE_LINK_LIBRARY"
: entry.Feature));
@@ -1714,7 +1714,7 @@ void cmComputeLinkInformation::AddTargetItem(LinkEntry const& entry)
} else {
// Now add the full path to the library.
this->Items.emplace_back(
- item, ItemIsPath::Yes, target,
+ item, ItemIsPath::Yes, target, nullptr,
this->FindLibraryFeature(
entry.Feature == DEFAULT ? "__CMAKE_LINK_LIBRARY" : entry.Feature));
}
@@ -1774,7 +1774,7 @@ void cmComputeLinkInformation::AddFullItem(LinkEntry const& entry)
// Now add the full path to the library.
this->Items.emplace_back(
- item, ItemIsPath::Yes, nullptr,
+ item, ItemIsPath::Yes, nullptr, entry.ObjectSource,
this->FindLibraryFeature(
entry.Feature == DEFAULT
? (entry.Kind == cmComputeLinkDepends::LinkEntry::Object
@@ -2000,13 +2000,13 @@ void cmComputeLinkInformation::AddFrameworkItem(LinkEntry const& entry)
if (this->GlobalGenerator->IsXcode()) {
// Add framework path - it will be handled by Xcode after it's added to
// "Link Binary With Libraries" build phase
- this->Items.emplace_back(item, ItemIsPath::Yes, nullptr,
+ this->Items.emplace_back(item, ItemIsPath::Yes, nullptr, nullptr,
this->FindLibraryFeature(entry.Feature == DEFAULT
? "FRAMEWORK"
: entry.Feature));
} else {
this->Items.emplace_back(
- fwDescriptor->GetLinkName(), ItemIsPath::Yes, nullptr,
+ fwDescriptor->GetLinkName(), ItemIsPath::Yes, nullptr, nullptr,
this->FindLibraryFeature(entry.Feature == DEFAULT ? "FRAMEWORK"
: entry.Feature));
}
@@ -2024,7 +2024,7 @@ void cmComputeLinkInformation::AddXcFrameworkItem(LinkEntry const& entry)
plist->SelectSuitableLibrary(*this->Makefile, entry.Item.Backtrace)) {
if (this->GlobalGenerator->IsXcode()) {
this->Items.emplace_back(
- entry.Item.Value, ItemIsPath::Yes, nullptr,
+ entry.Item.Value, ItemIsPath::Yes, nullptr, nullptr,
this->FindLibraryFeature(entry.Feature == DEFAULT
? "__CMAKE_LINK_XCFRAMEWORK"
: entry.Feature));
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index 1e8556d..3ee995f 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -22,6 +22,7 @@ class cmGeneratorTarget;
class cmGlobalGenerator;
class cmMakefile;
class cmOrderDirectories;
+class cmSourceFile;
class cmake;
/** \class cmComputeLinkInformation
@@ -51,16 +52,21 @@ public:
{
Item(BT<std::string> v, ItemIsPath isPath,
cmGeneratorTarget const* target = nullptr,
+ cmSourceFile const* objectSource = nullptr,
FeatureDescriptor const* feature = nullptr)
: Value(std::move(v))
, IsPath(isPath)
, Target(target)
+ , ObjectSource(objectSource)
, Feature(feature)
{
}
BT<std::string> Value;
ItemIsPath IsPath = ItemIsPath::No;
cmGeneratorTarget const* Target = nullptr;
+ // The source file representing the external object (used when linking
+ // `$<TARGET_OBJECTS>`)
+ cmSourceFile const* ObjectSource = nullptr;
bool HasFeature() const { return this->Feature != nullptr; }
const std::string& GetFeatureName() const
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index 2a50565..b23dabd 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -258,6 +258,12 @@ bool cmDependsFortran::LocateModules()
}
this->MatchRemoteModules(fin, targetDir);
}
+
+ // TODO: Use `CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES` to handle cases
+ // described in #25425. Note that because Makefiles generators do not
+ // implement relaxed object compilation as described in #15555, the issues
+ // never actually cause build failures; only incremental build incorrectness.
+
return true;
}
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 930922c..8d21e63 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -6898,6 +6898,7 @@ void cmGeneratorTarget::ExpandLinkItems(
cmSourceFile const* sf =
mf->GetSource(maybeObj, cmSourceFileLocationKind::Known);
if (sf && sf->GetPropertyAsBool("EXTERNAL_OBJECT")) {
+ item.ObjectSource = sf;
iface.Objects.emplace_back(std::move(item));
continue;
}
@@ -8044,35 +8045,38 @@ void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
}
}
- std::vector<cmGeneratorTarget*> objectLibraries;
- std::vector<cmSourceFile const*> externalObjects;
+ std::set<cmGeneratorTarget const*> objectLibraries;
if (!this->GlobalGenerator->GetConfigureDoneCMP0026()) {
std::vector<cmGeneratorTarget*> objectTargets;
this->GetObjectLibrariesCMP0026(objectTargets);
- objectLibraries.reserve(objectTargets.size());
for (cmGeneratorTarget* gt : objectTargets) {
- objectLibraries.push_back(gt);
+ objectLibraries.insert(gt);
}
} else {
- this->GetExternalObjects(externalObjects, config);
- for (cmSourceFile const* extObj : externalObjects) {
- std::string objLib = extObj->GetObjectLibrary();
- if (cmGeneratorTarget* tgt =
- this->LocalGenerator->FindGeneratorTargetToUse(objLib)) {
- auto const objLibIt =
- std::find_if(objectLibraries.cbegin(), objectLibraries.cend(),
- [tgt](cmGeneratorTarget* t) { return t == tgt; });
- if (objectLibraries.cend() == objLibIt) {
- objectLibraries.push_back(tgt);
- }
- }
- }
+ objectLibraries = this->GetSourceObjectLibraries(config);
}
- for (cmGeneratorTarget* objLib : objectLibraries) {
+ for (cmGeneratorTarget const* objLib : objectLibraries) {
objLib->GetLanguages(languages, config);
}
}
+std::set<cmGeneratorTarget const*> cmGeneratorTarget::GetSourceObjectLibraries(
+ std::string const& config) const
+{
+ std::set<cmGeneratorTarget const*> objectLibraries;
+ std::vector<cmSourceFile const*> externalObjects;
+ this->GetExternalObjects(externalObjects, config);
+ for (cmSourceFile const* extObj : externalObjects) {
+ std::string objLib = extObj->GetObjectLibrary();
+ if (cmGeneratorTarget* tgt =
+ this->LocalGenerator->FindGeneratorTargetToUse(objLib)) {
+ objectLibraries.insert(tgt);
+ }
+ }
+
+ return objectLibraries;
+}
+
bool cmGeneratorTarget::IsLanguageUsed(std::string const& language,
std::string const& config) const
{
@@ -8486,6 +8490,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
cmSourceFile const* sf =
mf->GetSource(maybeObj, cmSourceFileLocationKind::Known);
if (sf && sf->GetPropertyAsBool("EXTERNAL_OBJECT")) {
+ item.ObjectSource = sf;
impl.Objects.emplace_back(std::move(item));
continue;
}
@@ -9087,19 +9092,47 @@ std::string cmGeneratorTarget::GetImportedXcFrameworkPath(
bool cmGeneratorTarget::HaveFortranSources(std::string const& config) const
{
auto sources = this->GetSourceFiles(config);
- return std::any_of(sources.begin(), sources.end(),
- [](BT<cmSourceFile*> const& sf) -> bool {
- return sf.Value->GetLanguage() == "Fortran"_s;
- });
+ bool const have_direct = std::any_of(
+ sources.begin(), sources.end(), [](BT<cmSourceFile*> const& sf) -> bool {
+ return sf.Value->GetLanguage() == "Fortran"_s;
+ });
+ bool have_via_target_objects = false;
+ if (!have_direct) {
+ auto const sourceObjectLibraries = this->GetSourceObjectLibraries(config);
+ have_via_target_objects =
+ std::any_of(sourceObjectLibraries.begin(), sourceObjectLibraries.end(),
+ [&config](cmGeneratorTarget const* tgt) -> bool {
+ return tgt->HaveFortranSources(config);
+ });
+ }
+ return have_direct || have_via_target_objects;
}
bool cmGeneratorTarget::HaveFortranSources() const
{
- auto sources = cmGeneratorTarget::GetAllConfigSources();
- return std::any_of(sources.begin(), sources.end(),
- [](AllConfigSource const& sf) -> bool {
- return sf.Source->GetLanguage() == "Fortran"_s;
- });
+ auto sources = this->GetAllConfigSources();
+ bool const have_direct = std::any_of(
+ sources.begin(), sources.end(), [](AllConfigSource const& sf) -> bool {
+ return sf.Source->GetLanguage() == "Fortran"_s;
+ });
+ bool have_via_target_objects = false;
+ if (!have_direct) {
+ std::vector<std::string> configs =
+ this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+ for (auto const& config : configs) {
+ auto const sourceObjectLibraries =
+ this->GetSourceObjectLibraries(config);
+ have_via_target_objects =
+ std::any_of(sourceObjectLibraries.begin(), sourceObjectLibraries.end(),
+ [&config](cmGeneratorTarget const* tgt) -> bool {
+ return tgt->HaveFortranSources(config);
+ });
+ if (have_via_target_objects) {
+ break;
+ }
+ }
+ }
+ return have_direct || have_via_target_objects;
}
bool cmGeneratorTarget::HaveCxx20ModuleSources(std::string* errorMessage) const
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index bf49914..2a301e3 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -463,6 +463,11 @@ public:
bool IsLanguageUsed(std::string const& language,
std::string const& config) const;
+ // Get the set of targets directly referenced via `TARGET_OBJECTS` in the
+ // source list for a configuration.
+ std::set<cmGeneratorTarget const*> GetSourceObjectLibraries(
+ std::string const& config) const;
+
bool IsCSharpOnly() const;
bool IsDotNetSdkTarget() const;
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index d691d88..cba48f4 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -2527,6 +2527,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
std::string const& arg_dd, std::vector<std::string> const& arg_ddis,
std::string const& module_dir,
std::vector<std::string> const& linked_target_dirs,
+ std::vector<std::string> const& forward_modules_from_target_dirs,
std::string const& arg_lang, std::string const& arg_modmapfmt,
cmCxxModuleExportInfo const& export_info)
{
@@ -2804,6 +2805,51 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
// use by dependents that reference this target in linked-target-dirs.
std::string const target_mods_file = cmStrCat(
cmSystemTools::GetFilenamePath(arg_dd), '/', arg_lang, "Modules.json");
+
+ // Populate the module map with those provided by linked targets first.
+ for (std::string const& forward_modules_from_target_dir :
+ forward_modules_from_target_dirs) {
+ std::string const fmftn =
+ cmStrCat(forward_modules_from_target_dir, '/', arg_lang, "Modules.json");
+ Json::Value fmft;
+ cmsys::ifstream fmftf(fmftn.c_str(), std::ios::in | std::ios::binary);
+ if (!fmftf) {
+ cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to open ",
+ fmftn, " for module information"));
+ return false;
+ }
+ Json::Reader reader;
+ if (!reader.parse(fmftf, fmft, false)) {
+ cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
+ forward_modules_from_target_dir,
+ reader.getFormattedErrorMessages()));
+ return false;
+ }
+ if (!fmft.isObject()) {
+ continue;
+ }
+
+ auto forward_info = [](Json::Value& target, Json::Value const& source) {
+ if (!source.isObject()) {
+ return;
+ }
+
+ for (auto i = source.begin(); i != source.end(); ++i) {
+ std::string const key = i.key().asString();
+ if (target.isMember(key)) {
+ continue;
+ }
+ target[key] = *i;
+ }
+ };
+
+ // Forward info from forwarding targets into our collation.
+ Json::Value& tmi_target_modules = target_module_info["modules"];
+ forward_info(tmi_target_modules, fmft["modules"]);
+ forward_info(target_references, fmft["references"]);
+ forward_info(target_usages, fmft["usages"]);
+ }
+
cmGeneratedFileStream tmf(target_mods_file);
tmf << target_module_info;
@@ -2891,6 +2937,16 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
linked_target_dirs.push_back(tdi_linked_target_dir.asString());
}
}
+ std::vector<std::string> forward_modules_from_target_dirs;
+ Json::Value const& tdi_forward_modules_from_target_dirs =
+ tdi["forward-modules-from-target-dirs"];
+ if (tdi_forward_modules_from_target_dirs.isArray()) {
+ for (auto const& tdi_forward_modules_from_target_dir :
+ tdi_forward_modules_from_target_dirs) {
+ forward_modules_from_target_dirs.push_back(
+ tdi_forward_modules_from_target_dir.asString());
+ }
+ }
std::string const compilerId = tdi["compiler-id"].asString();
std::string const simulateId = tdi["compiler-simulate-id"].asString();
std::string const compilerFrontendVariant =
@@ -2914,7 +2970,8 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
# endif
return gg.WriteDyndepFile(dir_top_src, dir_top_bld, dir_cur_src, dir_cur_bld,
arg_dd, arg_ddis, module_dir, linked_target_dirs,
- arg_lang, arg_modmapfmt, *export_info)
+ forward_modules_from_target_dirs, arg_lang,
+ arg_modmapfmt, *export_info)
? 0
: 1;
}
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index c5d6901..220d393 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -430,6 +430,7 @@ public:
std::string const& arg_dd, std::vector<std::string> const& arg_ddis,
std::string const& module_dir,
std::vector<std::string> const& linked_target_dirs,
+ std::vector<std::string> const& forward_modules_from_target_dirs,
std::string const& arg_lang, std::string const& arg_modmapfmt,
cmCxxModuleExportInfo const& export_info);
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index 262728b..e4444d3 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -17,6 +17,7 @@
#include "cmTargetLinkLibraryType.h"
class cmGeneratorTarget;
+class cmSourceFile;
// Basic information about each link item.
class cmLinkItem
@@ -29,6 +30,9 @@ public:
cmLinkItem(cmGeneratorTarget const* t, bool c, cmListFileBacktrace bt);
std::string const& AsStr() const;
cmGeneratorTarget const* Target = nullptr;
+ // The source file representing the external object (used when linking
+ // `$<TARGET_OBJECTS>`)
+ cmSourceFile const* ObjectSource = nullptr;
bool Cross = false;
cmListFileBacktrace Backtrace;
friend bool operator<(cmLinkItem const& l, cmLinkItem const& r);
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index e26a6ea..7bce1d2 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -1899,6 +1899,11 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
: "OFF")
<< ")\n\n";
+ bool requireFortran = false;
+ if (target->HaveFortranSources(this->GetConfigName())) {
+ requireFortran = true;
+ }
+
auto const& implicitLangs =
this->GetImplicitDepends(target, cmDependencyScannerKind::CMake);
@@ -1908,6 +1913,12 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
cmakefileStream << "set(CMAKE_DEPENDS_LANGUAGES\n";
for (auto const& implicitLang : implicitLangs) {
cmakefileStream << " \"" << implicitLang.first << "\"\n";
+ if (requireFortran && implicitLang.first == "Fortran"_s) {
+ requireFortran = false;
+ }
+ }
+ if (requireFortran) {
+ cmakefileStream << " \"Fortran\"\n";
}
cmakefileStream << " )\n";
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 4a190db..93fb8b4 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -3630,6 +3630,9 @@ void cmMakefile::AddTargetObject(std::string const& tgtName,
this->GetOrCreateSource(objFile, true, cmSourceFileLocationKind::Known);
sf->SetObjectLibrary(tgtName);
sf->SetProperty("EXTERNAL_OBJECT", "1");
+ // TODO: Compute a language for this object based on the associated source
+ // file that compiles to it. Needs a policy as it likely affects link
+ // language selection if done unconditionally.
#if !defined(CMAKE_BOOTSTRAP)
this->SourceGroups[this->ObjectLibrariesSourceGroupIndex].AddGroupFile(
sf->ResolveFullPath());
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 0c2a719..74b4b75 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1440,9 +1440,20 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
"# Targets to which this target links which contain Fortran sources.\n"
"set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES\n";
/* clang-format on */
- std::vector<std::string> const dirs =
+ auto const dirs =
this->GetLinkedTargetDirectories("Fortran", this->GetConfigName());
- for (std::string const& d : dirs) {
+ for (std::string const& d : dirs.Direct) {
+ *this->InfoFileStream << " \"" << d << "/DependInfo.cmake\"\n";
+ }
+ *this->InfoFileStream << " )\n";
+
+ /* clang-format off */
+ *this->InfoFileStream
+ << "\n"
+ "# Targets to which this target links which contain Fortran sources.\n"
+ "set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES\n";
+ /* clang-format on */
+ for (std::string const& d : dirs.Forward) {
*this->InfoFileStream << " \"" << d << "/DependInfo.cmake\"\n";
}
*this->InfoFileStream << " )\n";
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index dabb078..2283923 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -1175,6 +1175,15 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
}
}
+ // Check if there are Fortran objects which need to participate in forwarding
+ // module requirements.
+ if (this->GeneratorTarget->HaveFortranSources(config) &&
+ !this->Configs[config].ScanningInfo.count("Fortran")) {
+ ScanningFiles files;
+ this->Configs[config].ScanningInfo["Fortran"].emplace_back(files);
+ this->WriteCompileRule("Fortran", config, WithScanning::Yes);
+ }
+
for (auto const& langScanningFiles : this->Configs[config].ScanningInfo) {
std::string const& language = langScanningFiles.first;
std::vector<ScanningFiles> const& scanningFiles = langScanningFiles.second;
@@ -1197,10 +1206,13 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
this->WriteTargetDependInfo(language, config);
- for (std::string const& l :
- this->GetLinkedTargetDirectories(language, config)) {
- build.ImplicitDeps.emplace_back(
- cmStrCat(l, '/', language, "Modules.json"));
+ auto const linked_directories =
+ this->GetLinkedTargetDirectories(language, config);
+ for (std::string const& l : linked_directories.Direct) {
+ build.ImplicitDeps.push_back(cmStrCat(l, '/', language, "Modules.json"));
+ }
+ for (std::string const& l : linked_directories.Forward) {
+ build.ImplicitDeps.push_back(cmStrCat(l, '/', language, "Modules.json"));
}
this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
@@ -1900,10 +1912,18 @@ 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(lang, config)) {
+ auto const linked_directories =
+ this->GetLinkedTargetDirectories(lang, config);
+ for (std::string const& l : linked_directories.Direct) {
tdi_linked_target_dirs.append(l);
}
+ Json::Value& tdi_forward_modules_from_target_dirs =
+ tdi["forward-modules-from-target-dirs"] = Json::arrayValue;
+ for (std::string const& l : linked_directories.Forward) {
+ tdi_forward_modules_from_target_dirs.append(l);
+ }
+
cmDyndepGeneratorCallbacks cb;
cb.ObjectFilePath = [this](cmSourceFile const* sf, std::string const& cnf) {
return this->GetObjectFilePath(sf, cnf);
diff --git a/Tests/FortranModules/CMakeLists.txt b/Tests/FortranModules/CMakeLists.txt
index 16ea0d4..1e5ff89 100644
--- a/Tests/FortranModules/CMakeLists.txt
+++ b/Tests/FortranModules/CMakeLists.txt
@@ -137,3 +137,9 @@ add_subdirectory(Issue25252-iface-sources)
add_subdirectory(Issue25365-target-objects)
add_subdirectory(Issue25365-target-objects-iface)
+
+# Issue#25425
+add_subdirectory(ModulesViaTargetObjectsSource)
+add_subdirectory(ModulesViaSubdirTargetObjectsSource)
+add_subdirectory(ModulesViaTargetObjectsLink)
+add_subdirectory(ModulesViaSubdirTargetObjectsLink)
diff --git a/Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/CMakeLists.txt b/Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/CMakeLists.txt
new file mode 100644
index 0000000..b52b423
--- /dev/null
+++ b/Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_subdirectory(subdir)
+
+add_library(mvstol_lib dummy.f90)
+target_link_libraries(mvstol_lib PRIVATE "$<TARGET_OBJECTS:mvstol_obj>")
+target_include_directories(mvstol_lib PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/subdir")
+add_library(mvstol_use use.f90)
+target_link_libraries(mvstol_use PRIVATE mvstol_lib)
diff --git a/Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/dummy.f90 b/Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/dummy.f90
new file mode 100644
index 0000000..96a8138
--- /dev/null
+++ b/Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/dummy.f90
@@ -0,0 +1,3 @@
+pure real function dummy()
+dummy = 4*atan(1.)
+end function
diff --git a/Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/subdir/CMakeLists.txt b/Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/subdir/CMakeLists.txt
new file mode 100644
index 0000000..b2a250d
--- /dev/null
+++ b/Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/subdir/CMakeLists.txt
@@ -0,0 +1 @@
+add_library(mvstol_obj STATIC obj.f90)
diff --git a/Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/subdir/obj.f90 b/Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/subdir/obj.f90
new file mode 100644
index 0000000..6b5ddd5
--- /dev/null
+++ b/Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/subdir/obj.f90
@@ -0,0 +1,11 @@
+module m1
+
+implicit none
+
+contains
+
+pure real function pi()
+pi = 4*atan(1.)
+end function
+
+end module m1
diff --git a/Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/use.f90 b/Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/use.f90
new file mode 100644
index 0000000..f971909
--- /dev/null
+++ b/Tests/FortranModules/ModulesViaSubdirTargetObjectsLink/use.f90
@@ -0,0 +1,13 @@
+module lib
+
+use m1, only : pi
+
+implicit none
+
+contains
+
+pure real function func()
+func = pi()
+end function
+
+end module
diff --git a/Tests/FortranModules/ModulesViaSubdirTargetObjectsSource/CMakeLists.txt b/Tests/FortranModules/ModulesViaSubdirTargetObjectsSource/CMakeLists.txt
new file mode 100644
index 0000000..255e8a7
--- /dev/null
+++ b/Tests/FortranModules/ModulesViaSubdirTargetObjectsSource/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_subdirectory(subdir)
+
+add_library(mvstos_lib "$<TARGET_OBJECTS:mvstos_obj>")
+target_include_directories(mvstos_lib PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/subdir")
+add_library(mvstos_use use.f90)
+target_link_libraries(mvstos_use PRIVATE mvstos_lib)
diff --git a/Tests/FortranModules/ModulesViaSubdirTargetObjectsSource/subdir/CMakeLists.txt b/Tests/FortranModules/ModulesViaSubdirTargetObjectsSource/subdir/CMakeLists.txt
new file mode 100644
index 0000000..acc0da9
--- /dev/null
+++ b/Tests/FortranModules/ModulesViaSubdirTargetObjectsSource/subdir/CMakeLists.txt
@@ -0,0 +1 @@
+add_library(mvstos_obj OBJECT obj.f90)
diff --git a/Tests/FortranModules/ModulesViaSubdirTargetObjectsSource/subdir/obj.f90 b/Tests/FortranModules/ModulesViaSubdirTargetObjectsSource/subdir/obj.f90
new file mode 100644
index 0000000..6b5ddd5
--- /dev/null
+++ b/Tests/FortranModules/ModulesViaSubdirTargetObjectsSource/subdir/obj.f90
@@ -0,0 +1,11 @@
+module m1
+
+implicit none
+
+contains
+
+pure real function pi()
+pi = 4*atan(1.)
+end function
+
+end module m1
diff --git a/Tests/FortranModules/ModulesViaSubdirTargetObjectsSource/use.f90 b/Tests/FortranModules/ModulesViaSubdirTargetObjectsSource/use.f90
new file mode 100644
index 0000000..f971909
--- /dev/null
+++ b/Tests/FortranModules/ModulesViaSubdirTargetObjectsSource/use.f90
@@ -0,0 +1,13 @@
+module lib
+
+use m1, only : pi
+
+implicit none
+
+contains
+
+pure real function func()
+func = pi()
+end function
+
+end module
diff --git a/Tests/FortranModules/ModulesViaTargetObjectsLink/CMakeLists.txt b/Tests/FortranModules/ModulesViaTargetObjectsLink/CMakeLists.txt
new file mode 100644
index 0000000..202e59e
--- /dev/null
+++ b/Tests/FortranModules/ModulesViaTargetObjectsLink/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_library(mvtol_obj STATIC obj.f90)
+add_library(mvtol_lib dummy.f90)
+target_link_libraries(mvtol_lib PRIVATE "$<TARGET_OBJECTS:mvtol_obj>")
+add_library(mvtol_use use.f90)
+target_link_libraries(mvtol_use PRIVATE mvtol_lib)
diff --git a/Tests/FortranModules/ModulesViaTargetObjectsLink/dummy.f90 b/Tests/FortranModules/ModulesViaTargetObjectsLink/dummy.f90
new file mode 100644
index 0000000..96a8138
--- /dev/null
+++ b/Tests/FortranModules/ModulesViaTargetObjectsLink/dummy.f90
@@ -0,0 +1,3 @@
+pure real function dummy()
+dummy = 4*atan(1.)
+end function
diff --git a/Tests/FortranModules/ModulesViaTargetObjectsLink/obj.f90 b/Tests/FortranModules/ModulesViaTargetObjectsLink/obj.f90
new file mode 100644
index 0000000..6b5ddd5
--- /dev/null
+++ b/Tests/FortranModules/ModulesViaTargetObjectsLink/obj.f90
@@ -0,0 +1,11 @@
+module m1
+
+implicit none
+
+contains
+
+pure real function pi()
+pi = 4*atan(1.)
+end function
+
+end module m1
diff --git a/Tests/FortranModules/ModulesViaTargetObjectsLink/use.f90 b/Tests/FortranModules/ModulesViaTargetObjectsLink/use.f90
new file mode 100644
index 0000000..f971909
--- /dev/null
+++ b/Tests/FortranModules/ModulesViaTargetObjectsLink/use.f90
@@ -0,0 +1,13 @@
+module lib
+
+use m1, only : pi
+
+implicit none
+
+contains
+
+pure real function func()
+func = pi()
+end function
+
+end module
diff --git a/Tests/FortranModules/ModulesViaTargetObjectsSource/CMakeLists.txt b/Tests/FortranModules/ModulesViaTargetObjectsSource/CMakeLists.txt
new file mode 100644
index 0000000..9113a11
--- /dev/null
+++ b/Tests/FortranModules/ModulesViaTargetObjectsSource/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_library(mvtos_obj OBJECT obj.f90)
+add_library(mvtos_lib "$<TARGET_OBJECTS:mvtos_obj>")
+add_library(mvtos_use use.f90)
+target_link_libraries(mvtos_use PRIVATE mvtos_lib)
diff --git a/Tests/FortranModules/ModulesViaTargetObjectsSource/obj.f90 b/Tests/FortranModules/ModulesViaTargetObjectsSource/obj.f90
new file mode 100644
index 0000000..6b5ddd5
--- /dev/null
+++ b/Tests/FortranModules/ModulesViaTargetObjectsSource/obj.f90
@@ -0,0 +1,11 @@
+module m1
+
+implicit none
+
+contains
+
+pure real function pi()
+pi = 4*atan(1.)
+end function
+
+end module m1
diff --git a/Tests/FortranModules/ModulesViaTargetObjectsSource/use.f90 b/Tests/FortranModules/ModulesViaTargetObjectsSource/use.f90
new file mode 100644
index 0000000..f971909
--- /dev/null
+++ b/Tests/FortranModules/ModulesViaTargetObjectsSource/use.f90
@@ -0,0 +1,13 @@
+module lib
+
+use m1, only : pi
+
+implicit none
+
+contains
+
+pure real function func()
+func = pi()
+end function
+
+end module
diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-private.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-private.json
index 45b0396..78f7928 100644
--- a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-private.json
+++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-private.json
@@ -45,6 +45,7 @@
"exports": [],
"include-dirs": [],
"language": "CXX",
+ "forward-modules-from-target-dirs": [],
"linked-target-dirs": [],
"module-dir": "<BINARY_DIR>/CMakeFiles/ninja-bmi-install-private.dir<CONFIG_DIR>"
}
diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-public.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-public.json
index 30b55e3..6c23354 100644
--- a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-public.json
+++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-public.json
@@ -45,6 +45,7 @@
"exports": [],
"include-dirs": [],
"language": "CXX",
+ "forward-modules-from-target-dirs": [],
"linked-target-dirs": [],
"module-dir": "<BINARY_DIR>/CMakeFiles/ninja-bmi-install-public.dir<CONFIG_DIR>"
}
diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-private.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-private.json
index f06a846..61f8f64 100644
--- a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-private.json
+++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-private.json
@@ -73,6 +73,7 @@
],
"include-dirs": [],
"language": "CXX",
+ "forward-modules-from-target-dirs": [],
"linked-target-dirs": [],
"module-dir": "<BINARY_DIR>/CMakeFiles/ninja-exports-private.dir<CONFIG_DIR>"
}
diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-public.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-public.json
index 938481c..d0263b0 100644
--- a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-public.json
+++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-public.json
@@ -73,6 +73,7 @@
],
"include-dirs": [],
"language": "CXX",
+ "forward-modules-from-target-dirs": [],
"linked-target-dirs": [],
"module-dir": "<BINARY_DIR>/CMakeFiles/ninja-exports-public.dir<CONFIG_DIR>"
}
diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-private.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-private.json
index 3a66a94..ed61e0e 100644
--- a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-private.json
+++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-private.json
@@ -40,6 +40,7 @@
"exports": [],
"include-dirs": [],
"language": "CXX",
+ "forward-modules-from-target-dirs": [],
"linked-target-dirs": [],
"module-dir": "<BINARY_DIR>/CMakeFiles/ninja-file-sets-private.dir<CONFIG_DIR>"
}
diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-public.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-public.json
index ac06c0f..171935f 100644
--- a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-public.json
+++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-public.json
@@ -40,6 +40,7 @@
"exports": [],
"include-dirs": [],
"language": "CXX",
+ "forward-modules-from-target-dirs": [],
"linked-target-dirs": [],
"module-dir": "<BINARY_DIR>/CMakeFiles/ninja-file-sets-public.dir<CONFIG_DIR>"
}