Brad King wrote: > On 05/06/2013 12:44 PM, Stephen Kelly wrote: >> I'm not sure what you mean by 'for now'? > > I meant we could drop it and move on but not rule out the possibility > of someday moving to it for consistency and (eventual) simplicity. > >> I'd prefer not to introduce INTERFACE_LIBRARY with support for the >> old-style interface if there will eventually be a new-style. > > Perhaps we can look at reviving it but we'll have to re-work the > policy to handle generator expressions in the old interface as > you pointed out. Can you please take a stab at proposing the > new form of the policy (in design only, no code yet).
For reference, here's some old threads: * http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/5398 (Policy for INTERFACE_LINK_LIBRARIES) * http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/5526 (Setting include directories via target_link_libraries() ?) * http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/5680 (New INTERFACE_LINK_LIBRARIES policy approach) * http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/5734 (Interface includes and defines plumbing) * http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/5904 (Setting includes, defines and other usage requirements with one command) In summary, we spent some time discussing INTERFACE_LINK_LIBRARIES while at the same time discussing the tll-vs-new-command question and various options for how to implement the plumbing. Eventually, without fanfare and apparently without discussion on the mailing list, I abandonned that INTERFACE_LINK_LIBRARIES property in early January and added genex support to the properties matching (IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)? instead. The topic was merged in c0c8ef85fc8d65a47abfd293031bcde91e7ee930. This meant that the complexity of issues associated with introducing the new property were worked-around - namely which properties to install(EXPORT). The initial justification for replacing the old properties with the new one was so that targets would have property content like this using a uniform property name: LINK_LIBRARIES $<TARGET_PROPERTY:foo,INTERFACE_LINK_LIBRARIES> That became irrelevant long ago as it was based on my misunderstanding about how link lines are determined. Other justifications for the new property remain: * Name consistency with INTERFACE_INCLUDE_DIRECTORIES and INTERFACE_COMPILE_DEFINITIONS * Not having a <CONFIG> suffix, which is no longer needed because of genex support * Consistency of access to the link interface. For static imported targets, the old IMPORTED_LINK_INTERFACE_LIBRARIES property contains the link interface, but for non-imported static libraries the old LINK_INTERFACE_LIBRARIES does not. * We may in the future find a need and justification for a genex like $<IS_LINKED:foo> which determines whether foo is linked. The i implementation of that genex would be a lot simpler if it needed to support only one property. This may be unlikely however. Currently properties like COMPATIBLE_INTERFACE_* solve similar problems that a $<IS_LINKED> would solve. * We can have empty INTERFACE_LINK_LIBRARIES on shared libraries by default. * ?? 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. * When a target is install(EXPORT)ed, the new property will be exported. ** 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). ** 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. * 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. There needs to be a final-migration-moment where projects no longer export targets with the old properties. * If the INTERFACE_LINK_LIBRARIES property is read on a static non-imported library, its LINK_LIBRARIES property is returned. * When exporting, if 'the implementation is the interface' So, the primary thing to determine is whether to export the old properties, which is related to whether they get populated by tll(). 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. 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. Existing code could look like this: A) add_library(foo SHARED|STATIC ...) tll(foo bar) # install(TARGETS) and proper export name omitted install(EXPORT foo bar ...) In this case, if the policy is NEW, we report an error on the tll line. If the policy is OLD, we populate both the new and the old link interface properties. B) # Else as (A) ... tll(foo LINK_PUBLIC bar) In this case, if the policy is NEW, we populate only the new property. If the policy is OLD, we populate both the new and the old link interface properties. 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. An error is reported (see below) if the target has populated old properties as a result of a set_property() for example so we don't have to worry about overwriting user-defined content. tll can't result in old property population for foo as the policy is determined early. 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. C) # 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. This can't reliably be encoded into the new INTERFACE_LINK_LIBRARIES property on export. The exporting project needs to be ported to use generator expressions instead. This results in the CMake requirement of their downstreams to necessarily be bumped to CMake 2.8.11. 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
