cmCommonTargetGenerator: return forward linked target dirs too
This will be used for module forwarding in order to support `$<TARGET_OBJECTS>` usage in source and link libraries calls.
This commit is contained in:
parent
f8729ab366
commit
06df59b930
@ -163,50 +163,65 @@ 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);
|
||||
addLinkedTarget(item.Target, Forwarding::No);
|
||||
}
|
||||
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);
|
||||
addLinkedTarget(target, Forwarding::Yes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -1440,9 +1440,9 @@ 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";
|
||||
|
@ -1206,10 +1206,10 @@ 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"));
|
||||
}
|
||||
|
||||
this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
|
||||
@ -1909,7 +1909,9 @@ 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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user