Re: [cmake-developers] INTERFACE_LIBRARY target type
Stephen Kelly wrote: 7) I've only implemented the support for this target type in the Makefile generator so far. I can also do the Ninja one after all of the details about how it works are sorted out. Can someone else implement the VS and Xcode support? I'm too unfamiliar with those generators. Do you mean support for make iface in the other generators? Yes. Something similar to what is changed in the makefile generator in the first patch 'Add the INTERFACE library type.' is likely needed in other generators too. I've done this part and merged into next for testing. I split off the 'make iface' stuff into a separate gitorious/INTERFACE_LIBRARY-build-targets topic in my clone. I suspect the generator-specific parts of that will be more-involved. 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
Re: [cmake-developers] INTERFACE_LIBRARY target type
On 08/28/2013 11:31 AM, Stephen Kelly wrote: 1) We already have ALIAS targets, which leaves INTERFACE_LIBRARY to cover the uses cases of Okay. 2) In my branch, the 'old' (IMPORTED_)?LINK_INTERFACE_LIBRARIES(_CONFIG)? are always ignored for INTERFACE_LIBRARY types, for simplicity like the above, and always being able to rely on the INTERFACE_LINK_LIBRARIES property for them. Good. 3) I have left a TODO note in cmLocalGenerator.cxx about the return value from GetRealDependency. Callers of GetRealDependency are looking for a file-level dependency. Targets like OBJECT_LIBRARY and INTERFACE_LIBRARY have no real file on which to depend. The OBJECT_LIBRARY comment This was listed to get the target-level dependency is talking about ordering dependencies among logical targets. 4) The target_* commands always need to be invoked with an explicit INTERFACE option. In other words, with their existing INTERFACE option because PUBLIC and PRIVATE both affect the compilation and linking of the target itself which makes no sense for INTERFACE_LIBRARY. Good. 5) The INTERFACE_LIBRARY can be installed and exported, resulting in add_library(Foo::iface INTERFACE IMPORTED) # ... In my branch, the versions are a bit messed up in the install(EXPORT) code, due to what's currently in master. That will be cleaned later. Okay. 6) When we get transitive INTERFACE_SOURCES, it will be possible to 'link to' OBJECT_LIBRARYs: [snip] So, it might make sense to revisit whether it is allowed to link to OBJECT_LIBRARYs. Either way, the obj_iface can't be exported in this case, because the dependent obj library can't be exported. We don't allow linking to object libraries just for simplicity in their original introduction. We need to define behavior when they are reached transitively. Let's leave this aside for now and come back to it later. 7) I've only implemented the support for this target type in the Makefile generator so far. I can also do the Ninja one after all of the details about how it works are sorted out. Can someone else implement the VS and Xcode support? I'm too unfamiliar with those generators. Do you mean support for make iface in the other generators? 8) I made it possible to use make iface to build the *dependencies* of iface. The special /requires /depends and /build sub-targets are not generated for INTERFACE_LIBRARY targets. Okay. Yes, all those requires/etc. steps are for building files in the target itself. 9) INTERFACE_LIBRARY targets are always effectively EXCLUDE_FROM_ALL because they have no direct outputs. ...but they do have dependencies on other targets, as built by make iface. If a given directory contains nothing but an interface target that depends on real targets from other directories, shouldn't typing make in that directory bring everything up to date to use the interface? -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
Re: [cmake-developers] INTERFACE_LIBRARY target type
Brad King wrote: 3) I have left a TODO note in cmLocalGenerator.cxx about the return value from GetRealDependency. Callers of GetRealDependency are looking for a file-level dependency. Targets like OBJECT_LIBRARY and INTERFACE_LIBRARY have no real file on which to depend. The OBJECT_LIBRARY comment This was listed to get the target-level dependency is talking about ordering dependencies among logical targets. Ok, I've changed the patch to add a similar comment for INTERFACE_LIBRARY types. 7) I've only implemented the support for this target type in the Makefile generator so far. I can also do the Ninja one after all of the details about how it works are sorted out. Can someone else implement the VS and Xcode support? I'm too unfamiliar with those generators. Do you mean support for make iface in the other generators? Yes. Something similar to what is changed in the makefile generator in the first patch 'Add the INTERFACE library type.' is likely needed in other generators too. 9) INTERFACE_LIBRARY targets are always effectively EXCLUDE_FROM_ALL because they have no direct outputs. ...but they do have dependencies on other targets, as built by make iface. If a given directory contains nothing but an interface target that depends on real targets from other directories, shouldn't typing make in that directory bring everything up to date to use the interface? Good point. I'll look into that a bit more. 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
Re: [cmake-developers] INTERFACE_LIBRARY target type
4) The target_* commands always need to be invoked with an explicit INTERFACE option. Maybe PUBLIC should be allowed too (providing the same effect)? I don't really have a rationale. I just wrote PUBLIC a few times by accident. That might be a hint for a more intuitive interface. -- 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
Re: [cmake-developers] INTERFACE_LIBRARY target type
Stephen Kelly wrote: Hi there, I've rebased and pushed the INTERFACE_LIBRARY-target-type branch to my clone again. See also proof of concept here: https://github.com/purpleKarrot/BoostCMake/pull/1 which is the ongoing work to use CMake for boost using ALIAS targets, INTERFACE targets, EXPORT_NAME, usage requirements etc. It allows this to 'just work': cmake_minimum_required(VERSION 2.8.11) # 2.8.13 project(Test) find_package(BoostAny REQUIRED) add_executable(someexe main.cpp) target_link_libraries(someexe boost::any) For boost, a few more interesting INTERFACE features will be needed eventually, but one step at a time... :) 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
[cmake-developers] INTERFACE_LIBRARY target type
Hi there, I've rebased and pushed the INTERFACE_LIBRARY-target-type branch to my clone again. I'd like to get this one in to the next release soon after it opens for features, but there are still a few things to discuss about how it should work. Relevant previous threads: http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/6691 http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/3615/focus=5320 1) We already have ALIAS targets, which leaves INTERFACE_LIBRARY to cover the uses cases of add_library(iface INTERFACE) target_link_libraries(iface INTERFACE bing sing) target_link_libraries(foo INTERFACE bar iface bat) and add_library(iface INTERFACE) target_link_libraries(iface INTERFACE bing sing) target_link_libraries(foo INTERFACE bar $TARGET_PROPERTY:iface,INTERFACE_LINK_LIBRARIES bat ) I think that's fine. 2) In my branch, the 'old' (IMPORTED_)?LINK_INTERFACE_LIBRARIES(_CONFIG)? are always ignored for INTERFACE_LIBRARY types, for simplicity like the above, and always being able to rely on the INTERFACE_LINK_LIBRARIES property for them. 3) I have left a TODO note in cmLocalGenerator.cxx about the return value from GetRealDependency. 4) The target_* commands always need to be invoked with an explicit INTERFACE option. 5) The INTERFACE_LIBRARY can be installed and exported, resulting in add_library(Foo::iface INTERFACE IMPORTED) # ... In my branch, the versions are a bit messed up in the install(EXPORT) code, due to what's currently in master. That will be cleaned later. 6) When we get transitive INTERFACE_SOURCES, it will be possible to 'link to' OBJECT_LIBRARYs: add_library(obj OBJECT foo.cpp) add_library(obj_iface INTERFACE) set_property(TARGET obj_iface PROPERTY INTERFACE_SOURCES $TARGET_OBJECTS:obj ) add_executable(user main.cpp) target_link_libraries(user obj_iface) So, it might make sense to revisit whether it is allowed to link to OBJECT_LIBRARYs. Either way, the obj_iface can't be exported in this case, because the dependent obj library can't be exported. 7) I've only implemented the support for this target type in the Makefile generator so far. I can also do the Ninja one after all of the details about how it works are sorted out. Can someone else implement the VS and Xcode support? I'm too unfamiliar with those generators. 8) I made it possible to use make iface to build the *dependencies* of iface. The special /requires /depends and /build sub-targets are not generated for INTERFACE_LIBRARY targets. 9) INTERFACE_LIBRARY targets are always effectively EXCLUDE_FROM_ALL because they have no direct outputs. Is there anything I'm missing here? 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
Re: [cmake-developers] INTERFACE_LIBRARY target type
Brad King wrote: On 05/02/2013 11:26 AM, Stephen Kelly wrote: Perhaps we could do aliasing with a target property instead? add_library(foo SHARED foo.cpp) set_property(TARGET foo APPEND PROPERTY ALIAS_NAME KF5::foo) No, I like to be able to say that all logical target names are created by an add_* call. Actually your point about scopes of target names means that ALIAS targets should be scoped like IMPORTED targets since their purpose is to self-import. That is an argument for ALIAS targets to be built on IMPORTED targets. I wouldn't say the primary purpose is to self-import, and therefore they should behave as IMPORTED targets. Their primary purpose is to be an alias for another target. This might need some deeper consideration. I like that IMPORTED targets can not be re-exported, and I would expect the same for the INTERFACE_LIBRARY type. How should a project define an interface library and get CMake to put it in a targets file through install(EXPORT) or export()? I don't think I understand the question. It should be the same as for any other target. add_library(iface INTERFACE) export(TARGETS iface) results in add_library(iface INTERFACE IMPORTED) # ... I think that's the conclusion you reach below too. Shouldn't header-only libraries be able to work like that? Yes. IMPORTED targets also have a different scope to non-imported targets. I'd expect that if I find_package somewhere and a KF5::iface INTERFACE_LIBRARY results, that follows the same scope rules as KF5::KArchive. Perhaps IMPORTED and INTERFACE are orthogonal. Yes, that's the way I've been thinking of them. One could import an interface library defined by another project. I'll retract my previous assertion that IMPORTED targets should always refer to files. 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
Re: [cmake-developers] INTERFACE_LIBRARY target type
On Friday 03 May 2013, Stephen Kelly wrote: Brad King wrote: On 05/02/2013 11:26 AM, Stephen Kelly wrote: Perhaps we could do aliasing with a target property instead? add_library(foo SHARED foo.cpp) set_property(TARGET foo APPEND PROPERTY ALIAS_NAME KF5::foo) No, I like to be able to say that all logical target names are created by an add_* call. Actually your point about scopes of target names means that ALIAS targets should be scoped like IMPORTED targets since their purpose is to self-import. That is an argument for ALIAS targets to be built on IMPORTED targets. I wouldn't say the primary purpose is to self-import, and therefore they should behave as IMPORTED targets. Their primary purpose is to be an alias for another target. Ok. So why is this needed in cmake ? Alex -- 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
Re: [cmake-developers] INTERFACE_LIBRARY target type
Brad King wrote: Having said that, would IMPORTED targets actually be good enough for all the things you list, maybe with some wrapper macros ? The IMPORTED targets still need to have an IMPORTED_LOCATION that refers to a real file, so they are not quite equivalent to the proposed INTERFACE or ALIAS targets. What they all share in common is the lack of build-time actions. Actually it might be useful to make it possible to do this: add_library(foo SHARED foo.cpp) add_library(bar SHARED bar.cpp) add_library(iface INTERFACE) target_link_libraries(iface INTERFACE foo bar) and have make iface cause a (re)build of foo and bar if necessary. This would be in conflict with the idea of considering targets with double colons to be imported targets if the INTERFACE_LIBRARY was used in the alias pattern I described before. Perhaps we could do aliasing with a target property instead? add_library(foo SHARED foo.cpp) set_property(TARGET foo APPEND PROPERTY ALIAS_NAME KF5::foo) ? Just another angle to consider in the design of this stuff. The proposed INTERFACE and ALIAS target types would remain the same when exported instead of being converted to IMPORTED targets. However, all their interface content would be mapped to the exported names. I think new target types are worth considering for these roles to keep the IMPORTED concept focused on importing targets with files on disk. This might need some deeper consideration. I like that IMPORTED targets can not be re-exported, and I would expect the same for the INTERFACE_LIBRARY type. IMPORTED targets also have a different scope to non-imported targets. I'd expect that if I find_package somewhere and a KF5::iface INTERFACE_LIBRARY results, that follows the same scope rules as KF5::KArchive. The code would become uglier too. We'd need to add special cases for INTERFACE_LIBRARY types in places where we currently check IsImported, eg cmTarget::AddLinkLibrary. Also, commands like target_include_directories() shouldn't work with IMPORTED targets as the first argument, but if such targets are not marked as IMPORTED, there would be no way to enforce that. Some configuration- relevant information is only known to the exporting project upstream. See commit b98d14d40016efee420bee26b9795880fdf6a5f8 (Disallow porcelain to populate includes and defines of IMPORTED targets., 2013-01-21). 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
Re: [cmake-developers] INTERFACE_LIBRARY target type
On 05/02/2013 11:26 AM, Stephen Kelly wrote: Perhaps we could do aliasing with a target property instead? add_library(foo SHARED foo.cpp) set_property(TARGET foo APPEND PROPERTY ALIAS_NAME KF5::foo) No, I like to be able to say that all logical target names are created by an add_* call. Actually your point about scopes of target names means that ALIAS targets should be scoped like IMPORTED targets since their purpose is to self-import. That is an argument for ALIAS targets to be built on IMPORTED targets. This might need some deeper consideration. I like that IMPORTED targets can not be re-exported, and I would expect the same for the INTERFACE_LIBRARY type. How should a project define an interface library and get CMake to put it in a targets file through install(EXPORT) or export()? Shouldn't header-only libraries be able to work like that? IMPORTED targets also have a different scope to non-imported targets. I'd expect that if I find_package somewhere and a KF5::iface INTERFACE_LIBRARY results, that follows the same scope rules as KF5::KArchive. Perhaps IMPORTED and INTERFACE are orthogonal. One could import an interface library defined by another project. I'll retract my previous assertion that IMPORTED targets should always refer to files. -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
Re: [cmake-developers] INTERFACE_LIBRARY target type
On Thursday 02 May 2013, Stephen Kelly wrote: Brad King wrote: Having said that, would IMPORTED targets actually be good enough for all the things you list, maybe with some wrapper macros ? The IMPORTED targets still need to have an IMPORTED_LOCATION that refers to a real file, so they are not quite equivalent to the proposed INTERFACE or ALIAS targets. What they all share in common is the lack of build-time actions. Actually it might be useful to make it possible to do this: add_library(foo SHARED foo.cpp) add_library(bar SHARED bar.cpp) add_library(iface INTERFACE) target_link_libraries(iface INTERFACE foo bar) and have make iface cause a (re)build of foo and bar if necessary. This would be in conflict with the idea of considering targets with double colons to be imported targets if the INTERFACE_LIBRARY was used in the alias pattern I described before. Perhaps we could do aliasing with a target property instead? add_library(foo SHARED foo.cpp) set_property(TARGET foo APPEND PROPERTY ALIAS_NAME KF5::foo) Why would I want an alias ? Doesn't that make things only more complicated ? If I have to be flexible on the name, I can do that right now already if(something) set(theTargetName KF5::foo) else() set(theTargetName foo) endif() tll(blub ${theTargetName}) Alex -- 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
[cmake-developers] INTERFACE_LIBRARY target type
Hi, Last year, the new INTERFACE_LIBRARY target type was to be part of the 'target usage requirements' feature, but it was deferred until after 2.8.11. It was discussed a bit though, in my point 3 in this thread and some follow up messages: http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/3615/focus=5247 The idea of the INTERFACE_LIBRARY is that it creates no output itself, but it can have content in its INTERFACE_* properties. That makes it suitable for defining header-only libraries for example like in boost. My implementation of it is in the INTERFACE_LIBRARY-target-type branch in my clone. Other potential uses for it would be for an umbrella-target. In KDE frameworks the libkdecore.so library will no longer be present, but it will have been split into several smaller libraries. The kdecore target is install(EXPORT)ed as KDE4__kdecore. That target name is rarely used because the KDE4_KDECORE_LIBS variable is used instead. So, we will be able to populate that variable or a similar one with the smaller libraries for compatibility. In the future as imported targets are used more, it might make sense to introduce compatibility libraries like that, and the INTERFACE_LIBRARY would be a candidate for implementing that. However, in that case, the order of libraries resulting from tll(foo directdep1 iface directdep2) might have an effect. Maybe we could also introduce an ALIAS_LIBRARY or so which would be expanded in-place? Another potential use-case for INTERFACE_LIBRARY/alias is a non-deprecated way of aliasing a target. Currently that can be done like this by relying on export() being executed at configure-time: export(TARGETS foo NAMESPACE BuiltIn:: FILE fooTarget.cmake) include(fooTarget.cmake) # Use BuiltIn::foo The new/alternative use would look something like: add_library(BuiltIn::foo INTERFACE) target_link_libraries(BuiltIn::foo INTERFACE_LINK_LIBRARIES foo) # Use BuiltIn::foo Another use-case (which again is mostly about aliasing) is being able to build example code as part of the same build-system or using an external package. For example, the QtWidgets examples can be built as part of the Qt build, or not by specifying -nomake examples. Any example can also be built using an installed Qt. For a cmake project, a buildsystem for an example application could look like this: if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) find_package(KArchive NO_MODULE REQUIRED) endif() add_executable(bzip_example main.cpp) target_link_libraries(bzip_example KF5::KArchive) The problem is that in the case of the example being in the same build- system as the KArchive target itself, KF5::KArchive has no meaning. The two solutions to that are 1. The Aliasing above 2. Create a KArchive_LIBRARIES variable and use that in the example The KArchive_LIBRARIES would be defined as KArchive in the KArchive buildsystem and KF5::KArchive in the KArchiveConfig.cmake. I generally would prefer to not require variables like that (I would like to move towards the direct result of install(EXPORT) being a usable and conventional Config file), and I think the kind of aliasing allowed by the INTERFACE_LIBRARY makes that possible. add_library(KArchive ...) add_library(KF5::KArchive INTERFACE) target_link_libraries(KF5::KArchive INTERFACE_LINK_LIBRARIES KArchive) So, the question is, should we design the INTERFACE_LIBRARY type to be suitable for all of these use-cases? Header-only libraries, aliasing of single targets, and encapsulating multiple targets (while resulting in a somewhat funny, or expected depending how you think of it, link order)? 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