Brad King wrote: > 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.
Any thoughts on adding PUBLIC PRIVATE and INTERFACE keywords to tll for consistency with the other target_* commands? http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/6864/focus=6886 >> When the policy is not set (internally it is WARN) then tll() >> will populate both the old and new properties. ComputeLinkInterface >> will compute both the old and new style link interfaces, warn if >> they are different, and use the old one. Ok. > ... >> 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. Yes. > 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. Right. > 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. Right. >> * 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. Ok. >> ** 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. I'm still not a fan of partial evaluation like that. It would be complex and a source of bugs for little gain. >> ** 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. I'd prefer not to try to magically generate things like that. It would be complex and a source of bugs. > This will give projects a choice on whether they want to populate the > old properties explicitly or ask CMake to do it for them. Rather than offer so much choice for something which is pure backwards- compatibility (and therefore obsolete from the start), I'd prefer to offer only one way - user specified old properties. >> * 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. You mean CMake magically determining the old properties from the new one? > >> 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. Ok. >> 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. Agreed. > 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) This seems very similar to the proposal I made ('I'd propose deprecating with a policy the signature...') that you vetoed. Is it just a refinement of what I proposed? > 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. Yes, I think this is also what I proposed. Although I still propose deprecating LINK_PUBLIC/LINK_PRIVATE for PUBLIC/PRIVATE for consistency with the new commands. >> 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. Yes. >> 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"? Yes, that seems fine. >> # 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. Yes. Thanks, Steve. -- 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
