summaryrefslogtreecommitdiffstats
path: root/Source/cmExportFileGenerator.cxx
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2012-12-10 22:07:09 (GMT)
committerStephen Kelly <steveire@gmail.com>2013-01-05 00:18:36 (GMT)
commite04f737c7a3e66c49e2d50813af1fa40a415eff8 (patch)
tree25cbf74d6303780829668e6bda8f15f05f1741a8 /Source/cmExportFileGenerator.cxx
parentb0c8f73eb62c5651b4a039f95676cae310bcada9 (diff)
downloadCMake-e04f737c7a3e66c49e2d50813af1fa40a415eff8.zip
CMake-e04f737c7a3e66c49e2d50813af1fa40a415eff8.tar.gz
CMake-e04f737c7a3e66c49e2d50813af1fa40a415eff8.tar.bz2
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.
Diffstat (limited to 'Source/cmExportFileGenerator.cxx')
-rw-r--r--Source/cmExportFileGenerator.cxx136
1 files changed, 136 insertions, 0 deletions
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 3f738cc..2507b72 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -126,6 +126,142 @@ void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
//----------------------------------------------------------------------------
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
::SetImportDetailProperties(const char* config, std::string const& suffix,
cmTarget* target, ImportPropertyMap& properties,