[cmake-developers] Object library linking (and a bit about INTERFACE_SOURCES)

Stephen Kelly steveire at gmail.com
Tue Feb 24 17:25:20 EST 2015


Brad King wrote:

> On 02/23/2015 07:50 PM, Ben Boeckel wrote:
>> We could also lift the restriction then. I'm fine with just dropping the
>> patch. Basically without it, all it blocks is
>> add_custom_{command,target} from using $<TARGET_OBJECTS>…which could be
>> useful for some obscure linker target CMake doesn't understand. So maybe
>> just lifting all such restrictions on $<TARGET_OBJECTS> is the thing to
>> do.
> 
> Some restrictions are there because we cannot safely evaluate the
> $<TARGET_OBJECTS> in general for all generators.  See the code
> using EvaluateForBuildsystem.

TARGET_OBJECTS already may not be used by add_custom_{command,target}, 
because cmake does not portably know the path to the object files.

 http://public.kitware.com/Bug/view.php?id=15226

If you want to lift that restriction for Makefile|Ninja generators and non-
portable buildsystems, we can discuss that in a different thread. I think 
it's probably a good idea.

Ben Boeckel wrote:
>> Can you imagine a reason for both 'b' and 'exe' need sym1.c? Or do you
>> imagine it to be something that should be only compiled into the shared
>> library or only the executable? In other words - Is the buildsystem
>> description above buggy?
> 
> Sure, I *can*, but it's also not how I've used object libraries so far
> (basically as static libraries I don't need to export).

They're probably different enough to that that that mental model of them is 
unhelpful.


>>> I had imagined other cases which were easy to reason about (and probably
>>> more common to need) such as:
>>>
>>>  target_sources(a INTERFACE
>>>    $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>sym1.c>
>>>  )
>>>
>>> So that it would just 'pass through' any intermediate libraries.
>> 
>> That works for that case, but doesn't work when it needs to land in a
>> specific shared or static library (though I suppose STREQUAL +
>> TARGET_NAME could work there too, but that doesn't feel clean to me and
>> also feels like the tail wagging the dog).

If you want to affect a particular downstream target, as opposed to a 
category of downstreams, transitive usage requirements and putting something 
like that in an INTERFACE are probably not the right tools.

>> Would it make sense to uniq all sources? Or only uniq the ones which come
>> from the link interface?

This uniq is actually already done.

>> I would prefer to see 'linking to' an object library consume its sources
>> directly without needing to specify the target in both the sources and
>> the target_link_libraries.
> 
> I would as well, but with transitive linking, getting duplicate
> symbols/static variables is way too easy at the moment (and debugging
> the latter is not always easy if you don't know what you're looking
> for). 

It is just as easy to get into this situation when linking static libraries, 
right? Object libraries are not part of the problem, right? Or could you 
post a sscce?

> For the diamond-usage problem, is there some way of utilizing the
> COMPATIBLE_INTERFACES to deny the mixing of two libraries where each
> built with an object libraries' objects? Having a property to trigger
> that would be nice...

Yes, that's possible by adding an ExclusiveList compatible type and 
populating an appropriate property when linking to OBJECT libraries. I've 
written a prototype and can clean it up and post it if that's part of the 
solution.

> Until that problem is solved we cannot make object libraries
> implicitly offer their objects just through tll().

Honestly, the problem is still not clear to me. Is it something you would 
want to write and expect to be correct, but which would actually be 
incorrect? Is the static global object instance a necessary part of the 
problem-scenario?

Thanks,

Steve.




More information about the cmake-developers mailing list