[cmake-developers] Generator expressisons in target properties

Stephen Kelly steveire at gmail.com
Sun Nov 11 13:32:28 EST 2012


Brad King wrote:
>> However, I can see that if upstream instead did this:
>> 
>>  set_property(TARGET foo APPEND PROPERTY
>>      LINK_INTERFACE_LIBRARIES_DEBUG yip)
>>  target_link_libraries(foo LINK_PUBLIC bang floom)
>> 
>> Then 2.8.10 would result in 'yip;bang;floom', but 2.8.11 would result in
>> 'bang;floom;yip'. I guess that's the case you're interested in.
> 
> Yes, plus possibly others we haven't thought of from trying to do a
> "union" of old and new interfaces.
> 
>> In my topic it uses the result of processing INTERFACE_LINK_LIBRARIES,
>> then whatever is in LINK_INTERFACE_LIBRARIES_DEBUG but not in the result
>> yet.
> 
> This will not be reliably compatible given cases like the above.
> This is why we need to use either one interface or the other, always.

Ok, I see that now.

> If the consumer builds with 2.8.11 but we somehow know to ignore the
> new interface and behave like 2.8.10 then it will all work.
> 
> Perhaps this is where the policy should go.  If the policy is set to
> OLD, use only the old interface.  If the policy is set to NEW then
> use only the new interface.  Otherwise compute the link rules twice,
> once using just the old interface and once using just the new
> interface.  If they are the same, use the result.  If they are not
> the same, then issue the policy warning and use old behavior.

I can do that up to a point.

This means that if the user starts to use non-trivial content in the 
INTERFACE_LINK_LIBRARIES content, then old behavior will be chosen (unless 
the policy is set).

By non-trivial, I mean using generator expressions apart from $<CONFIG>. 
That is, if the user does this:

 add_library(foo ...)
 set_property(TARGET foo 
     PROPERTY INTERFACE_LINK_LIBRARIES
     bar_debug 
     $<$<TARGET_PROPERTY:WIN32_EXECUTABLE>:Qt5::WinMain>
 )
 set_property(TARGET foo 
     PROPERTY LINK_INTERFACE_LIBRARIES_DEBUG
     bar_debug
     # Not possible to add Qt5::WinMain without generator expressions
 )

Then the OLD behavior will be used, and the generator expression will be 
ignored. 

That might be fine, in that the explicit act needed by the person 
implementing the buildsystem for foo to change that is:

 set_minimum_required(VERSION 2.8.11)

Simply removing the use of the old property would not be enough, because 
tll() is likely also used, and that will populate the old properties anyway.

> In the long term projects will eventually set cmake_minimum_required
> to >= 2.8.11 and the policy will always be NEW.  However, how do we
> eventually stop adding the old interfaces to the export files?

It might depend on what the contents of the properties are.

If they are 'exactly what you *need*', and not 'what you likely need, so we 
add it for you to be convenient', then we should only generate the new 
properties if the policy is NEW. I think the former is more appropriate, and 
as INTERFACE_LINK_LIBRARIES is a new property, we can document it as such 
explicitly (and add similar documentation for other INTERFACE_ properties).

Otherwise the old properties would not be able to specify the contents of 
the properties as accurately as the generator expression based ones, and 
therefore the old properties would contain incorrect information.

If the buildsystem maintainer for foo uses generator expressions in the 
INTERFACE_LINK_LIBRARIES (apart from $<CONFIG> - I can handle that while 
comparing to process the policy), that is also a requirement for downstreams 
to use CMake 2.8.11. 

In case non-trivial generator expressions are used, maybe we would need to 
add:

 if (CMAKE_VERSION VERSION_LESS 2.8.11)
    message(FATAL_ERROR "This file requires CMake 2.8.11 or later")
 endif()

when exporting the targets.

Thanks,

Steve.





More information about the cmake-developers mailing list