[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