Add API to extract target names from a genex string.
The TARGET_NAME expression, which requires a literal, provides target names. $<TARGET_PROPERTY:tgt,prop> also provides target names in the cases where tgt is a literal, so that TARGET_NAME is not needed then in addition.
This commit is contained in:
parent
b0c8f73eb6
commit
e04f737c7a
|
@ -124,6 +124,142 @@ void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
|
|||
this->GenerateImportTargetsConfig(os, config, suffix);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
|
||||
std::string &input,
|
||||
cmTarget* target,
|
||||
std::vector<std::string> &missingTargets)
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type lastPos = pos;
|
||||
|
||||
cmMakefile *mf = target->GetMakefile();
|
||||
std::string errorString;
|
||||
|
||||
while((pos = input.find("$<TARGET_PROPERTY:", lastPos)) != input.npos)
|
||||
{
|
||||
std::string::size_type nameStartPos = pos +
|
||||
sizeof("$<TARGET_PROPERTY:") - 1;
|
||||
std::string::size_type closePos = input.find(">", nameStartPos);
|
||||
std::string::size_type commaPos = input.find(",", nameStartPos);
|
||||
std::string::size_type nextOpenPos = input.find("$<", nameStartPos);
|
||||
if (commaPos == input.npos // Implied 'this' target
|
||||
|| closePos == input.npos // Imcomplete expression.
|
||||
|| closePos < commaPos // Implied 'this' target
|
||||
|| nextOpenPos < commaPos) // Non-literal
|
||||
{
|
||||
lastPos = nameStartPos;
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string targetName = input.substr(nameStartPos,
|
||||
commaPos - nameStartPos);
|
||||
|
||||
pos = nameStartPos; // We're not going to replace the entire expression,
|
||||
// but only the target parameter.
|
||||
if (cmTarget *tgt = mf->FindTargetToUse(targetName.c_str()))
|
||||
{
|
||||
if(tgt->IsImported())
|
||||
{
|
||||
pos += targetName.size();
|
||||
}
|
||||
else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
|
||||
{
|
||||
input.replace(pos, targetName.size(),
|
||||
this->Namespace + targetName);
|
||||
pos += this->Namespace.size() + targetName.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string namespacedTarget;
|
||||
this->HandleMissingTarget(namespacedTarget, missingTargets,
|
||||
mf, target, tgt);
|
||||
if (!namespacedTarget.empty())
|
||||
{
|
||||
input.replace(pos, targetName.size(), namespacedTarget);
|
||||
pos += namespacedTarget.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorString = "$<TARGET_PROPERTY:" + targetName + ",prop> requires "
|
||||
"its first parameter to be a reachable target.";
|
||||
}
|
||||
lastPos = pos;
|
||||
if (!errorString.empty())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!errorString.empty())
|
||||
{
|
||||
mf->IssueMessage(cmake::FATAL_ERROR, errorString);
|
||||
return;
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
lastPos = pos;
|
||||
while((pos = input.find("$<TARGET_NAME:", lastPos)) != input.npos)
|
||||
{
|
||||
std::string::size_type nameStartPos = pos + sizeof("$<TARGET_NAME:") - 1;
|
||||
std::string::size_type endPos = input.find(">", nameStartPos);
|
||||
if (endPos == input.npos)
|
||||
{
|
||||
errorString = "$<TARGET_NAME:...> expression incomplete";
|
||||
}
|
||||
const std::string targetName = input.substr(nameStartPos,
|
||||
endPos - nameStartPos);
|
||||
if(targetName.find("$<", lastPos) != input.npos)
|
||||
{
|
||||
errorString = "$<TARGET_NAME:...> requires its parameter to be a "
|
||||
"literal.";
|
||||
}
|
||||
if (cmTarget *tgt = mf->FindTargetToUse(targetName.c_str()))
|
||||
{
|
||||
if(tgt->IsImported())
|
||||
{
|
||||
input.replace(pos, sizeof("$<TARGET_NAME:") + targetName.size(),
|
||||
targetName);
|
||||
pos += sizeof("$<TARGET_NAME:") + targetName.size();
|
||||
}
|
||||
else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
|
||||
{
|
||||
input.replace(pos, sizeof("$<TARGET_NAME:") + targetName.size(),
|
||||
this->Namespace + targetName);
|
||||
pos += sizeof("$<TARGET_NAME:") + targetName.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string namespacedTarget;
|
||||
this->HandleMissingTarget(namespacedTarget, missingTargets,
|
||||
mf, target, tgt);
|
||||
if (!namespacedTarget.empty())
|
||||
{
|
||||
input.replace(pos, sizeof("$<TARGET_NAME:") + targetName.size(),
|
||||
namespacedTarget);
|
||||
pos += sizeof("$<TARGET_NAME:") + targetName.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorString = "$<TARGET_NAME:...> requires its parameter to be a "
|
||||
"reachable target.";
|
||||
}
|
||||
lastPos = pos;
|
||||
if (!errorString.empty())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!errorString.empty())
|
||||
{
|
||||
mf->IssueMessage(cmake::FATAL_ERROR, errorString);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmExportFileGenerator
|
||||
|
|
|
@ -94,6 +94,10 @@ protected:
|
|||
cmTarget* depender,
|
||||
cmTarget* dependee) = 0;
|
||||
|
||||
void ResolveTargetsInGeneratorExpressions(std::string &input,
|
||||
cmTarget* target,
|
||||
std::vector<std::string> &missingTargets);
|
||||
|
||||
// The namespace in which the exports are placed in the generated file.
|
||||
std::string Namespace;
|
||||
|
||||
|
|
Loading…
Reference in New Issue