[cmake-developers] Generator expressisons in target properties
Stephen Kelly
steveire at gmail.com
Tue Nov 6 14:07:16 EST 2012
Brad King wrote:
> On 11/06/2012 12:00 PM, Stephen Kelly wrote:
>> The include directories and compile definitions are set by the
>> target_link_libraries command.
>
> ...by adding generator expressions, right? They won't be evaluated
> until much later.
Yes.
>
>> It might make sense to add a policy for that
>> feature, as otherwise the order of include directories would change, eg:
>>
>> add_executable(foo ...)
>> target_link_libraries(foo bar bat)
>> include_directories(${bat_INCLUDE_DIRS} ${bar_INCLUDE_DIRS})
>
> How do you propose to trigger this policy warning? At no one point
> while processing the above commands do we know whether the order
> changes.
True, I don't know how to warn about it. Does that mean that a policy is
entirely unsuitable? Or does it mean we can't build this functionality into
tll() after all?
>
>> I propose that
>>
>> target_link_libraries(foo LINK_INTERFACE_LIBRARIES bar)
>>
>> should be allowed for an imported foo, but
>>
>> target_link_libraries(foo bar)
>>
>> remains not-allowed.
>
> Okay. The only purpose of it is to set properties while processing the
> debug/optimized keywords anyway.
In my branch it also sets the INTERFACE_INCLUDE_DIRECTORIES and
INTERFACE_COMPILE_DEFINITIONS.
>
>> As I introduced the INTERFACE_LINK_LIBRARIES property, I also introduced
>> a backward-compatibility feature to also read the old IMPORTED*_<CONFIG>
>> properties. I don't know enough about cmComputeLinkDepends to know if
>> that's ok.
>
> I don't think we should honor both properties at once. If the new
> name is set the old names should be ignored (perhaps with a warning if
> an old name is set too).
That could be an option. I think it gets complicated though.
1. In my branch I made tll() populate the INTERFACE_LINK_LIBRARIES prop
2. Exports generate INTERFACE_LINK_LIBRARIES on imported targets if set
3. The maintainer of the library may have also set
INTERFACE_LINK_LIBRARIES_DEBUG
4. A consumer of the library might build it with CMake 2.8.11, and when
using the imported target, the INTERFACE_LINK_LIBRARIES (autopopulated by
tll()) will be used and the INTERFACE_LINK_LIBRARIES_DEBUG will be ignored.
The maintainer might not be aware of CMake 2.8.11 yet, and so it would
appear to be a backward incompatible change.
>
> A common use of LINK_INTERFACE_LIBRARIES is to be empty so this
> does not look correct:
>
> - if(!explicitLibraries &&
> + if(explicitLibraries.empty() &&
Ok, I'll think more about it.
>> I asked before for more information about why direct depends are
>> separated from transitive ones. The reason seems to be related to
>> ordering of the
>
> Yes. If you read and understand cmComputeLinkDepends in detail you will
> see there is no way to implement the current logic without keeping these
> separate.
>
>> depends when invoking the linker, which is relevant for static libraries
>> (but not shared libraries, right?).
>
> It's platform dependent IIRC. On some platforms order doesn't even matter
> among static libraries. On others order matters among both.
Yes, I read the comment and implementation in cmComputeLinkDepends, but I
didn't fully understand the motivation. This is good enough for me though.
>> add_library(iface INTERFACE)
>> set_property(TARGET iface PROPERTY INTERFACE_LINK_LIBRARIES foo bar)
>> target_link_libraries(test_exe directdep1 iface directdep2)
>>
>> It is not really equivalent to this:
>>
>> target_link_libraries(test_exe directdep1 foo bar directdep2)
>>
>> But maybe it should be, or maybe I would want it to be? Maybe we can make
>> it possible to populate the non-INTERFACE LINK_LIBRARIES property on
>> libraries of type INTERFACE_LIBRARY to use the contents as direct depends
>> of test_exe?
>
> Yes, interfaces should be flattened and replaced with their content.
So the INTERFACE_LINK_LIBRARIES property would be handled differently for an
INTERFACE_LIBRARY than a SHARED_LIBRARY. I think that's a bit confusing.
In that case INTERFACE_LIBRARY might not be the best name for it. Maybe
SUBSTITUTE would be better.
>> I'm thinking of simply removing the memoization from cmTarget.
>
> Sure, they are only an optimization. Get things correct first and
> optimize later.
What I'm proposing is removal of an existing optimization, but ok I'll go
ahead and do that.
>> add_library(boost::core INTERFACE IMPORTED)
>
> Side question: Does the "IMPORTED" status of an INTERFACE have any
> real meaning? It won't build anything in the project either way.
I thought about this too, but I haven't thought it through fully yet. I do
want INTERFACE_LIBRARYs to be install(EXPORT)able (for the boost use-case),
and that is not possible for IMPORTED libraries.
I haven't yet thought through whether it makes sense to allow or disallow
install(EXPORT)ing an INTERFACE_LIBRARY imported from elsewhere. If it has
other IMPORTED targets in its interface, then it probably doesn't make sense
to allow it.
Thanks,
Steve.
More information about the cmake-developers
mailing list