[cmake-developers] conditionals in generator expressions

Brad King brad.king at kitware.com
Thu Jun 7 12:07:50 EDT 2012


On 06/07/2012 11:41 AM, Stephen Kelly wrote:
> Brad King wrote:
>> On 06/05/2012 04:59 PM, Stephen Kelly wrote:
>>> generator_expression(myGenExpr)
>>
>> That is an interesting idea to keep in mind for the future but I think
>> the implementation of it is too tricky to be in scope now.
> 
> That's a little unfortunate. I'm not familiar enough with the existing 
> implementation to understand why yet that is so. 

Allowing arbitrary code to run during generate time will be very
difficult to get right.  In what initial state does it run?
Can any command be invoked?  What side effects can it have?
In what order do they run in case side effects interact?  Does
it run separately for every combination of possible input
(language, config, etc.)?  How do names/variables/functions in
the generator_expression body bind?

The above questions are rhetorical to illustrate the difficulty of
the proposal.  I'm quite happy with the alternative now proposed.

>>  $<TARGET_PROPERTY_BOOL:WIN32_EXECUTABLE,tgt>  = 0 or 1
> 
> Are you sure about this one? Given your further explanation below, and 
> assuming the intention is 'link to tgt if *this has a WIN32_EXECUTABLE 
> property which is True', it should rather be:
> 
> $<$<TARGET_PROPERTY_BOOL:WIN32_EXECUTABLE>:tgt>

The TARGET_PROPERTY_BOOL condition needs to know in what target
to check the property.  Therefore it needs both the target name
and the property name:

  $<$<TARGET_PROPERTY_BOOL:WIN32_EXECUTABLE,exe-getting-linked>:lib-to-link>

I suppose the "exe-getting-linked" can be implied when the
expression appears inside the list of link libraries for a target,
just as the $<LANGUAGE:...> condition tests the language implied by
the context.

>>  $<$<CONFIG:Debug>:/path/for/Debug>
>>  $<$<NOT:$<CONFIG:Debug>>:/path/for/non-Debug>
>>  $<$<AND:$<CONFIG:Debug>,$<LANGUAGE:CXX>>:/path/for/Debug/Cxx>
> 
> There's a lot of repetition, at least in these examples. If there's a lot 
> also in the real world, it might be more maintenance burden than 
> convenience. 

The goal is to provide a minimal workable interface.  If it becomes
too verbose we can enhance it later.  The above examples are contrived
to demonstrate capabilities.  A more realistic example might be:

 set(FOO_INCLUDE_DIRS
   $<$<CONFIG:Debug>:${FOO_INCLUDE_DIRS_DEBUG}>
   $<$<CONFIG:Release>:${FOO_INCLUDE_DIRS_RELEASE}>
   )

Even if a given condition needs to be repeated it can be stored in
a normal variable "cond" and referenced later "${cond}".  The
final verbose generator expressions that the evaluator sees do not
have to appear verbatim in source.

-Brad



More information about the cmake-developers mailing list