On 05/10/2013 06:41 AM, Stephen Kelly wrote:
> * http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/5680
>   (New INTERFACE_LINK_LIBRARIES policy approach)

I remember being quite happy with the proposal I made at the start of
that thread.  Let's see if we can come up with something equivalent.
For reference, the key sections of my message were:

On 12/22/2012 10:22 AM, Brad King wrote:
> First I'll define how the properties behave when building a target.
> I'll cover exporting below.
>
> In the OLD behavior the link interface is completely determined as
> it is in CMake 2.8.10 by the LINK_INTERFACE_LIBRARIES(_<CONFIG>)
> properties.  The target_link_libraries command will populate the
> properties as it does now and leave the new names untouched.
>
> In the NEW behavior the link interface is completely determined
> by the new INTERFACE_LINK_LIBRARIES property.  All forms of tll()
> including its LINK_INTERFACE_LIBRARIES mode will populate only
> the new properties.  The old property is completely ignored.
>
> When the property is not set (internally it is WARN) then tll()
> will populate both the old and new properties.  ComputeLinkInfo
> will compute both the old and new style link interfaces, warn if
> they are different, and use the old one.
...
> Now, on to exporting.  Unlike the previous iteration the policy
> affects it too.
>
> When the policy is OLD/WARN we export only the old interface and
> not the new interface.
>
> When the policy is NEW we export only the new interface and not
> the old interface by default.  We can have a new property to
> explicitly request that the old link interface properties be
> exported.  We can either ask projects to set the old interface
> properties manually for export or try to compute the values from
> the new ones by pre-evaluating the generator expressions for
> each configuration.  This will allow projects to support older
> CMake versions for their clients if they want to, but it will
> be an explicit decision.

Now, returning to your message:

On 05/10/2013 06:41 AM, Stephen Kelly wrote:
> If the new property is introduced, the behavior would be:
> 
> * If an in-buildsystem or IMPORTED target has the new property, it is used 
>   and the old properties are not used.

For in-build targets this needs to depend on the policy setting as in my
quote above.  The behavior of the project's build should not depend on
the version of CMake currently running, but rather the behavior intended
by the project author.  The intention is implied by the policy setting
or lack of one.

For IMPORTED targets I think your proposal is correct: use the new
property if it is set and otherwise use the old property.  It is up to
the provider of the imported targets to specify the old and/or new
properties correctly to handle various CMake versions for consumers.

> * When a target is install(EXPORT)ed, the new property will be exported. 

...when the policy is NEW.  When it is OLD/WARN we export only the old
properties.

> ** There needs to be a way to determine whether to additionally export the 
>    old properties. Even if the exporting target does not have the old 
>    properties set, we can still conditionally write the content of the new 
>    INTERFACE_LINK_LIBRARIES to IMPORTED_LINK_INTERFACE_LIBRARIES, as both 
>    now support generator expressions. This will allow exporting projects to 
>    maintain compatibility with downstreams using CMake 2.8.11 (or earlier if 
>    generator expressions are not used).

Yes, and the install(EXPORT) option you proposed can work for that.
If possible I'd like to try to (partially) evaluate the $<CONFIG>-type
expressions to set the old per-config properties.  That will make it easy
for packages to support the old properties for CMake < 2.8.11.

> ** If the old properties and the new property are set, we export them 
>    all. This will allow exporting projects to maintain compatibility with 
>    downstreams using CMake < 2.8.11. It is ok if the new 
>    INTERFACE_LINK_LIBRARIES and the old LINK_INTERFACE_LIBRARIES have 
>    differing content and no warning is issued. The new property may simply 
>    contain new genex-powered-convenience, similar to how QtCore now 
>    conveniently links to the qtmain.lib now on Windows.

Perhaps whatever install(EXPORT) option exports the old properties can
also somehow indicate whether to use the project's settings for the old
properties or try to generate values automatically from the new ones.
This will give projects a choice on whether they want to populate the
old properties explicitly or ask CMake to do it for them.

> * target_link_libraries signatures will populate the new 
>   INTERFACE_LINK_LIBRARIES property. There will need to be a way to make it 
>   additionally conditionally populate the old properties.

See my proposed approach quoted above for this.

> So, the primary thing to determine is whether to export the old properties, 
> which is related to whether they get populated by tll().

I don't think they are related.  The policy I proposed will determine
which properties define the link interface and how the link interface
is represented on export.  When the policy is OLD/WARN nothing changes.
When the policy is NEW we use/export only the new properties unless a
keyword explicitly says to populate the old.

> I'd propose deprecating with a policy the signature
> 
>  target_link_libraries(foo bar)
> 
> and require that a public/private/interface keyword is present for all usage 
> of it.

As convenient as that would be for us I do not think we can ever do that.
This signature is one of the fundamental interfaces CMake has provided
since near the beginning.  It is in use in thousands of projects, tutorials,
documents, etc. throughout the CMake user community.  We cannot ask all
users to change such calls just to simplify our transition of what is
mostly an internal implementation detail.

We'll have to define a behavior for the old signature that makes sense
in the new design.  The current behavior is to populate the link
implementation which becomes the link interface if no explicit link
interface is set.  I think this needs to remain the case because the
established behavior is so fundamental, but see below.

> * When exporting, if 'the implementation is the interface'
>
> With the policy, the required tll signature, and new property, the
> implementation is never the interface for shared libraries.

Since I'm vetoing "the required tll signature" we need another way
to achieve this.  One of the confusing things about use of the old
tll() signature is that it seems to populate the public link interface
until one uses one of the newer signatures and suddenly all the other
"public" entries disappear.  I think we can solve both problems with
a second new policy (distinct from the other policy discussed outside
this paragraph) that simply disallows use of the old signatures
(plain tll and LINK_INTERFACE_LIBRARIES mode) and the new signature
(LINK_PUBLIC/LINK_PRIVATE) for a single LHS.  If a project uses *only*
the new signature then we never need to use "the implementation is the
interface" for shared libraries.  If a project uses *only* the old
signatures then the existing behavior continues to work.

> The policy would also determine whether the new or old link interface 
> property is populated by the command. The value of the policy is determined 
> when the foo target is created.

Yes, that is consistent with my above-quoted proposal.  The tll signatures
that explicitly populate the link interface will simply choose which
properties to populate based on the policy.

> When the policy is switched to NEW, exporting projects can simultaneously 
> use a new keyword to install(EXPORT) to make it duplicate the 
> INTERFACE_LINK_LIBRARIES as old property names. 

Yes, as discussed above.

> So, the API difference would be
> 
>  install(EXPORT fooTargets ...) # Export only new properties
> 
> vs 
> 
>  install(EXPORT fooTargets GEN_OLD ...) # Export new and old properties
> 
> I don't mind what the keyword is.

Yes, and the keyword is an error when the policy is not NEW.
Perhaps "EXPORT_LINK_INTERFACE_LIBRARIES"?

>  # Else as (A) ...
>  set_property(TARGET foo PROPERTY LINK_INTERFACE_LIBRARIES_COVERAGE bat)
>  install(EXPORT foo bar bat ...) 
>  
> In this case, if the policy is NEW, the export line reports an error because 
> a LINK_INTERFACE_LIBRARIES_<foo> property is set.

Yes, something like this.

In my proposal when the policy is NEW the old properties are ignored
and the link interface is fully determined by the new property.
Therefore when processing an export that does not request that the
old properties be populated by the project's own values we should
generate an error if it sets them.

-Brad
--

Powered by www.kitware.com

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-developers

Reply via email to