Merge topic 'join-genex'
a7ba452
Add the JOIN generator expression.96ec314
Make it possible for any genex to have arbitrary content at the end.bd638ee
Rename the method determining if a genex accepts arbitrary content.dc742fe
Extract the ProcessArbitraryContent method.
This commit is contained in:
commit
3db29d2724
|
@ -28,6 +28,8 @@
|
||||||
"strings which contain a ',' for example.\n" \
|
"strings which contain a ',' for example.\n" \
|
||||||
" $<SEMICOLON> = A literal ';'. Used to prevent " \
|
" $<SEMICOLON> = A literal ';'. Used to prevent " \
|
||||||
"list expansion on an argument with ';'.\n" \
|
"list expansion on an argument with ';'.\n" \
|
||||||
|
" $<JOIN:list,...> = joins the list with the content of " \
|
||||||
|
"\"...\"\n" \
|
||||||
" $<TARGET_NAME:...> = Marks ... as being the name of a " \
|
" $<TARGET_NAME:...> = Marks ... as being the name of a " \
|
||||||
"target. This is required if exporting targets to multiple " \
|
"target. This is required if exporting targets to multiple " \
|
||||||
"dependent export sets. The '...' must be a literal name of a " \
|
"dependent export sets. The '...' must be a literal name of a " \
|
||||||
|
|
|
@ -51,7 +51,7 @@ struct cmGeneratorExpressionNode
|
||||||
|
|
||||||
virtual bool RequiresLiteralInput() const { return false; }
|
virtual bool RequiresLiteralInput() const { return false; }
|
||||||
|
|
||||||
virtual bool AcceptsSingleArbitraryContentParameter() const
|
virtual bool AcceptsArbitraryContentParameter() const
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
virtual int NumExpectedParameters() const { return 1; }
|
virtual int NumExpectedParameters() const { return 1; }
|
||||||
|
@ -70,7 +70,7 @@ static const struct ZeroNode : public cmGeneratorExpressionNode
|
||||||
|
|
||||||
virtual bool GeneratesContent() const { return false; }
|
virtual bool GeneratesContent() const { return false; }
|
||||||
|
|
||||||
virtual bool AcceptsSingleArbitraryContentParameter() const { return true; }
|
virtual bool AcceptsArbitraryContentParameter() const { return true; }
|
||||||
|
|
||||||
std::string Evaluate(const std::vector<std::string> &,
|
std::string Evaluate(const std::vector<std::string> &,
|
||||||
cmGeneratorExpressionContext *,
|
cmGeneratorExpressionContext *,
|
||||||
|
@ -87,7 +87,7 @@ static const struct OneNode : public cmGeneratorExpressionNode
|
||||||
{
|
{
|
||||||
OneNode() {}
|
OneNode() {}
|
||||||
|
|
||||||
virtual bool AcceptsSingleArbitraryContentParameter() const { return true; }
|
virtual bool AcceptsArbitraryContentParameter() const { return true; }
|
||||||
|
|
||||||
std::string Evaluate(const std::vector<std::string> &,
|
std::string Evaluate(const std::vector<std::string> &,
|
||||||
cmGeneratorExpressionContext *,
|
cmGeneratorExpressionContext *,
|
||||||
|
@ -307,6 +307,34 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
|
||||||
} configurationTestNode;
|
} configurationTestNode;
|
||||||
|
|
||||||
|
|
||||||
|
static const struct JoinNode : public cmGeneratorExpressionNode
|
||||||
|
{
|
||||||
|
JoinNode() {}
|
||||||
|
|
||||||
|
virtual int NumExpectedParameters() const { return 2; }
|
||||||
|
|
||||||
|
virtual bool AcceptsArbitraryContentParameter() const { return true; }
|
||||||
|
|
||||||
|
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||||
|
cmGeneratorExpressionContext *,
|
||||||
|
const GeneratorExpressionContent *,
|
||||||
|
cmGeneratorExpressionDAGChecker *) const
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
|
||||||
|
std::vector<std::string> list;
|
||||||
|
cmSystemTools::ExpandListArgument(parameters.front(), list);
|
||||||
|
std::string sep;
|
||||||
|
for(std::vector<std::string>::const_iterator li = list.begin();
|
||||||
|
li != list.end(); ++li)
|
||||||
|
{
|
||||||
|
result += sep + *li;
|
||||||
|
sep = parameters[1];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} joinNode;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
static const char* targetPropertyTransitiveWhitelist[] = {
|
static const char* targetPropertyTransitiveWhitelist[] = {
|
||||||
"INTERFACE_INCLUDE_DIRECTORIES"
|
"INTERFACE_INCLUDE_DIRECTORIES"
|
||||||
|
@ -600,7 +628,7 @@ static const struct TargetNameNode : public cmGeneratorExpressionNode
|
||||||
|
|
||||||
virtual bool GeneratesContent() const { return true; }
|
virtual bool GeneratesContent() const { return true; }
|
||||||
|
|
||||||
virtual bool AcceptsSingleArbitraryContentParameter() const { return true; }
|
virtual bool AcceptsArbitraryContentParameter() const { return true; }
|
||||||
virtual bool RequiresLiteralInput() const { return true; }
|
virtual bool RequiresLiteralInput() const { return true; }
|
||||||
|
|
||||||
std::string Evaluate(const std::vector<std::string> ¶meters,
|
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||||
|
@ -973,6 +1001,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
|
||||||
return &installInterfaceNode;
|
return &installInterfaceNode;
|
||||||
else if (identifier == "INSTALL_PREFIX")
|
else if (identifier == "INSTALL_PREFIX")
|
||||||
return &installPrefixNode;
|
return &installPrefixNode;
|
||||||
|
else if (identifier == "JOIN")
|
||||||
|
return &joinNode;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -992,6 +1022,57 @@ std::string GeneratorExpressionContent::GetOriginalExpression() const
|
||||||
return std::string(this->StartContent, this->ContentLength);
|
return std::string(this->StartContent, this->ContentLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::string GeneratorExpressionContent::ProcessArbitraryContent(
|
||||||
|
const cmGeneratorExpressionNode *node,
|
||||||
|
const std::string &identifier,
|
||||||
|
cmGeneratorExpressionContext *context,
|
||||||
|
cmGeneratorExpressionDAGChecker *dagChecker,
|
||||||
|
std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
|
||||||
|
pit) const
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
|
||||||
|
const
|
||||||
|
std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
|
||||||
|
pend = this->ParamChildren.end();
|
||||||
|
for ( ; pit != pend; ++pit)
|
||||||
|
{
|
||||||
|
std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it
|
||||||
|
= pit->begin();
|
||||||
|
const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end
|
||||||
|
= pit->end();
|
||||||
|
for ( ; it != end; ++it)
|
||||||
|
{
|
||||||
|
if (node->RequiresLiteralInput())
|
||||||
|
{
|
||||||
|
if ((*it)->GetType() != cmGeneratorExpressionEvaluator::Text)
|
||||||
|
{
|
||||||
|
reportError(context, this->GetOriginalExpression(),
|
||||||
|
"$<" + identifier + "> expression requires literal input.");
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result += (*it)->Evaluate(context, dagChecker);
|
||||||
|
if (context->HadError)
|
||||||
|
{
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((pit + 1) != pend)
|
||||||
|
{
|
||||||
|
result += ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node->RequiresLiteralInput())
|
||||||
|
{
|
||||||
|
std::vector<std::string> parameters;
|
||||||
|
parameters.push_back(result);
|
||||||
|
return node->Evaluate(parameters, context, this, dagChecker);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
std::string GeneratorExpressionContent::Evaluate(
|
std::string GeneratorExpressionContent::Evaluate(
|
||||||
cmGeneratorExpressionContext *context,
|
cmGeneratorExpressionContext *context,
|
||||||
|
@ -1024,7 +1105,8 @@ std::string GeneratorExpressionContent::Evaluate(
|
||||||
|
|
||||||
if (!node->GeneratesContent())
|
if (!node->GeneratesContent())
|
||||||
{
|
{
|
||||||
if (node->AcceptsSingleArbitraryContentParameter())
|
if (node->NumExpectedParameters() == 1
|
||||||
|
&& node->AcceptsArbitraryContentParameter())
|
||||||
{
|
{
|
||||||
if (this->ParamChildren.empty())
|
if (this->ParamChildren.empty())
|
||||||
{
|
{
|
||||||
|
@ -1041,49 +1123,12 @@ std::string GeneratorExpressionContent::Evaluate(
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->AcceptsSingleArbitraryContentParameter())
|
if (node->NumExpectedParameters() == 1
|
||||||
|
&& node->AcceptsArbitraryContentParameter())
|
||||||
{
|
{
|
||||||
std::string result;
|
return this->ProcessArbitraryContent(node, identifier, context,
|
||||||
std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
|
dagChecker,
|
||||||
pit = this->ParamChildren.begin();
|
this->ParamChildren.begin());
|
||||||
const
|
|
||||||
std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
|
|
||||||
pend = this->ParamChildren.end();
|
|
||||||
for ( ; pit != pend; ++pit)
|
|
||||||
{
|
|
||||||
std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it
|
|
||||||
= pit->begin();
|
|
||||||
const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end
|
|
||||||
= pit->end();
|
|
||||||
for ( ; it != end; ++it)
|
|
||||||
{
|
|
||||||
if (node->RequiresLiteralInput())
|
|
||||||
{
|
|
||||||
if ((*it)->GetType() != cmGeneratorExpressionEvaluator::Text)
|
|
||||||
{
|
|
||||||
reportError(context, this->GetOriginalExpression(),
|
|
||||||
"$<" + identifier + "> expression requires literal input.");
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result += (*it)->Evaluate(context, dagChecker);
|
|
||||||
if (context->HadError)
|
|
||||||
{
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((pit + 1) != pend)
|
|
||||||
{
|
|
||||||
result += ",";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (node->RequiresLiteralInput())
|
|
||||||
{
|
|
||||||
std::vector<std::string> parameters;
|
|
||||||
parameters.push_back(result);
|
|
||||||
return node->Evaluate(parameters, context, this, dagChecker);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> parameters;
|
std::vector<std::string> parameters;
|
||||||
|
@ -1104,12 +1149,15 @@ std::string GeneratorExpressionContent::EvaluateParameters(
|
||||||
cmGeneratorExpressionDAGChecker *dagChecker,
|
cmGeneratorExpressionDAGChecker *dagChecker,
|
||||||
std::vector<std::string> ¶meters) const
|
std::vector<std::string> ¶meters) const
|
||||||
{
|
{
|
||||||
|
const int numExpected = node->NumExpectedParameters();
|
||||||
{
|
{
|
||||||
std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
|
std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
|
||||||
pit = this->ParamChildren.begin();
|
pit = this->ParamChildren.begin();
|
||||||
const
|
const
|
||||||
std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
|
std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
|
||||||
pend = this->ParamChildren.end();
|
pend = this->ParamChildren.end();
|
||||||
|
const bool acceptsArbitraryContent
|
||||||
|
= node->AcceptsArbitraryContentParameter();
|
||||||
for ( ; pit != pend; ++pit)
|
for ( ; pit != pend; ++pit)
|
||||||
{
|
{
|
||||||
std::string parameter;
|
std::string parameter;
|
||||||
|
@ -1126,10 +1174,20 @@ std::string GeneratorExpressionContent::EvaluateParameters(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parameters.push_back(parameter);
|
parameters.push_back(parameter);
|
||||||
|
if (acceptsArbitraryContent
|
||||||
|
&& parameters.size() == (unsigned int)numExpected - 1)
|
||||||
|
{
|
||||||
|
assert(pit != pend);
|
||||||
|
std::string lastParam = this->ProcessArbitraryContent(node, identifier,
|
||||||
|
context,
|
||||||
|
dagChecker,
|
||||||
|
pit + 1);
|
||||||
|
parameters.push_back(lastParam);
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int numExpected = node->NumExpectedParameters();
|
|
||||||
if ((numExpected != -1 && (unsigned int)numExpected != parameters.size()))
|
if ((numExpected != -1 && (unsigned int)numExpected != parameters.size()))
|
||||||
{
|
{
|
||||||
if (numExpected == 0)
|
if (numExpected == 0)
|
||||||
|
|
|
@ -129,6 +129,14 @@ private:
|
||||||
cmGeneratorExpressionDAGChecker *dagChecker,
|
cmGeneratorExpressionDAGChecker *dagChecker,
|
||||||
std::vector<std::string> ¶meters) const;
|
std::vector<std::string> ¶meters) const;
|
||||||
|
|
||||||
|
std::string ProcessArbitraryContent(
|
||||||
|
const cmGeneratorExpressionNode *node,
|
||||||
|
const std::string &identifier,
|
||||||
|
cmGeneratorExpressionContext *context,
|
||||||
|
cmGeneratorExpressionDAGChecker *dagChecker,
|
||||||
|
std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
|
||||||
|
pit) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<cmGeneratorExpressionEvaluator*> IdentifierChildren;
|
std::vector<cmGeneratorExpressionEvaluator*> IdentifierChildren;
|
||||||
std::vector<std::vector<cmGeneratorExpressionEvaluator*> > ParamChildren;
|
std::vector<std::vector<cmGeneratorExpressionEvaluator*> > ParamChildren;
|
||||||
|
|
|
@ -20,10 +20,16 @@ static const char very_fun_string[] = CMAKE_IS_REALLY;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
StringLiteralTest1 = sizeof(CMakeStaticAssert<sizeof(CMAKE_IS_) == sizeof("Fun")>)
|
StringLiteralTest1 = sizeof(CMakeStaticAssert<sizeof(CMAKE_IS_) == sizeof("Fun")>),
|
||||||
#ifndef NO_SPACES_IN_DEFINE_VALUES
|
#ifndef NO_SPACES_IN_DEFINE_VALUES
|
||||||
,
|
StringLiteralTest2 = sizeof(CMakeStaticAssert<sizeof(CMAKE_IS_REALLY) == sizeof("Very Fun")>),
|
||||||
StringLiteralTest2 = sizeof(CMakeStaticAssert<sizeof(CMAKE_IS_REALLY) == sizeof("Very Fun")>)
|
#endif
|
||||||
|
#ifdef TEST_GENERATOR_EXPRESSIONS
|
||||||
|
StringLiteralTest3 = sizeof(CMakeStaticAssert<sizeof(LETTER_LIST1) == sizeof("A,B,C,D")>),
|
||||||
|
StringLiteralTest4 = sizeof(CMakeStaticAssert<sizeof(LETTER_LIST2) == sizeof("A,,B,,C,,D")>),
|
||||||
|
StringLiteralTest5 = sizeof(CMakeStaticAssert<sizeof(LETTER_LIST3) == sizeof("A,-B,-C,-D")>),
|
||||||
|
StringLiteralTest6 = sizeof(CMakeStaticAssert<sizeof(LETTER_LIST4) == sizeof("A-,-B-,-C-,-D")>),
|
||||||
|
StringLiteralTest7 = sizeof(CMakeStaticAssert<sizeof(LETTER_LIST5) == sizeof("A-,B-,C-,D")>)
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,6 +48,14 @@ enum {
|
||||||
#error Expected define expanded from list
|
#error Expected define expanded from list
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef PREFIX_DEF1
|
||||||
|
#error Expect PREFIX_DEF1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PREFIX_DEF2
|
||||||
|
#error Expect PREFIX_DEF2
|
||||||
|
#endif
|
||||||
|
|
||||||
// TEST_GENERATOR_EXPRESSIONS
|
// TEST_GENERATOR_EXPRESSIONS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,12 @@ set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS
|
||||||
"$<1:CMAKE_IS_DECLARATIVE>"
|
"$<1:CMAKE_IS_DECLARATIVE>"
|
||||||
"$<0:GE_NOT_DEFINED>"
|
"$<0:GE_NOT_DEFINED>"
|
||||||
"$<1:ARGUMENT;LIST>"
|
"$<1:ARGUMENT;LIST>"
|
||||||
|
PREFIX_$<JOIN:DEF1;DEF2,;PREFIX_>
|
||||||
|
LETTER_LIST1=\"$<JOIN:A;B;C;D,,>\"
|
||||||
|
LETTER_LIST2=\"$<JOIN:A;B;C;D,,,>\"
|
||||||
|
LETTER_LIST3=\"$<JOIN:A;B;C;D,,->\"
|
||||||
|
LETTER_LIST4=\"$<JOIN:A;B;C;D,-,->\"
|
||||||
|
LETTER_LIST5=\"$<JOIN:A;B;C;D,-,>\"
|
||||||
)
|
)
|
||||||
|
|
||||||
set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS
|
set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS
|
||||||
|
|
|
@ -123,3 +123,8 @@ target_link_libraries(lib5 libbad libgood)
|
||||||
target_include_directories(lib5
|
target_include_directories(lib5
|
||||||
BEFORE PRIVATE $<TARGET_PROPERTY:libgood,INTERFACE_INCLUDE_DIRECTORIES>
|
BEFORE PRIVATE $<TARGET_PROPERTY:libgood,INTERFACE_INCLUDE_DIRECTORIES>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/prefix_foo/prefix_bar/prefix_bat")
|
||||||
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/prefix_foo/prefix_bar/prefix_bat/prefix_foo_bar_bat.h" "// prefix_foo_bar_bat.h\n")
|
||||||
|
|
||||||
|
target_include_directories(TargetIncludeDirectories PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/prefix_$<JOIN:foo;bar;bat,/prefix_>")
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "arguments.h"
|
#include "arguments.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
#include "prefix_foo_bar_bat.h"
|
||||||
|
|
||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue