mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-15 03:48:02 +08:00
Add support for foreign targets
This commit is contained in:
@@ -107,7 +107,8 @@ bool cmAddExecutableCommand(std::vector<std::string> const& args,
|
||||
"\" is itself an ALIAS."));
|
||||
return false;
|
||||
}
|
||||
cmTarget* aliasedTarget = mf.FindTargetToUse(aliasedName, true);
|
||||
cmTarget* aliasedTarget =
|
||||
mf.FindTargetToUse(aliasedName, { cmStateEnums::TargetDomain::NATIVE });
|
||||
if (!aliasedTarget) {
|
||||
status.SetError(cmStrCat("cannot create ALIAS target \"", exename,
|
||||
"\" because target \"", aliasedName,
|
||||
|
@@ -189,7 +189,8 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
|
||||
"\" is itself an ALIAS."));
|
||||
return false;
|
||||
}
|
||||
cmTarget* aliasedTarget = mf.FindTargetToUse(aliasedName, true);
|
||||
cmTarget* aliasedTarget =
|
||||
mf.FindTargetToUse(aliasedName, { cmStateEnums::TargetDomain::NATIVE });
|
||||
if (!aliasedTarget) {
|
||||
status.SetError(cmStrCat("cannot create ALIAS target \"", libName,
|
||||
"\" because target \"", aliasedName,
|
||||
|
@@ -1149,6 +1149,11 @@ bool cmGeneratorTarget::IsImportedGloballyVisible() const
|
||||
return this->Target->IsImportedGloballyVisible();
|
||||
}
|
||||
|
||||
bool cmGeneratorTarget::IsForeign() const
|
||||
{
|
||||
return this->Target->IsForeign();
|
||||
}
|
||||
|
||||
bool cmGeneratorTarget::CanCompileSources() const
|
||||
{
|
||||
return this->Target->CanCompileSources();
|
||||
@@ -5396,7 +5401,8 @@ bool cmGeneratorTarget::AddHeaderSetVerification()
|
||||
cmTarget* verifyTarget = nullptr;
|
||||
cmTarget* allVerifyTarget =
|
||||
this->GlobalGenerator->GetMakefiles().front()->FindTargetToUse(
|
||||
"all_verify_interface_header_sets", true);
|
||||
"all_verify_interface_header_sets",
|
||||
{ cmStateEnums::TargetDomain::NATIVE });
|
||||
|
||||
auto interfaceFileSetEntries = this->Target->GetInterfaceHeaderSetsEntries();
|
||||
|
||||
|
@@ -60,6 +60,7 @@ public:
|
||||
bool IsSynthetic() const;
|
||||
bool IsImported() const;
|
||||
bool IsImportedGloballyVisible() const;
|
||||
bool IsForeign() const;
|
||||
bool CanCompileSources() const;
|
||||
bool HasKnownRuntimeArtifactLocation(std::string const& config) const;
|
||||
const std::string& GetLocation(const std::string& config) const;
|
||||
|
@@ -1362,7 +1362,8 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
|
||||
std::string name = this->CheckCMP0004(lib);
|
||||
if (this->GetPolicyStatusCMP0108() == cmPolicies::NEW) {
|
||||
// resolve alias name
|
||||
auto* target = this->Makefile->FindTargetToUse(name);
|
||||
auto* target = this->Makefile->FindTargetToUse(
|
||||
name, cmStateEnums::AllTargetDomains);
|
||||
if (target) {
|
||||
name = target->GetName();
|
||||
}
|
||||
|
@@ -1929,7 +1929,8 @@ bool cmGlobalGenerator::AddHeaderSetVerification()
|
||||
}
|
||||
|
||||
cmTarget* allVerifyTarget = this->Makefiles.front()->FindTargetToUse(
|
||||
"all_verify_interface_header_sets", true);
|
||||
"all_verify_interface_header_sets",
|
||||
{ cmStateEnums::TargetDomain::NATIVE });
|
||||
if (allVerifyTarget) {
|
||||
this->LocalGenerators.front()->AddGeneratorTarget(
|
||||
cm::make_unique<cmGeneratorTarget>(allVerifyTarget,
|
||||
@@ -2671,11 +2672,18 @@ void cmGlobalGenerator::IndexLocalGenerator(cmLocalGenerator* lg)
|
||||
this->LocalGeneratorSearchIndex[id.String] = lg;
|
||||
}
|
||||
|
||||
cmTarget* cmGlobalGenerator::FindTargetImpl(std::string const& name) const
|
||||
cmTarget* cmGlobalGenerator::FindTargetImpl(
|
||||
std::string const& name, cmStateEnums::TargetDomainSet domains) const
|
||||
{
|
||||
bool const useForeign =
|
||||
domains.contains(cmStateEnums::TargetDomain::FOREIGN);
|
||||
bool const useNative = domains.contains(cmStateEnums::TargetDomain::NATIVE);
|
||||
|
||||
auto const it = this->TargetSearchIndex.find(name);
|
||||
if (it != this->TargetSearchIndex.end()) {
|
||||
return it->second;
|
||||
if (it->second->IsForeign() ? useForeign : useNative) {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -2690,16 +2698,16 @@ cmGeneratorTarget* cmGlobalGenerator::FindGeneratorTargetImpl(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cmTarget* cmGlobalGenerator::FindTarget(const std::string& name,
|
||||
bool excludeAliases) const
|
||||
cmTarget* cmGlobalGenerator::FindTarget(
|
||||
const std::string& name, cmStateEnums::TargetDomainSet domains) const
|
||||
{
|
||||
if (!excludeAliases) {
|
||||
if (domains.contains(cmStateEnums::TargetDomain::ALIAS)) {
|
||||
auto const ai = this->AliasTargets.find(name);
|
||||
if (ai != this->AliasTargets.end()) {
|
||||
return this->FindTargetImpl(ai->second);
|
||||
return this->FindTargetImpl(ai->second, domains);
|
||||
}
|
||||
}
|
||||
return this->FindTargetImpl(name);
|
||||
return this->FindTargetImpl(name, domains);
|
||||
}
|
||||
|
||||
cmGeneratorTarget* cmGlobalGenerator::FindGeneratorTarget(
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include "cmExportSet.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmStateSnapshot.h"
|
||||
#include "cmStateTypes.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmTarget.h"
|
||||
@@ -380,7 +381,9 @@ public:
|
||||
|
||||
//! Find a target by name by searching the local generators.
|
||||
cmTarget* FindTarget(const std::string& name,
|
||||
bool excludeAliases = false) const;
|
||||
cmStateEnums::TargetDomainSet domains = {
|
||||
cmStateEnums::TargetDomain::NATIVE,
|
||||
cmStateEnums::TargetDomain::ALIAS }) const;
|
||||
|
||||
cmGeneratorTarget* FindGeneratorTarget(const std::string& name) const;
|
||||
|
||||
@@ -783,7 +786,8 @@ protected:
|
||||
|
||||
std::map<std::string, std::string> AliasTargets;
|
||||
|
||||
cmTarget* FindTargetImpl(std::string const& name) const;
|
||||
cmTarget* FindTargetImpl(std::string const& name,
|
||||
cmStateEnums::TargetDomainSet domains) const;
|
||||
|
||||
cmGeneratorTarget* FindGeneratorTargetImpl(std::string const& name) const;
|
||||
|
||||
|
@@ -711,7 +711,8 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
||||
if (!target) {
|
||||
// If no local target has been found, find it in the global scope.
|
||||
cmTarget* const global_target =
|
||||
helper.Makefile->GetGlobalGenerator()->FindTarget(tgt, true);
|
||||
helper.Makefile->GetGlobalGenerator()->FindTarget(
|
||||
tgt, { cmStateEnums::TargetDomain::NATIVE });
|
||||
if (global_target && !global_target->IsImported()) {
|
||||
target = global_target;
|
||||
}
|
||||
@@ -1402,7 +1403,8 @@ bool HandleImportedRuntimeArtifactsMode(std::vector<std::string> const& args,
|
||||
if (!target || !target->IsImported()) {
|
||||
// If no local target has been found, find it in the global scope.
|
||||
cmTarget* const global_target =
|
||||
helper.Makefile->GetGlobalGenerator()->FindTarget(tgt, true);
|
||||
helper.Makefile->GetGlobalGenerator()->FindTarget(
|
||||
tgt, { cmStateEnums::TargetDomain::NATIVE });
|
||||
if (global_target && global_target->IsImported()) {
|
||||
target = global_target;
|
||||
}
|
||||
|
@@ -4357,31 +4357,56 @@ cmTarget* cmMakefile::AddImportedTarget(const std::string& name,
|
||||
return this->ImportedTargetsOwned.back().get();
|
||||
}
|
||||
|
||||
cmTarget* cmMakefile::FindTargetToUse(const std::string& name,
|
||||
bool excludeAliases) const
|
||||
cmTarget* cmMakefile::AddForeignTarget(const std::string& origin,
|
||||
const std::string& name)
|
||||
{
|
||||
std::unique_ptr<cmTarget> target(new cmTarget(
|
||||
cmStrCat("@foreign_", origin, "::", name),
|
||||
cmStateEnums::TargetType::INTERFACE_LIBRARY, cmTarget::Visibility::Foreign,
|
||||
this, cmTarget::PerConfig::Yes));
|
||||
|
||||
this->ImportedTargets[name] = target.get();
|
||||
this->GetGlobalGenerator()->IndexTarget(target.get());
|
||||
this->GetStateSnapshot().GetDirectory().AddImportedTargetName(name);
|
||||
|
||||
this->ImportedTargetsOwned.push_back(std::move(target));
|
||||
return this->ImportedTargetsOwned.back().get();
|
||||
}
|
||||
|
||||
cmTarget* cmMakefile::FindTargetToUse(
|
||||
const std::string& name, cmStateEnums::TargetDomainSet domains) const
|
||||
{
|
||||
// Look for an imported target. These take priority because they
|
||||
// are more local in scope and do not have to be globally unique.
|
||||
auto targetName = name;
|
||||
if (!excludeAliases) {
|
||||
if (domains.contains(cmStateEnums::TargetDomain::ALIAS)) {
|
||||
// Look for local alias targets.
|
||||
auto alias = this->AliasTargets.find(name);
|
||||
if (alias != this->AliasTargets.end()) {
|
||||
targetName = alias->second;
|
||||
}
|
||||
}
|
||||
auto imported = this->ImportedTargets.find(targetName);
|
||||
auto const imported = this->ImportedTargets.find(targetName);
|
||||
|
||||
bool const useForeign =
|
||||
domains.contains(cmStateEnums::TargetDomain::FOREIGN);
|
||||
bool const useNative = domains.contains(cmStateEnums::TargetDomain::NATIVE);
|
||||
|
||||
if (imported != this->ImportedTargets.end()) {
|
||||
return imported->second;
|
||||
if (imported->second->IsForeign() ? useForeign : useNative) {
|
||||
return imported->second;
|
||||
}
|
||||
}
|
||||
|
||||
// Look for a target built in this directory.
|
||||
if (cmTarget* t = this->FindLocalNonAliasTarget(name)) {
|
||||
return t;
|
||||
if (t->IsForeign() ? useForeign : useNative) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
// Look for a target built in this project.
|
||||
return this->GetGlobalGenerator()->FindTarget(name, excludeAliases);
|
||||
return this->GetGlobalGenerator()->FindTarget(name, domains);
|
||||
}
|
||||
|
||||
bool cmMakefile::IsAlias(const std::string& name) const
|
||||
|
@@ -260,6 +260,9 @@ public:
|
||||
cmTarget* AddImportedTarget(const std::string& name,
|
||||
cmStateEnums::TargetType type, bool global);
|
||||
|
||||
cmTarget* AddForeignTarget(const std::string& origin,
|
||||
const std::string& name);
|
||||
|
||||
std::pair<cmTarget&, bool> CreateNewTarget(
|
||||
const std::string& name, cmStateEnums::TargetType type,
|
||||
cmTarget::PerConfig perConfig = cmTarget::PerConfig::Yes,
|
||||
@@ -493,7 +496,9 @@ public:
|
||||
/** Find a target to use in place of the given name. The target
|
||||
returned may be imported or built within the project. */
|
||||
cmTarget* FindTargetToUse(const std::string& name,
|
||||
bool excludeAliases = false) const;
|
||||
cmStateEnums::TargetDomainSet domains = {
|
||||
cmStateEnums::TargetDomain::NATIVE,
|
||||
cmStateEnums::TargetDomain::ALIAS }) const;
|
||||
bool IsAlias(const std::string& name) const;
|
||||
|
||||
std::map<std::string, std::string> GetAliasTargets() const
|
||||
|
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include <cmext/enum_set>
|
||||
|
||||
#include "cmLinkedTree.h"
|
||||
|
||||
namespace cmStateDetail {
|
||||
@@ -43,6 +45,22 @@ enum TargetType
|
||||
UNKNOWN_LIBRARY
|
||||
};
|
||||
|
||||
// Target search domains for FindTarget() style commands.
|
||||
enum class TargetDomain : unsigned
|
||||
{
|
||||
// Native, unaliased CMake targets, generated via add_library or
|
||||
// add_executable
|
||||
NATIVE,
|
||||
// Alias index, must include another domain
|
||||
ALIAS,
|
||||
// Foreign domain targets, generated directly inside CMake
|
||||
FOREIGN
|
||||
};
|
||||
using TargetDomainSet = cm::enum_set<TargetDomain>;
|
||||
static const TargetDomainSet AllTargetDomains{ TargetDomain::NATIVE,
|
||||
TargetDomain::ALIAS,
|
||||
TargetDomain::FOREIGN };
|
||||
|
||||
enum CacheEntryType
|
||||
{
|
||||
BOOL = 0,
|
||||
|
@@ -2940,6 +2940,7 @@ bool cmTarget::IsNormal() const
|
||||
case Visibility::Generated:
|
||||
case Visibility::Imported:
|
||||
case Visibility::ImportedGlobally:
|
||||
case Visibility::Foreign:
|
||||
return false;
|
||||
}
|
||||
assert(false && "unknown visibility (IsNormal)");
|
||||
@@ -2954,6 +2955,7 @@ bool cmTarget::IsSynthetic() const
|
||||
case Visibility::Normal:
|
||||
case Visibility::Imported:
|
||||
case Visibility::ImportedGlobally:
|
||||
case Visibility::Foreign:
|
||||
return false;
|
||||
}
|
||||
assert(false && "unknown visibility (IsSynthetic)");
|
||||
@@ -2965,6 +2967,7 @@ bool cmTargetInternals::IsImported() const
|
||||
switch (this->TargetVisibility) {
|
||||
case cmTarget::Visibility::Imported:
|
||||
case cmTarget::Visibility::ImportedGlobally:
|
||||
case cmTarget::Visibility::Foreign:
|
||||
return true;
|
||||
case cmTarget::Visibility::Normal:
|
||||
case cmTarget::Visibility::Generated:
|
||||
@@ -2987,12 +2990,28 @@ bool cmTarget::IsImportedGloballyVisible() const
|
||||
case Visibility::Normal:
|
||||
case Visibility::Generated:
|
||||
case Visibility::Imported:
|
||||
case Visibility::Foreign:
|
||||
return false;
|
||||
}
|
||||
assert(false && "unknown visibility (IsImportedGloballyVisible)");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cmTarget::IsForeign() const
|
||||
{
|
||||
switch (this->impl->TargetVisibility) {
|
||||
case Visibility::Foreign:
|
||||
return true;
|
||||
case Visibility::Normal:
|
||||
case Visibility::Generated:
|
||||
case Visibility::Imported:
|
||||
case Visibility::ImportedGlobally:
|
||||
return false;
|
||||
}
|
||||
assert(false && "unknown visibility (isForeign)");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cmTarget::IsPerConfig() const
|
||||
{
|
||||
return this->impl->PerConfig;
|
||||
|
@@ -49,6 +49,7 @@ public:
|
||||
Generated,
|
||||
Imported,
|
||||
ImportedGlobally,
|
||||
Foreign,
|
||||
};
|
||||
|
||||
enum class PerConfig
|
||||
@@ -218,6 +219,7 @@ public:
|
||||
bool IsSynthetic() const;
|
||||
bool IsImported() const;
|
||||
bool IsImportedGloballyVisible() const;
|
||||
bool IsForeign() const;
|
||||
bool IsPerConfig() const;
|
||||
bool IsRuntimeBinary() const;
|
||||
bool CanCompileSources() const;
|
||||
|
@@ -88,7 +88,8 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args,
|
||||
cmTarget* target = mf.GetGlobalGenerator()->FindTarget(args[0]);
|
||||
if (!target) {
|
||||
for (const auto& importedTarget : mf.GetOwnedImportedTargets()) {
|
||||
if (importedTarget->GetName() == args[0]) {
|
||||
if (importedTarget->GetName() == args[0] &&
|
||||
!importedTarget->IsForeign()) {
|
||||
target = importedTarget.get();
|
||||
break;
|
||||
}
|
||||
|
Reference in New Issue
Block a user