diff options
author | Stephen Kelly <steveire@gmail.com> | 2012-12-10 22:07:09 (GMT) |
---|---|---|
committer | Stephen Kelly <steveire@gmail.com> | 2013-01-05 00:18:36 (GMT) |
commit | e04f737c7a3e66c49e2d50813af1fa40a415eff8 (patch) | |
tree | 25cbf74d6303780829668e6bda8f15f05f1741a8 /Source/cmExportFileGenerator.cxx | |
parent | b0c8f73eb62c5651b4a039f95676cae310bcada9 (diff) | |
download | CMake-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.cxx | 136 |
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, |