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

Brad King brad.king at kitware.com
Wed Jan 30 14:11:38 EST 2013


On 01/30/2013 12:09 PM, Stephen Kelly wrote:
>> 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.

Okay, if preprocessing is sufficient to get rid of those then go for it.

>> 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.

Thoughts on this behavior?

Another thought is to have tll() only append includes/defines if the
target is already defined at the call site and otherwise do nothing.
When I previously pointed out the need for handling not-yet-defined
targets I did not realize the cost.

We could even go as far as not adding the generator expression to
INCLUDE_DIRECTORIES if the target dependency does not have an
INTERFACE_INCLUDE_DIRECTORIES already defined too (and similarly for
COMPILE_DEFINITIONS).

Advantages:

* Very little overhead for non-target arguments
* Very little overhead for targets without interfaces
* Works in the motivating case of using targets imported from an upstream

Disadvantages:

* Does not work automatically for circular dependencies.

I think the disadvantage is okay because circular dependencies are a
less common case and one can always make it work by writing out the
generator expression manually.  We should not make everyone pay the
cost for supporting circular interfaces when few are using them.  We
can't even define circular interfaces through tll() anyway except for
static libraries.

>> * 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.

Thanks.

>> * 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.

Perhaps there is no need for it if we use the simpler approach above.

-Brad



More information about the cmake-developers mailing list