Add the ALIAS target concept for libraries and executables.
* The ALIAS name must match a validity regex. * Executables and libraries may be aliased. * An ALIAS acts immutable. It can not be used as the lhs of target_link_libraries or other commands. * An ALIAS can be used with add_custom_command, add_custom_target, and add_test in the same way regular targets can. * The target of an ALIAS can be retrieved with the ALIASED_TARGET target property. * An ALIAS does not appear in the generated buildsystem. It is kept separate from cmMakefile::Targets for that reason. * A target may have multiple aliases. * An ALIAS target may not itself have an alias. * An IMPORTED target may not have an alias. * An ALIAS may not be exported or imported.
This commit is contained in:
parent
b341bf2178
commit
370bf55415
|
@ -24,6 +24,13 @@ bool cmAddDependenciesCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string target_name = args[0];
|
std::string target_name = args[0];
|
||||||
|
if(this->Makefile->IsAlias(target_name.c_str()))
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "Cannot add target-level dependencies to alias target \""
|
||||||
|
<< target_name << "\".\n";
|
||||||
|
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||||
|
}
|
||||||
if(cmTarget* target = this->Makefile->FindTargetToUse(target_name.c_str()))
|
if(cmTarget* target = this->Makefile->FindTargetToUse(target_name.c_str()))
|
||||||
{
|
{
|
||||||
std::vector<std::string>::const_iterator s = args.begin();
|
std::vector<std::string>::const_iterator s = args.begin();
|
||||||
|
|
|
@ -30,6 +30,7 @@ bool cmAddExecutableCommand
|
||||||
bool excludeFromAll = false;
|
bool excludeFromAll = false;
|
||||||
bool importTarget = false;
|
bool importTarget = false;
|
||||||
bool importGlobal = false;
|
bool importGlobal = false;
|
||||||
|
bool isAlias = false;
|
||||||
while ( s != args.end() )
|
while ( s != args.end() )
|
||||||
{
|
{
|
||||||
if (*s == "WIN32")
|
if (*s == "WIN32")
|
||||||
|
@ -57,6 +58,11 @@ bool cmAddExecutableCommand
|
||||||
++s;
|
++s;
|
||||||
importGlobal = true;
|
importGlobal = true;
|
||||||
}
|
}
|
||||||
|
else if(*s == "ALIAS")
|
||||||
|
{
|
||||||
|
++s;
|
||||||
|
isAlias = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -83,6 +89,72 @@ bool cmAddExecutableCommand
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (isAlias)
|
||||||
|
{
|
||||||
|
if(!cmGeneratorExpression::IsValidTargetName(exename.c_str()))
|
||||||
|
{
|
||||||
|
this->SetError(("Invalid name for ALIAS: " + exename).c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(excludeFromAll)
|
||||||
|
{
|
||||||
|
this->SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(importTarget || importGlobal)
|
||||||
|
{
|
||||||
|
this->SetError("IMPORTED with ALIAS is not allowed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(args.size() != 3)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "ALIAS requires exactly one target argument.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *aliasedName = s->c_str();
|
||||||
|
if(this->Makefile->IsAlias(aliasedName))
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "cannot create ALIAS target \"" << exename
|
||||||
|
<< "\" because target \"" << aliasedName << "\" is itself an ALIAS.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cmTarget *aliasedTarget =
|
||||||
|
this->Makefile->FindTargetToUse(aliasedName, true);
|
||||||
|
if(!aliasedTarget)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "cannot create ALIAS target \"" << exename
|
||||||
|
<< "\" because target \"" << aliasedName << "\" does not already "
|
||||||
|
"exist.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cmTarget::TargetType type = aliasedTarget->GetType();
|
||||||
|
if(type != cmTarget::EXECUTABLE)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "cannot create ALIAS target \"" << exename
|
||||||
|
<< "\" because target \"" << aliasedName << "\" is not an "
|
||||||
|
"executable.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(aliasedTarget->IsImported())
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "cannot create ALIAS target \"" << exename
|
||||||
|
<< "\" because target \"" << aliasedName << "\" is IMPORTED.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this->Makefile->AddAlias(exename.c_str(), aliasedTarget);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle imported target creation.
|
// Handle imported target creation.
|
||||||
if(importTarget)
|
if(importTarget)
|
||||||
|
|
|
@ -107,6 +107,19 @@ public:
|
||||||
"(and its per-configuration version IMPORTED_LOCATION_<CONFIG>) "
|
"(and its per-configuration version IMPORTED_LOCATION_<CONFIG>) "
|
||||||
"which specifies the location of the main executable file on disk. "
|
"which specifies the location of the main executable file on disk. "
|
||||||
"See documentation of the IMPORTED_* properties for more information."
|
"See documentation of the IMPORTED_* properties for more information."
|
||||||
|
"\n"
|
||||||
|
"The signature\n"
|
||||||
|
" add_executable(<name> ALIAS <target>)\n"
|
||||||
|
"creates an alias, such that <name> can be used to refer to <target> "
|
||||||
|
"in subsequent commands. The <name> does not appear in the generated "
|
||||||
|
"buildsystem as a make target. The <target> may not be an IMPORTED "
|
||||||
|
"target or an ALIAS. Alias targets can be used as linkable targets, "
|
||||||
|
"targets to read properties from, executables for custom commands and "
|
||||||
|
"custom targets. They can also be tested for existance with the "
|
||||||
|
"regular if(TARGET) subcommand. The <name> may not be used to modify "
|
||||||
|
"properties of <target>, that is, it may not be used as the operand of "
|
||||||
|
"set_property, set_target_properties, target_link_libraries etc. An "
|
||||||
|
"ALIAS target may not be installed of exported."
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ bool cmAddLibraryCommand
|
||||||
// the type of library. Otherwise, it is treated as a source or
|
// the type of library. Otherwise, it is treated as a source or
|
||||||
// source list name. There may be two keyword arguments, check for them
|
// source list name. There may be two keyword arguments, check for them
|
||||||
bool haveSpecifiedType = false;
|
bool haveSpecifiedType = false;
|
||||||
|
bool isAlias = false;
|
||||||
while ( s != args.end() )
|
while ( s != args.end() )
|
||||||
{
|
{
|
||||||
std::string libType = *s;
|
std::string libType = *s;
|
||||||
|
@ -76,6 +77,11 @@ bool cmAddLibraryCommand
|
||||||
type = cmTarget::UNKNOWN_LIBRARY;
|
type = cmTarget::UNKNOWN_LIBRARY;
|
||||||
haveSpecifiedType = true;
|
haveSpecifiedType = true;
|
||||||
}
|
}
|
||||||
|
else if(libType == "ALIAS")
|
||||||
|
{
|
||||||
|
++s;
|
||||||
|
isAlias = true;
|
||||||
|
}
|
||||||
else if(*s == "EXCLUDE_FROM_ALL")
|
else if(*s == "EXCLUDE_FROM_ALL")
|
||||||
{
|
{
|
||||||
++s;
|
++s;
|
||||||
|
@ -96,6 +102,80 @@ bool cmAddLibraryCommand
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isAlias)
|
||||||
|
{
|
||||||
|
if(!cmGeneratorExpression::IsValidTargetName(libName.c_str()))
|
||||||
|
{
|
||||||
|
this->SetError(("Invalid name for ALIAS: " + libName).c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(excludeFromAll)
|
||||||
|
{
|
||||||
|
this->SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(importTarget || importGlobal)
|
||||||
|
{
|
||||||
|
this->SetError("IMPORTED with ALIAS is not allowed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(args.size() != 3)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "ALIAS requires exactly one target argument.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *aliasedName = s->c_str();
|
||||||
|
if(this->Makefile->IsAlias(aliasedName))
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "cannot create ALIAS target \"" << libName
|
||||||
|
<< "\" because target \"" << aliasedName << "\" is itself an ALIAS.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cmTarget *aliasedTarget =
|
||||||
|
this->Makefile->FindTargetToUse(aliasedName, true);
|
||||||
|
if(!aliasedTarget)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "cannot create ALIAS target \"" << libName
|
||||||
|
<< "\" because target \"" << aliasedName << "\" does not already "
|
||||||
|
"exist.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cmTarget::TargetType aliasedType = aliasedTarget->GetType();
|
||||||
|
if(aliasedType != cmTarget::SHARED_LIBRARY
|
||||||
|
&& aliasedType != cmTarget::STATIC_LIBRARY
|
||||||
|
&& aliasedType != cmTarget::MODULE_LIBRARY
|
||||||
|
&& aliasedType != cmTarget::OBJECT_LIBRARY)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "cannot create ALIAS target \"" << libName
|
||||||
|
<< "\" because target \"" << aliasedName << "\" is not a library.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(aliasedTarget->IsImported())
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "cannot create ALIAS target \"" << libName
|
||||||
|
<< "\" because target \"" << aliasedName << "\" is IMPORTED.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this->Makefile->AddAlias(libName.c_str(), aliasedTarget);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(importTarget && excludeFromAll)
|
||||||
|
{
|
||||||
|
this->SetError("excludeFromAll with IMPORTED target makes no sense.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* ideally we should check whether for the linker language of the target
|
/* ideally we should check whether for the linker language of the target
|
||||||
CMAKE_${LANG}_CREATE_SHARED_LIBRARY is defined and if not default to
|
CMAKE_${LANG}_CREATE_SHARED_LIBRARY is defined and if not default to
|
||||||
|
|
|
@ -138,6 +138,19 @@ public:
|
||||||
"Some native build systems may not like targets that have only "
|
"Some native build systems may not like targets that have only "
|
||||||
"object files, so consider adding at least one real source file "
|
"object files, so consider adding at least one real source file "
|
||||||
"to any target that references $<TARGET_OBJECTS:objlib>."
|
"to any target that references $<TARGET_OBJECTS:objlib>."
|
||||||
|
"\n"
|
||||||
|
"The signature\n"
|
||||||
|
" add_library(<name> ALIAS <target>)\n"
|
||||||
|
"creates an alias, such that <name> can be used to refer to <target> "
|
||||||
|
"in subsequent commands. The <name> does not appear in the generated "
|
||||||
|
"buildsystem as a make target. The <target> may not be an IMPORTED "
|
||||||
|
"target or an ALIAS. Alias targets can be used as linkable targets, "
|
||||||
|
"targets to read properties from. They can also be tested for "
|
||||||
|
"existance with the "
|
||||||
|
"regular if(TARGET) subcommand. The <name> may not be used to modify "
|
||||||
|
"properties of <target>, that is, it may not be used as the operand of "
|
||||||
|
"set_property, set_target_properties, target_link_libraries etc. An "
|
||||||
|
"ALIAS target may not be installed of exported."
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,15 @@ bool cmExportCommand
|
||||||
currentTarget != this->Targets.GetVector().end();
|
currentTarget != this->Targets.GetVector().end();
|
||||||
++currentTarget)
|
++currentTarget)
|
||||||
{
|
{
|
||||||
|
if (this->Makefile->IsAlias(currentTarget->c_str()))
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "given ALIAS target \"" << *currentTarget
|
||||||
|
<< "\" which may not be exported.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(cmTarget* target =
|
if(cmTarget* target =
|
||||||
this->Makefile->GetLocalGenerator()->
|
this->Makefile->GetLocalGenerator()->
|
||||||
GetGlobalGenerator()->FindTarget(0, currentTarget->c_str()))
|
GetGlobalGenerator()->FindTarget(0, currentTarget->c_str()))
|
||||||
|
|
|
@ -747,6 +747,18 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||||
"Target name not supported.");
|
"Target name not supported.");
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
if(propertyName == "ALIASED_TARGET")
|
||||||
|
{
|
||||||
|
if(context->Makefile->IsAlias(targetName.c_str()))
|
||||||
|
{
|
||||||
|
if(cmTarget* tgt =
|
||||||
|
context->Makefile->FindTargetToUse(targetName.c_str()))
|
||||||
|
{
|
||||||
|
return tgt->GetName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
target = context->Makefile->FindTargetToUse(
|
target = context->Makefile->FindTargetToUse(
|
||||||
targetName.c_str());
|
targetName.c_str());
|
||||||
|
|
||||||
|
|
|
@ -288,6 +288,18 @@ bool cmGetPropertyCommand::HandleTargetMode()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this->PropertyName == "ALIASED_TARGET")
|
||||||
|
{
|
||||||
|
if(this->Makefile->IsAlias(this->Name.c_str()))
|
||||||
|
{
|
||||||
|
if(cmTarget* target =
|
||||||
|
this->Makefile->FindTargetToUse(this->Name.c_str()))
|
||||||
|
{
|
||||||
|
return this->StoreResult(target->GetName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if(cmTarget* target = this->Makefile->FindTargetToUse(this->Name.c_str()))
|
if(cmTarget* target = this->Makefile->FindTargetToUse(this->Name.c_str()))
|
||||||
{
|
{
|
||||||
return this->StoreResult(target->GetProperty(this->PropertyName.c_str()));
|
return this->StoreResult(target->GetProperty(this->PropertyName.c_str()));
|
||||||
|
|
|
@ -22,16 +22,29 @@ bool cmGetTargetPropertyCommand
|
||||||
}
|
}
|
||||||
std::string var = args[0].c_str();
|
std::string var = args[0].c_str();
|
||||||
const char* targetName = args[1].c_str();
|
const char* targetName = args[1].c_str();
|
||||||
|
const char *prop = 0;
|
||||||
|
|
||||||
if(cmTarget* tgt = this->Makefile->FindTargetToUse(targetName))
|
if(args[2] == "ALIASED_TARGET")
|
||||||
|
{
|
||||||
|
if(this->Makefile->IsAlias(targetName))
|
||||||
|
{
|
||||||
|
if(cmTarget* target =
|
||||||
|
this->Makefile->FindTargetToUse(targetName))
|
||||||
|
{
|
||||||
|
prop = target->GetName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(cmTarget* tgt = this->Makefile->FindTargetToUse(targetName))
|
||||||
{
|
{
|
||||||
cmTarget& target = *tgt;
|
cmTarget& target = *tgt;
|
||||||
const char *prop = target.GetProperty(args[2].c_str());
|
prop = target.GetProperty(args[2].c_str());
|
||||||
if (prop)
|
}
|
||||||
{
|
|
||||||
this->Makefile->AddDefinition(var.c_str(), prop);
|
if (prop)
|
||||||
return true;
|
{
|
||||||
}
|
this->Makefile->AddDefinition(var.c_str(), prop);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
this->Makefile->AddDefinition(var.c_str(), (var+"-NOTFOUND").c_str());
|
this->Makefile->AddDefinition(var.c_str(), (var+"-NOTFOUND").c_str());
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1769,10 +1769,22 @@ cmLocalGenerator* cmGlobalGenerator::FindLocalGenerator(const char* start_dir)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmGlobalGenerator::AddAlias(const char *name, cmTarget *tgt)
|
||||||
|
{
|
||||||
|
this->AliasTargets[name] = tgt;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmGlobalGenerator::IsAlias(const char *name)
|
||||||
|
{
|
||||||
|
return this->AliasTargets.find(name) != this->AliasTargets.end();
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
cmTarget*
|
cmTarget*
|
||||||
cmGlobalGenerator::FindTarget(const char* project, const char* name)
|
cmGlobalGenerator::FindTarget(const char* project, const char* name,
|
||||||
|
bool excludeAliases)
|
||||||
{
|
{
|
||||||
// if project specific
|
// if project specific
|
||||||
if(project)
|
if(project)
|
||||||
|
@ -1780,7 +1792,8 @@ cmGlobalGenerator::FindTarget(const char* project, const char* name)
|
||||||
std::vector<cmLocalGenerator*>* gens = &this->ProjectMap[project];
|
std::vector<cmLocalGenerator*>* gens = &this->ProjectMap[project];
|
||||||
for(unsigned int i = 0; i < gens->size(); ++i)
|
for(unsigned int i = 0; i < gens->size(); ++i)
|
||||||
{
|
{
|
||||||
cmTarget* ret = (*gens)[i]->GetMakefile()->FindTarget(name);
|
cmTarget* ret = (*gens)[i]->GetMakefile()->FindTarget(name,
|
||||||
|
excludeAliases);
|
||||||
if(ret)
|
if(ret)
|
||||||
{
|
{
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1790,6 +1803,15 @@ cmGlobalGenerator::FindTarget(const char* project, const char* name)
|
||||||
// if all projects/directories
|
// if all projects/directories
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!excludeAliases)
|
||||||
|
{
|
||||||
|
std::map<cmStdString, cmTarget*>::iterator ai
|
||||||
|
= this->AliasTargets.find(name);
|
||||||
|
if (ai != this->AliasTargets.end())
|
||||||
|
{
|
||||||
|
return ai->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
std::map<cmStdString,cmTarget *>::iterator i =
|
std::map<cmStdString,cmTarget *>::iterator i =
|
||||||
this->TotalTargets.find ( name );
|
this->TotalTargets.find ( name );
|
||||||
if ( i != this->TotalTargets.end() )
|
if ( i != this->TotalTargets.end() )
|
||||||
|
|
|
@ -196,7 +196,11 @@ public:
|
||||||
void FindMakeProgram(cmMakefile*);
|
void FindMakeProgram(cmMakefile*);
|
||||||
|
|
||||||
///! Find a target by name by searching the local generators.
|
///! Find a target by name by searching the local generators.
|
||||||
cmTarget* FindTarget(const char* project, const char* name);
|
cmTarget* FindTarget(const char* project, const char* name,
|
||||||
|
bool excludeAliases = false);
|
||||||
|
|
||||||
|
void AddAlias(const char *name, cmTarget *tgt);
|
||||||
|
bool IsAlias(const char *name);
|
||||||
|
|
||||||
/** Determine if a name resolves to a framework on disk or a built target
|
/** Determine if a name resolves to a framework on disk or a built target
|
||||||
that is a framework. */
|
that is a framework. */
|
||||||
|
@ -347,6 +351,7 @@ protected:
|
||||||
|
|
||||||
// All targets in the entire project.
|
// All targets in the entire project.
|
||||||
std::map<cmStdString,cmTarget *> TotalTargets;
|
std::map<cmStdString,cmTarget *> TotalTargets;
|
||||||
|
std::map<cmStdString,cmTarget *> AliasTargets;
|
||||||
std::map<cmStdString,cmTarget *> ImportedTargets;
|
std::map<cmStdString,cmTarget *> ImportedTargets;
|
||||||
std::vector<cmGeneratorExpressionEvaluationFile*> EvaluationFiles;
|
std::vector<cmGeneratorExpressionEvaluationFile*> EvaluationFiles;
|
||||||
|
|
||||||
|
|
|
@ -362,6 +362,15 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
||||||
targetIt!=targetList.GetVector().end();
|
targetIt!=targetList.GetVector().end();
|
||||||
++targetIt)
|
++targetIt)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (this->Makefile->IsAlias(targetIt->c_str()))
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "TARGETS given target \"" << (*targetIt)
|
||||||
|
<< "\" which is an alias.";
|
||||||
|
this->SetError(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Lookup this target in the current directory.
|
// Lookup this target in the current directory.
|
||||||
if(cmTarget* target=this->Makefile->FindTarget(targetIt->c_str()))
|
if(cmTarget* target=this->Makefile->FindTarget(targetIt->c_str()))
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <ctype.h> // for isspace
|
#include <ctype.h> // for isspace
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
class cmMakefile::Internals
|
class cmMakefile::Internals
|
||||||
{
|
{
|
||||||
|
@ -1437,6 +1438,14 @@ void cmMakefile::AddLinkDirectoryForTarget(const char *target,
|
||||||
cmTargets::iterator i = this->Targets.find(target);
|
cmTargets::iterator i = this->Targets.find(target);
|
||||||
if ( i != this->Targets.end())
|
if ( i != this->Targets.end())
|
||||||
{
|
{
|
||||||
|
if(this->IsAlias(target))
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "ALIAS target \"" << target << "\" "
|
||||||
|
<< "may not be linked into another target.";
|
||||||
|
this->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
i->second.AddLinkDirectory( d );
|
i->second.AddLinkDirectory( d );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1923,6 +1932,12 @@ void cmMakefile::AddGlobalLinkInformation(const char* name, cmTarget& target)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cmMakefile::AddAlias(const char* lname, cmTarget *tgt)
|
||||||
|
{
|
||||||
|
this->AliasTargets[lname] = tgt;
|
||||||
|
this->LocalGenerator->GetGlobalGenerator()->AddAlias(lname, tgt);
|
||||||
|
}
|
||||||
|
|
||||||
cmTarget* cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
|
cmTarget* cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
|
||||||
const std::vector<std::string> &srcs,
|
const std::vector<std::string> &srcs,
|
||||||
bool excludeFromAll)
|
bool excludeFromAll)
|
||||||
|
@ -3758,8 +3773,17 @@ const char* cmMakefile::GetFeature(const char* feature, const char* config)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmTarget* cmMakefile::FindTarget(const char* name)
|
cmTarget* cmMakefile::FindTarget(const char* name, bool excludeAliases)
|
||||||
{
|
{
|
||||||
|
if (!excludeAliases)
|
||||||
|
{
|
||||||
|
std::map<std::string, cmTarget*>::iterator i
|
||||||
|
= this->AliasTargets.find(name);
|
||||||
|
if (i != this->AliasTargets.end())
|
||||||
|
{
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
cmTargets& tgts = this->GetTargets();
|
cmTargets& tgts = this->GetTargets();
|
||||||
|
|
||||||
cmTargets::iterator i = tgts.find ( name );
|
cmTargets::iterator i = tgts.find ( name );
|
||||||
|
@ -4184,7 +4208,7 @@ cmMakefile::AddImportedTarget(const char* name, cmTarget::TargetType type,
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
cmTarget* cmMakefile::FindTargetToUse(const char* name)
|
cmTarget* cmMakefile::FindTargetToUse(const char* name, bool excludeAliases)
|
||||||
{
|
{
|
||||||
// Look for an imported target. These take priority because they
|
// Look for an imported target. These take priority because they
|
||||||
// are more local in scope and do not have to be globally unique.
|
// are more local in scope and do not have to be globally unique.
|
||||||
|
@ -4196,15 +4220,25 @@ cmTarget* cmMakefile::FindTargetToUse(const char* name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for a target built in this directory.
|
// Look for a target built in this directory.
|
||||||
if(cmTarget* t = this->FindTarget(name))
|
if(cmTarget* t = this->FindTarget(name, excludeAliases))
|
||||||
{
|
{
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for a target built in this project.
|
// Look for a target built in this project.
|
||||||
return this->LocalGenerator->GetGlobalGenerator()->FindTarget(0, name);
|
return this->LocalGenerator->GetGlobalGenerator()->FindTarget(0, name,
|
||||||
|
excludeAliases);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmMakefile::IsAlias(const char *name)
|
||||||
|
{
|
||||||
|
if (this->AliasTargets.find(name) != this->AliasTargets.end())
|
||||||
|
return true;
|
||||||
|
return this->GetLocalGenerator()->GetGlobalGenerator()->IsAlias(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
cmGeneratorTarget* cmMakefile::FindGeneratorTargetToUse(const char* name)
|
cmGeneratorTarget* cmMakefile::FindGeneratorTargetToUse(const char* name)
|
||||||
{
|
{
|
||||||
cmTarget *t = this->FindTargetToUse(name);
|
cmTarget *t = this->FindTargetToUse(name);
|
||||||
|
@ -4215,6 +4249,14 @@ cmGeneratorTarget* cmMakefile::FindGeneratorTargetToUse(const char* name)
|
||||||
bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
|
bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
|
||||||
bool isCustom)
|
bool isCustom)
|
||||||
{
|
{
|
||||||
|
if(this->IsAlias(name.c_str()))
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "cannot create target \"" << name
|
||||||
|
<< "\" because an alias with the same name already exists.";
|
||||||
|
msg = e.str();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if(cmTarget* existing = this->FindTargetToUse(name.c_str()))
|
if(cmTarget* existing = this->FindTargetToUse(name.c_str()))
|
||||||
{
|
{
|
||||||
// The name given conflicts with an existing target. Produce an
|
// The name given conflicts with an existing target. Produce an
|
||||||
|
|
|
@ -337,6 +337,7 @@ public:
|
||||||
cmTarget* AddLibrary(const char *libname, cmTarget::TargetType type,
|
cmTarget* AddLibrary(const char *libname, cmTarget::TargetType type,
|
||||||
const std::vector<std::string> &srcs,
|
const std::vector<std::string> &srcs,
|
||||||
bool excludeFromAll = false);
|
bool excludeFromAll = false);
|
||||||
|
void AddAlias(const char *libname, cmTarget *tgt);
|
||||||
|
|
||||||
#if defined(CMAKE_BUILD_WITH_CMAKE)
|
#if defined(CMAKE_BUILD_WITH_CMAKE)
|
||||||
/**
|
/**
|
||||||
|
@ -536,11 +537,12 @@ public:
|
||||||
this->GeneratorTargets = targets;
|
this->GeneratorTargets = targets;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmTarget* FindTarget(const char* name);
|
cmTarget* FindTarget(const char* name, bool excludeAliases = false);
|
||||||
|
|
||||||
/** Find a target to use in place of the given name. The target
|
/** Find a target to use in place of the given name. The target
|
||||||
returned may be imported or built within the project. */
|
returned may be imported or built within the project. */
|
||||||
cmTarget* FindTargetToUse(const char* name);
|
cmTarget* FindTargetToUse(const char* name, bool excludeAliases = false);
|
||||||
|
bool IsAlias(const char *name);
|
||||||
cmGeneratorTarget* FindGeneratorTargetToUse(const char* name);
|
cmGeneratorTarget* FindGeneratorTargetToUse(const char* name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -902,6 +904,7 @@ protected:
|
||||||
|
|
||||||
// libraries, classes, and executables
|
// libraries, classes, and executables
|
||||||
cmTargets Targets;
|
cmTargets Targets;
|
||||||
|
std::map<std::string, cmTarget*> AliasTargets;
|
||||||
cmGeneratorTargetsType GeneratorTargets;
|
cmGeneratorTargetsType GeneratorTargets;
|
||||||
std::vector<cmSourceFile*> SourceFiles;
|
std::vector<cmSourceFile*> SourceFiles;
|
||||||
|
|
||||||
|
|
|
@ -244,6 +244,11 @@ bool cmSetPropertyCommand::HandleTargetMode()
|
||||||
for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
|
for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
|
||||||
ni != this->Names.end(); ++ni)
|
ni != this->Names.end(); ++ni)
|
||||||
{
|
{
|
||||||
|
if (this->Makefile->IsAlias(ni->c_str()))
|
||||||
|
{
|
||||||
|
this->SetError("can not be used on an ALIAS target.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if(cmTarget* target = this->Makefile->FindTargetToUse(ni->c_str()))
|
if(cmTarget* target = this->Makefile->FindTargetToUse(ni->c_str()))
|
||||||
{
|
{
|
||||||
// Handle the current target.
|
// Handle the current target.
|
||||||
|
|
|
@ -72,6 +72,11 @@ bool cmSetTargetPropertiesCommand
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < numFiles; ++i)
|
for(i = 0; i < numFiles; ++i)
|
||||||
{
|
{
|
||||||
|
if (this->Makefile->IsAlias(args[i].c_str()))
|
||||||
|
{
|
||||||
|
this->SetError("can not be used on an ALIAS target.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
bool ret = cmSetTargetPropertiesCommand::SetOneTarget
|
bool ret = cmSetTargetPropertiesCommand::SetOneTarget
|
||||||
(args[i].c_str(),propertyPairs,this->Makefile);
|
(args[i].c_str(),propertyPairs,this->Makefile);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
|
|
@ -968,6 +968,12 @@ void cmTarget::DefineProperties(cmake *cm)
|
||||||
"Per-configuration target file base name.",
|
"Per-configuration target file base name.",
|
||||||
"This is the configuration-specific version of OUTPUT_NAME.");
|
"This is the configuration-specific version of OUTPUT_NAME.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("ALIASED_TARGET", cmProperty::TARGET,
|
||||||
|
"Name of target aliased by this target.",
|
||||||
|
"If this is an ALIAS target, this property contains the name of the "
|
||||||
|
"target aliased.");
|
||||||
|
|
||||||
cm->DefineProperty
|
cm->DefineProperty
|
||||||
("<CONFIG>_OUTPUT_NAME", cmProperty::TARGET,
|
("<CONFIG>_OUTPUT_NAME", cmProperty::TARGET,
|
||||||
"Old per-configuration target file base name.",
|
"Old per-configuration target file base name.",
|
||||||
|
|
|
@ -31,6 +31,11 @@ bool cmTargetLinkLibrariesCommand
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->Makefile->IsAlias(args[0].c_str()))
|
||||||
|
{
|
||||||
|
this->SetError("can not be used on an ALIAS target.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Lookup the target for which libraries are specified.
|
// Lookup the target for which libraries are specified.
|
||||||
this->Target =
|
this->Target =
|
||||||
this->Makefile->GetCMakeInstance()
|
this->Makefile->GetCMakeInstance()
|
||||||
|
|
|
@ -26,6 +26,11 @@ bool cmTargetPropCommandBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup the target for which libraries are specified.
|
// Lookup the target for which libraries are specified.
|
||||||
|
if (this->Makefile->IsAlias(args[0].c_str()))
|
||||||
|
{
|
||||||
|
this->SetError("can not be used on an ALIAS target.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
this->Target =
|
this->Target =
|
||||||
this->Makefile->GetCMakeInstance()
|
this->Makefile->GetCMakeInstance()
|
||||||
->GetGlobalGenerator()->FindTarget(0, args[0].c_str());
|
->GetGlobalGenerator()->FindTarget(0, args[0].c_str());
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 2.8.11)
|
||||||
|
project(AliasTarget)
|
||||||
|
|
||||||
|
add_library(foo SHARED empty.cpp)
|
||||||
|
add_library(PREFIX::Foo ALIAS foo)
|
||||||
|
add_library(Another::Alias ALIAS foo)
|
||||||
|
|
||||||
|
add_library(objects OBJECT object.cpp)
|
||||||
|
add_library(Alias::Objects ALIAS objects)
|
||||||
|
|
||||||
|
target_compile_definitions(foo PUBLIC FOO_DEFINE)
|
||||||
|
|
||||||
|
add_library(bar SHARED empty.cpp)
|
||||||
|
target_compile_definitions(bar PUBLIC BAR_DEFINE)
|
||||||
|
|
||||||
|
target_link_libraries(foo LINK_PUBLIC $<$<STREQUAL:$<TARGET_PROPERTY:PREFIX::Foo,ALIASED_TARGET>,foo>:bar>)
|
||||||
|
|
||||||
|
add_executable(AliasTarget commandgenerator.cpp $<TARGET_OBJECTS:Alias::Objects>)
|
||||||
|
add_executable(PREFIX::AliasTarget ALIAS AliasTarget)
|
||||||
|
add_executable(Generator::Command ALIAS AliasTarget)
|
||||||
|
|
||||||
|
add_custom_command(OUTPUT commandoutput.h COMMAND Generator::Command)
|
||||||
|
|
||||||
|
add_library(bat SHARED bat.cpp "${CMAKE_CURRENT_BINARY_DIR}/commandoutput.h")
|
||||||
|
target_link_libraries(bat PREFIX::Foo)
|
||||||
|
target_include_directories(bat PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
|
||||||
|
add_executable(targetgenerator targetgenerator.cpp)
|
||||||
|
add_executable(Generator::Target ALIAS targetgenerator)
|
||||||
|
|
||||||
|
add_custom_target(usealias Generator::Target)
|
||||||
|
add_dependencies(bat usealias)
|
||||||
|
|
||||||
|
if (NOT TARGET Another::Alias)
|
||||||
|
message(SEND_ERROR "Another::Alias is not considered a target.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
get_target_property(_alt PREFIX::Foo ALIASED_TARGET)
|
||||||
|
if (NOT ${_alt} STREQUAL foo)
|
||||||
|
message(SEND_ERROR "ALIASED_TARGET is not foo: ${_alt}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
get_property(_alt2 TARGET PREFIX::Foo PROPERTY ALIASED_TARGET)
|
||||||
|
if (NOT ${_alt2} STREQUAL foo)
|
||||||
|
message(SEND_ERROR "ALIASED_TARGET is not foo.")
|
||||||
|
endif()
|
|
@ -0,0 +1,28 @@
|
||||||
|
|
||||||
|
#ifndef FOO_DEFINE
|
||||||
|
#error Expected FOO_DEFINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BAR_DEFINE
|
||||||
|
#error Expected Bar_DEFINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "commandoutput.h"
|
||||||
|
|
||||||
|
#ifndef COMMANDOUTPUT_DEFINE
|
||||||
|
#error Expected COMMANDOUTPUT_DEFINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "targetoutput.h"
|
||||||
|
|
||||||
|
#ifndef TARGETOUTPUT_DEFINE
|
||||||
|
#error Expected TARGETOUTPUT_DEFINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
int bar()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "object.h"
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
std::fstream fout;
|
||||||
|
fout.open("commandoutput.h", std::ios::out);
|
||||||
|
if (!fout)
|
||||||
|
return 1;
|
||||||
|
fout << "#define COMMANDOUTPUT_DEFINE\n";
|
||||||
|
fout.close();
|
||||||
|
return object();
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifdef _WIN32
|
||||||
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
int object(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
#ifdef _WIN32
|
||||||
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
int object(void);
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
std::fstream fout;
|
||||||
|
fout.open("targetoutput.h", std::ios::out);
|
||||||
|
if (!fout)
|
||||||
|
return 1;
|
||||||
|
fout << "#define TARGETOUTPUT_DEFINE\n";
|
||||||
|
fout.close();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -245,6 +245,7 @@ if(BUILD_TESTING)
|
||||||
ADD_TEST_MACRO(CompileDefinitions CompileDefinitions)
|
ADD_TEST_MACRO(CompileDefinitions CompileDefinitions)
|
||||||
ADD_TEST_MACRO(CompileOptions CompileOptions)
|
ADD_TEST_MACRO(CompileOptions CompileOptions)
|
||||||
ADD_TEST_MACRO(CompatibleInterface CompatibleInterface)
|
ADD_TEST_MACRO(CompatibleInterface CompatibleInterface)
|
||||||
|
ADD_TEST_MACRO(AliasTarget AliasTarget)
|
||||||
set_tests_properties(EmptyLibrary PROPERTIES
|
set_tests_properties(EmptyLibrary PROPERTIES
|
||||||
PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target: test")
|
PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target: test")
|
||||||
ADD_TEST_MACRO(CrossCompile CrossCompile)
|
ADD_TEST_MACRO(CrossCompile CrossCompile)
|
||||||
|
|
|
@ -3,7 +3,8 @@ project(CTestTestDepends)
|
||||||
include(CTest)
|
include(CTest)
|
||||||
|
|
||||||
add_executable (simple simple.cxx)
|
add_executable (simple simple.cxx)
|
||||||
add_test (one simple)
|
add_executable (TestExe::Simple ALIAS simple)
|
||||||
|
add_test (NAME one COMMAND TestExe::Simple)
|
||||||
add_test (two simple)
|
add_test (two simple)
|
||||||
add_test (three simple)
|
add_test (three simple)
|
||||||
|
|
||||||
|
|
|
@ -163,6 +163,11 @@ add_library(imported4 SHARED IMPORTED)
|
||||||
set_property(TARGET imported4 APPEND PROPERTY
|
set_property(TARGET imported4 APPEND PROPERTY
|
||||||
INCLUDE_DIRECTORIES $<TARGET_PROPERTY:imported3,INTERFACE_INCLUDE_DIRECTORIES>)
|
INCLUDE_DIRECTORIES $<TARGET_PROPERTY:imported3,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||||
|
|
||||||
|
add_executable(someexe empty.cpp)
|
||||||
|
add_executable(Alias::SomeExe ALIAS someexe)
|
||||||
|
|
||||||
|
add_library(Alias::SomeLib ALIAS empty1)
|
||||||
|
|
||||||
add_custom_target(check-part3 ALL
|
add_custom_target(check-part3 ALL
|
||||||
COMMAND ${CMAKE_COMMAND}
|
COMMAND ${CMAKE_COMMAND}
|
||||||
-Dtest_version_greater_1=$<VERSION_GREATER:1.0,1.1.1>
|
-Dtest_version_greater_1=$<VERSION_GREATER:1.0,1.1.1>
|
||||||
|
@ -176,6 +181,9 @@ add_custom_target(check-part3 ALL
|
||||||
-Dtest_imported_release=$<TARGET_PROPERTY:imported4,INCLUDE_DIRECTORIES>
|
-Dtest_imported_release=$<TARGET_PROPERTY:imported4,INCLUDE_DIRECTORIES>
|
||||||
-Dtest_imported_relwithdebinfo=$<TARGET_PROPERTY:imported4,INCLUDE_DIRECTORIES>
|
-Dtest_imported_relwithdebinfo=$<TARGET_PROPERTY:imported4,INCLUDE_DIRECTORIES>
|
||||||
-Dtest_imported_minsizerel=$<TARGET_PROPERTY:imported4,INCLUDE_DIRECTORIES>
|
-Dtest_imported_minsizerel=$<TARGET_PROPERTY:imported4,INCLUDE_DIRECTORIES>
|
||||||
|
-Dtest_alias_file_exe=$<STREQUAL:$<TARGET_FILE:Alias::SomeExe>,$<TARGET_FILE:someexe>>
|
||||||
|
-Dtest_alias_file_lib=$<STREQUAL:$<TARGET_FILE:Alias::SomeLib>,$<TARGET_FILE:empty1>>
|
||||||
|
-Dtest_alias_target_name=$<STREQUAL:$<TARGET_PROPERTY:Alias::SomeLib,NAME>,$<TARGET_PROPERTY:empty1,NAME>>
|
||||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/check-part3.cmake
|
-P ${CMAKE_CURRENT_SOURCE_DIR}/check-part3.cmake
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo "check done (part 3 of 3)"
|
COMMAND ${CMAKE_COMMAND} -E echo "check done (part 3 of 3)"
|
||||||
VERBATIM
|
VERBATIM
|
||||||
|
|
|
@ -20,3 +20,7 @@ foreach(c debug release relwithdebinfo minsizerel)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
check(test_alias_file_exe "1")
|
||||||
|
check(test_alias_file_lib "1")
|
||||||
|
check(test_alias_target_name "1")
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
|
#ifdef _WIN32
|
||||||
// empty
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
int main() { return 0; }
|
||||||
|
|
|
@ -98,6 +98,7 @@ add_RunCMake_test(try_compile)
|
||||||
add_RunCMake_test(variable_watch)
|
add_RunCMake_test(variable_watch)
|
||||||
add_RunCMake_test(CMP0004)
|
add_RunCMake_test(CMP0004)
|
||||||
add_RunCMake_test(TargetPolicies)
|
add_RunCMake_test(TargetPolicies)
|
||||||
|
add_RunCMake_test(alias_targets)
|
||||||
|
|
||||||
find_package(Qt4 QUIET)
|
find_package(Qt4 QUIET)
|
||||||
find_package(Qt5Core QUIET)
|
find_package(Qt5Core QUIET)
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
project(${RunCMake_TEST} NONE)
|
||||||
|
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1,20 @@
|
||||||
|
include(RunCMake)
|
||||||
|
|
||||||
|
run_cmake(no-targets)
|
||||||
|
run_cmake(multiple-targets)
|
||||||
|
run_cmake(exclude-from-all)
|
||||||
|
run_cmake(imported)
|
||||||
|
run_cmake(invalid-name)
|
||||||
|
run_cmake(invalid-target)
|
||||||
|
run_cmake(imported-target)
|
||||||
|
run_cmake(alias-target)
|
||||||
|
run_cmake(set_property)
|
||||||
|
run_cmake(set_target_properties)
|
||||||
|
run_cmake(target_link_libraries)
|
||||||
|
run_cmake(target_include_directories)
|
||||||
|
run_cmake(export)
|
||||||
|
run_cmake(install-export)
|
||||||
|
run_cmake(name-conflict)
|
||||||
|
run_cmake(add_dependencies)
|
||||||
|
run_cmake(add_executable-library)
|
||||||
|
run_cmake(add_library-executable)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,5 @@
|
||||||
|
CMake Error at add_dependencies.cmake:9 \(add_dependencies\):
|
||||||
|
Cannot add target-level dependencies to alias target "alias".
|
||||||
|
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(foo empty.cpp)
|
||||||
|
add_library(bar empty.cpp)
|
||||||
|
|
||||||
|
add_library(alias ALIAS foo)
|
||||||
|
|
||||||
|
add_dependencies(alias bar)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,5 @@
|
||||||
|
CMake Error at add_executable-library.cmake:6 \(add_executable\):
|
||||||
|
add_executable cannot create ALIAS target "alias" because target "foo" is
|
||||||
|
not an executable.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(foo empty.cpp)
|
||||||
|
|
||||||
|
add_executable(alias ALIAS foo)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,5 @@
|
||||||
|
CMake Error at add_library-executable.cmake:6 \(add_library\):
|
||||||
|
add_library cannot create ALIAS target "alias" because target "foo" is not
|
||||||
|
a library.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_executable(foo empty.cpp)
|
||||||
|
|
||||||
|
add_library(alias ALIAS foo)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,5 @@
|
||||||
|
CMake Error at alias-target.cmake:8 \(add_library\):
|
||||||
|
add_library cannot create ALIAS target "next_alias" because target "alias"
|
||||||
|
is itself an ALIAS.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(foo empty.cpp)
|
||||||
|
|
||||||
|
add_library(alias ALIAS foo)
|
||||||
|
|
||||||
|
add_library(next_alias ALIAS alias)
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifdef _WIN32
|
||||||
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
int empty()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,4 @@
|
||||||
|
CMake Error at exclude-from-all.cmake:6 \(add_library\):
|
||||||
|
add_library EXCLUDE_FROM_ALL with ALIAS makes no sense.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(foo empty.cpp)
|
||||||
|
|
||||||
|
add_library(alias ALIAS EXCLUDE_FROM_ALL foo)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,4 @@
|
||||||
|
CMake Error at export.cmake:8 \(export\):
|
||||||
|
export given ALIAS target "alias" which may not be exported.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(foo empty.cpp)
|
||||||
|
|
||||||
|
add_library(alias ALIAS foo)
|
||||||
|
|
||||||
|
export(TARGETS alias FILE someFile.cmake)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,4 @@
|
||||||
|
CMake Error at imported.cmake:2 \(add_library\):
|
||||||
|
add_library IMPORTED with ALIAS is not allowed.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,5 @@
|
||||||
|
CMake Error at imported-target.cmake:6 \(add_library\):
|
||||||
|
add_library cannot create ALIAS target "alias" because target "foo" is
|
||||||
|
IMPORTED.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(foo SHARED IMPORTED)
|
||||||
|
|
||||||
|
add_library(alias ALIAS foo)
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
add_library(alias IMPORTED ALIAS)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,4 @@
|
||||||
|
CMake Error at install-export.cmake:8 \(install\):
|
||||||
|
install TARGETS given target "alias" which is an alias.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(foo empty.cpp)
|
||||||
|
|
||||||
|
add_library(alias ALIAS foo)
|
||||||
|
|
||||||
|
install(TARGETS alias EXPORT theTargets DESTINATION prefix)
|
||||||
|
install(EXPORT theTargets DESTINATION lib/cmake)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,4 @@
|
||||||
|
CMake Error at invalid-name.cmake:6 \(add_library\):
|
||||||
|
add_library Invalid name for ALIAS: invalid\$name
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(foo empty.cpp)
|
||||||
|
|
||||||
|
add_library(invalid$name ALIAS foo)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,5 @@
|
||||||
|
CMake Error at invalid-target.cmake:2 \(add_library\):
|
||||||
|
add_library cannot create ALIAS target "alias" because target "foo" does
|
||||||
|
not already exist.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
add_library(alias ALIAS foo)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,4 @@
|
||||||
|
CMake Error at multiple-targets.cmake:7 \(add_library\):
|
||||||
|
add_library ALIAS requires exactly one target argument.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(foo empty.cpp)
|
||||||
|
add_library(bar empty.cpp)
|
||||||
|
|
||||||
|
add_library(alias ALIAS foo bar)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,5 @@
|
||||||
|
CMake Error at name-conflict.cmake:8 \(add_library\):
|
||||||
|
add_library cannot create target "bar" because an alias with the same name
|
||||||
|
already exists.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(foo empty.cpp)
|
||||||
|
|
||||||
|
add_library(bar ALIAS foo)
|
||||||
|
|
||||||
|
add_library(bar empty.cpp)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,4 @@
|
||||||
|
CMake Error at no-targets.cmake:4 \(add_library\):
|
||||||
|
add_library ALIAS requires exactly one target argument.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(alias ALIAS)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,4 @@
|
||||||
|
CMake Error at set_property.cmake:8 \(set_property\):
|
||||||
|
set_property can not be used on an ALIAS target.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(foo empty.cpp)
|
||||||
|
|
||||||
|
add_library(alias ALIAS foo)
|
||||||
|
|
||||||
|
set_property(TARGET alias PROPERTY ANYTHING 1)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,4 @@
|
||||||
|
CMake Error at set_target_properties.cmake:8 \(set_target_properties\):
|
||||||
|
set_target_properties can not be used on an ALIAS target.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(foo empty.cpp)
|
||||||
|
|
||||||
|
add_library(alias ALIAS foo)
|
||||||
|
|
||||||
|
set_target_properties(alias PROPERTIES ANYTHING 1)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,4 @@
|
||||||
|
CMake Error at target_include_directories.cmake:8 \(target_include_directories\):
|
||||||
|
target_include_directories can not be used on an ALIAS target.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(foo empty.cpp)
|
||||||
|
|
||||||
|
add_library(alias ALIAS foo)
|
||||||
|
|
||||||
|
target_include_directories(alias PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,4 @@
|
||||||
|
CMake Error at target_link_libraries.cmake:9 \(target_link_libraries\):
|
||||||
|
target_link_libraries can not be used on an ALIAS target.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(foo empty.cpp)
|
||||||
|
add_library(bar empty.cpp)
|
||||||
|
|
||||||
|
add_library(alias ALIAS foo)
|
||||||
|
|
||||||
|
target_link_libraries(alias bar)
|
Loading…
Reference in New Issue