|
|
@@ -2,6 +2,7 @@
|
|
|
file LICENSE.rst or https://cmake.org/licensing for details. */
|
|
|
#include "cmExportPackageInfoGenerator.h"
|
|
|
|
|
|
+#include <cstddef>
|
|
|
#include <memory>
|
|
|
#include <set>
|
|
|
#include <utility>
|
|
|
@@ -210,13 +211,15 @@ bool cmExportPackageInfoGenerator::GenerateInterfaceProperties(
|
|
|
}
|
|
|
|
|
|
namespace {
|
|
|
-bool forbidGeneratorExpressions(std::string const& propertyName,
|
|
|
- std::string const& propertyValue,
|
|
|
- cmGeneratorTarget const* target)
|
|
|
+bool ForbidGeneratorExpressions(
|
|
|
+ cmGeneratorTarget const* target, std::string const& propertyName,
|
|
|
+ std::string const& propertyValue, std::string& evaluatedValue,
|
|
|
+ std::map<std::string, std::vector<std::string>>& allowList)
|
|
|
{
|
|
|
- std::string const& evaluatedValue = cmGeneratorExpression::Preprocess(
|
|
|
- propertyValue, cmGeneratorExpression::StripAllGeneratorExpressions);
|
|
|
- if (evaluatedValue != propertyValue) {
|
|
|
+ size_t const allowedExpressions = allowList.size();
|
|
|
+ evaluatedValue = cmGeneratorExpression::Collect(propertyValue, allowList);
|
|
|
+ if (evaluatedValue != propertyValue &&
|
|
|
+ allowList.size() > allowedExpressions) {
|
|
|
target->Makefile->IssueMessage(
|
|
|
MessageType::FATAL_ERROR,
|
|
|
cmStrCat("Property \"", propertyName, "\" of target \"",
|
|
|
@@ -224,8 +227,32 @@ bool forbidGeneratorExpressions(std::string const& propertyName,
|
|
|
"\" contains a generator expression. This is not allowed."));
|
|
|
return false;
|
|
|
}
|
|
|
+ // Forbid Nested Generator Expressions
|
|
|
+ for (auto const& genexp : allowList) {
|
|
|
+ for (auto const& value : genexp.second) {
|
|
|
+ if (value.find("$<") != std::string::npos) {
|
|
|
+ target->Makefile->IssueMessage(
|
|
|
+ MessageType::FATAL_ERROR,
|
|
|
+ cmStrCat(
|
|
|
+ "$<", genexp.first, ":...> expression in \"", propertyName,
|
|
|
+ "\" of target \"", target->GetName(),
|
|
|
+ "\" contains a generator expression. This is not allowed."));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
return true;
|
|
|
}
|
|
|
+
|
|
|
+bool ForbidGeneratorExpressions(cmGeneratorTarget const* target,
|
|
|
+ std::string const& propertyName,
|
|
|
+ std::string const& propertyValue)
|
|
|
+{
|
|
|
+ std::map<std::string, std::vector<std::string>> allowList;
|
|
|
+ std::string evaluatedValue;
|
|
|
+ return ForbidGeneratorExpressions(target, propertyName, propertyValue,
|
|
|
+ evaluatedValue, allowList);
|
|
|
+}
|
|
|
}
|
|
|
|
|
|
bool cmExportPackageInfoGenerator::NoteLinkedTarget(
|
|
|
@@ -317,31 +344,43 @@ void cmExportPackageInfoGenerator::GenerateInterfaceLinkProperties(
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // TODO: Support $<LINK_ONLY>.
|
|
|
- if (!forbidGeneratorExpressions(iter->first, iter->second, target)) {
|
|
|
+ // Extract any $<LINK_ONLY:...> from the link libraries, and assert that no
|
|
|
+ // other generator expressions are present.
|
|
|
+ std::map<std::string, std::vector<std::string>> allowList = { { "LINK_ONLY",
|
|
|
+ {} } };
|
|
|
+ std::string interfaceLinkLibraries;
|
|
|
+ if (!ForbidGeneratorExpressions(target, iter->first, iter->second,
|
|
|
+ interfaceLinkLibraries, allowList)) {
|
|
|
result = false;
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- std::vector<std::string> buildRequires;
|
|
|
- // std::vector<std::string> linkRequires; TODO
|
|
|
std::vector<std::string> linkLibraries;
|
|
|
+ std::vector<std::string> linkRequires;
|
|
|
+ std::vector<std::string> buildRequires;
|
|
|
|
|
|
- for (auto const& name : cmList{ iter->second }) {
|
|
|
- auto const& ti = this->LinkTargets.find(name);
|
|
|
- if (ti != this->LinkTargets.end()) {
|
|
|
- if (ti->second.empty()) {
|
|
|
- result = false;
|
|
|
+ auto addLibraries = [this, &linkLibraries,
|
|
|
+ &result](std::vector<std::string> const& names,
|
|
|
+ std::vector<std::string>& output) -> void {
|
|
|
+ for (auto const& name : names) {
|
|
|
+ auto const& ti = this->LinkTargets.find(name);
|
|
|
+ if (ti != this->LinkTargets.end()) {
|
|
|
+ if (ti->second.empty()) {
|
|
|
+ result = false;
|
|
|
+ } else {
|
|
|
+ output.emplace_back(ti->second);
|
|
|
+ }
|
|
|
} else {
|
|
|
- buildRequires.emplace_back(ti->second);
|
|
|
+ linkLibraries.emplace_back(name);
|
|
|
}
|
|
|
- } else {
|
|
|
- linkLibraries.emplace_back(name);
|
|
|
}
|
|
|
- }
|
|
|
+ };
|
|
|
+
|
|
|
+ addLibraries(allowList["LINK_ONLY"], linkRequires);
|
|
|
+ addLibraries(cmList{ interfaceLinkLibraries }, buildRequires);
|
|
|
|
|
|
buildArray(component, "requires", buildRequires);
|
|
|
- // buildArray(component, "link_requires", linkRequires); TODO
|
|
|
+ buildArray(component, "link_requires", linkRequires);
|
|
|
buildArray(component, "link_libraries", linkLibraries);
|
|
|
}
|
|
|
|
|
|
@@ -354,7 +393,7 @@ void cmExportPackageInfoGenerator::GenerateInterfaceCompileFeatures(
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (!forbidGeneratorExpressions(iter->first, iter->second, target)) {
|
|
|
+ if (!ForbidGeneratorExpressions(target, iter->first, iter->second)) {
|
|
|
result = false;
|
|
|
return;
|
|
|
}
|
|
|
@@ -383,7 +422,7 @@ void cmExportPackageInfoGenerator::GenerateInterfaceCompileDefines(
|
|
|
}
|
|
|
|
|
|
// TODO: Support language-specific defines.
|
|
|
- if (!forbidGeneratorExpressions(iter->first, iter->second, target)) {
|
|
|
+ if (!ForbidGeneratorExpressions(target, iter->first, iter->second)) {
|
|
|
result = false;
|
|
|
return;
|
|
|
}
|
|
|
@@ -414,7 +453,7 @@ void cmExportPackageInfoGenerator::GenerateInterfaceListProperty(
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (!forbidGeneratorExpressions(prop, iter->second, target)) {
|
|
|
+ if (!ForbidGeneratorExpressions(target, prop, iter->second)) {
|
|
|
result = false;
|
|
|
return;
|
|
|
}
|