[cmake-developers] Setting includes, defines and other usage requirements with one command

Stephen Kelly steveire at gmail.com
Wed Jan 30 12:09:42 EST 2013


Brad King wrote:

> On 01/30/2013 10:57 AM, Stephen Kelly wrote:
>> Now that fix-target-property-commands was merged to master, I've rebased
>> tll-includes-defines to master and your testcase works.
> 
> Thanks.  However, now it leaks out all non-targets referenced by tll
> as giant strings in the exported interfaces:
> 
>  if(NOT ${CMAKE_FIND_PACKAGE_NAME}_NO_INTERFACES)
>    set_target_properties(bar PROPERTIES
>      INTERFACE_COMPILE_DEFINITIONS
>      "$<TARGET_PROPERTY:foo,INTERFACE_COMPILE_DEFINITIONS>;
$<$<TARGET_DEFINED:m>:$<TARGET_PROPERTY:m,INTERFACE_COMPILE_DEFINITIONS>>"
>      INTERFACE_INCLUDE_DIRECTORIES
>      "$<TARGET_PROPERTY:foo,INTERFACE_INCLUDE_DIRECTORIES>;
$<$<TARGET_DEFINED:m>:$<TARGET_PROPERTY:m,INTERFACE_INCLUDE_DIRECTORIES>>"
>    )
>  endif()
> 
> This is not acceptable.  We need to recognize when something was added
> by tll and was not a target and remove it from the non-linking interfaces.
> Can export() and install(EXPORT) do partial evaluation to remove these?

As preprocessing is how things like that are done so far, I think using 
preprocessing is the more straightforward way to do this at the moment. At 
some point in the future we can see if partial evaluation is possible. It 
would be possible to do in a later release if it is possible at all.

> We can document that $<TARGET_DEFINED> has scope only in the current
> project and will be processed away during export.  I do not think we
> want an upstream interface modifying its behavior based on the mere
> presence of an arbitrary target in the downstream anyway.
> 
> Other thoughts:
> 
> * The $<INSTALL_PREFIX> expression should evaluate as an error if
>   it is ever reached by any path except install(EXPORT).  Otherwise
>   the empty string in $<INSTALL_PREFIX>/somewhere is unlikely to
>   do the right thing.

Right. I've added a patch to that effect now.

> 
> * If exported interfaces were partially evaluated then $<INSTALL_PREFIX>
>   could be handled with a real evaluation instead of string replacement.
> 
> * Transitive linking is handled in C++ code rather than in generator
>   expressions so there is no bloat in the LINK_LIBRARIES properties
>   for non-target elements like the above.  Perhaps we can have a special
>   generator expression that has context-sensitive evaluation e.g.
> 
>     $<LINKED:blah>

That makes sense to me. I don't have time to do it right now though. Maybe I 
can do it later.

> 
>   tll() would add this to COMPILE_DEFINITIONS and INCLUDE_DIRECTORIES
>   properties where it would be evaluated to get relevant target interface
>   properties.  In other contexts it would be an empty string (or error?).
>   It could be preprocessed out during export and replaced by nothing for
>   non-targets or the relevant $<TARGET_PROPERTY:...> for targets.
> 
> * To optimize the large strings these interfaces generate, perhaps
>   properties can be represented in general as compiled generator
>   expressions that do not directly store their original strings but
>   have references to pieces of them and can reconstruct them.
>   This can be done later though.

Perhaps. We'll have to keep the fact that not all properties can contain 
generator expressions, but that should be possible. All for the future 
though.

Thanks,

Steve.






More information about the cmake-developers mailing list