[cmake-developers] conditionals in generator expressions
Stephen Kelly
steveire at gmail.com
Fri Aug 31 07:21:53 EDT 2012
I realised that what I wrote yesterday was not completely correct:
Stephen Kelly wrote:
>>> set_target_properties(foolib
>>>PROPERTIES COMPILE_OPTIONS
>>>"$<$<CONFIG:Debug>:-Wl$<COMMA>no-undefined>"
>>> )
>>
>> That is a good example of a reason not to use comma for separation.
The above is not necessary. It can instead be literally:
"$<$<CONFIG:Debug>:-Wl,no-undefined>"
"$<$<AND:$<CONFIG:Debug>,$<STREQUAL:$<TGT_PROP:FOO>,b>>:-Wl,no-undefined>"
The comma is ambiguous to the parser, but not to the generator expression.
I've updated my -refactor branch to deal with it.
$<1:...> already knows that the comma is not separating multiple parameters
because it knows it only takes one parameter of arbitrary content. So if it
is given multiple parameters, it can simply join them.
This is the most useful case and the most common case where a comma can
appear.
$<STREQUAL:a,b> can still be ambiguous, but considering the use-cases for
STREQUAL I think it's ok. We can make it an error for anything other than
one comma to appear literally there.
The use-cases for STREQUAL could be for comparing target names, target
properties, expected target property values, OS names, compiler names,
expected configuration names etc. I'm not aware of any of those containing a
comma.
STREQUAL doesn't need to be so general purpose that it must be able to
compare any two strings. We can optimise for the string literals we know
will be useful to it. As far as I can see, none of those would generally
contain commas. Even if a target property does contain a comma, and that is
tested in a generator expression, no existing code already makes use of
generator expressions in this way, so no existing code can break. The
options for existing code would be to use $<COMMA> or change the value of
the target property to not contain a comma if it is to be used in a STREQUAL
comparison (I can't think of any situations where the comma would be the
useful part of such a design).
It is allowed by cmake to use commas in target names and property names, but
again, that just means that if such targets or properties can't be used in
the TARGET_PROPERTY generator expression because of ambiguity
$<TARGET_PROPERTY:prop>
$<TARGET_PROPERTY:tgt,prop>
is $<TARGET_PROPERTY:hello,world> about a property on *this called
'hello,world', or a target 'hello' with a property 'world'. Using commas in
target and property names is so unusual and uncommon that I think we can
just ignore it.
So, given that the use of $<COMMA> would be so rare, my preference is to
keep the existing design in next, and add something similar to the parser
now in my branch.
>> I think I can adapt the parser to that.
>
> Before jumping into the code please try to construct a formal grammar
> for discussion. That will split review of the code from review of
> the grammar.
I don't know much about formal grammars, but I tried creating a pseudo-EBNF
of what is in my branch (similar to what is in next/master):
content = plain-text, {generator-expression, [plain-text]};
plain-text = NOT generator-expression;
generator-expression = "$<", content, [":", content, {",", content}], ">";
I'm not certain it's more useful than the code :). Can you provide a more
useful one describing what is in next/master now?
Thanks,
Steve.
More information about the cmake-developers
mailing list