Re: [CMake] Proposal: extra option PRIVATE for target_link_libraries
On 23. Dec, 2009, at 16:04 , Marcel Loose wrote: > On Wed, 2009-12-23 at 15:19 +0100, Michael Wild wrote: >> On 23. Dec, 2009, at 15:14 , Marcel Loose wrote: >> >>> On Wed, 2009-12-23 at 14:12 +0100, Michael Wild wrote: On 23. Dec, 2009, at 13:28 , Marcel Loose wrote: > On Wed, 2009-12-23 at 13:09 +0100, Michael Wild wrote: >> On 23. Dec, 2009, at 12:08 , Marcel Loose wrote: >> >>> Hi all, >>> >>> I suggested this in the quite long thread "third party library >>> dependencies", but it may have been overlooked. Hence, I started a new >>> thread. >>> >>> Upon (re)reading the Mandriva page >>> http://wiki.mandriva.com/en/Overlinking, I was thinking: maybe the issue >>> of overlinking can be solved more or less the same way as pkg-config >>> does: i.e. by defining private dependencies. This could be an extra >>> option to target_link_libraries. >>> Something like: >>> >>> target_link_libraries(mylib public1 public2 PRIVATE private1 private2) >>> >>> This would tell CMake that mylib directly depends on public1 and public2 >>> and should only link in these two libraries when these are shared >>> object libraries; otherwise private1 and private2 would also need to be >>> added on the link line. >>> >>> The big hurdle to take, of course, is to detect in a >>> platform-independent way whether the given library is shared or static. >>> However, a lot of this knowledge is already available in the diverse >>> Modules/Platform macros, so my feeling is that this should be feasible. >>> >>> Best regards, >>> Marcel Loose. >>> >> >> You would also need a PUBLIC keyword, and then require that all >> FindXXX.cmake modules prefix their libraries with PUBLIC and PRIVATE. If >> only the PRIVATE libraries where prefixed, the following would not work >> if A_LIBRARIES contains PRIVATE: >> >> find_package(A) >> find_package(B) >> add_library(C source.c) >> target_link_libraries(C ${A_LIBRARIES} ${B_LIBRARIES}) >> >> Because then all the B_LIBRARIES would be considered to be private >> "details" of the public A_LIBRARIES... Also, there's no way to tell >> CMake which of the private libraries belongs to which of the public >> libraries. >> >> I think it would be better if a FindXXX.cmake module marked the private >> libraries as a property of the public libraries and then let CMake take >> it from there (although as of now I wouldn't know on what to set the >> property, except if the module created an IMPORTED target for each of >> the public libraries, but that bears the possibility of target name >> collisions with the importing project). >> >> Michael > > Hi Michael, > > I don't think you'll need to prefix the library names with either > PRIVATE_ or PUBLIC_. CMake could figure out whether "public1" and > "public2" are shared or static libraries. If they are shared libraries, > then the libraries marked as private ("private1" and "private2") do not > have to be linked in as well. Otherwise they must also be linked in. I > assume that CMake keeps a list internally, of all dependent targets; the > private libs should only be added to that internal list if the public > libs are static libs. > > I don't completely understand your example. Are you suggesting that > you'll run into trouble if you have a library named "PRIVATE"? I think > name clashes will currently occur as well if I name my library "debug", > "optimized", or "general". > > Maybe, it would be better if the FindXXX modules would handle this. On > the other hand, you then depend on third parties to properly update > their FindXXX modules, or have to rewrite them yourselves :-( > > Best regards, > Marcel Loose. > No, it won't work. For example, if FindA.cmake does set(A_LIBRARIES /some/path/libA.so PRIVATE /some/other/path/libX.a /some/other/path/libY.a) and FindB.cmake contains # notice that this is a static library! set(B_LIBRARIES /some/path/libB.a) then the call target_link_libraries(C ${A_LIBRARIES} ${B_LIBRARIES}) expands to (wrapped for legibility target_link_libraries(C /some/path/libA.so PRIVATE /some/other/path/libX.a /some/other/path/libY.a /some/path/libB.a) which is different in meaning from target_link_libraries(C ${B_LIBRARIES} ${A_LIBRARIES}) which becomes target_link_libraries(C /some/path/libB.a /some/path/libA.so PRIVATE /some/other/path/libX.a /some/other/path/libY.a) In the first case libB.a becomes marked as PRIVATE of libA.so! Not very nice if
Re: [CMake] Proposal: extra option PRIVATE for target_link_libraries
On Wed, 2009-12-23 at 15:19 +0100, Michael Wild wrote: > On 23. Dec, 2009, at 15:14 , Marcel Loose wrote: > > > On Wed, 2009-12-23 at 14:12 +0100, Michael Wild wrote: > >> On 23. Dec, 2009, at 13:28 , Marcel Loose wrote: > >> > >>> On Wed, 2009-12-23 at 13:09 +0100, Michael Wild wrote: > On 23. Dec, 2009, at 12:08 , Marcel Loose wrote: > > > Hi all, > > > > I suggested this in the quite long thread "third party library > > dependencies", but it may have been overlooked. Hence, I started a new > > thread. > > > > Upon (re)reading the Mandriva page > > http://wiki.mandriva.com/en/Overlinking, I was thinking: maybe the issue > > of overlinking can be solved more or less the same way as pkg-config > > does: i.e. by defining private dependencies. This could be an extra > > option to target_link_libraries. > > Something like: > > > > target_link_libraries(mylib public1 public2 PRIVATE private1 private2) > > > > This would tell CMake that mylib directly depends on public1 and public2 > > and should only link in these two libraries when these are shared > > object libraries; otherwise private1 and private2 would also need to be > > added on the link line. > > > > The big hurdle to take, of course, is to detect in a > > platform-independent way whether the given library is shared or static. > > However, a lot of this knowledge is already available in the diverse > > Modules/Platform macros, so my feeling is that this should be feasible. > > > > Best regards, > > Marcel Loose. > > > > You would also need a PUBLIC keyword, and then require that all > FindXXX.cmake modules prefix their libraries with PUBLIC and PRIVATE. If > only the PRIVATE libraries where prefixed, the following would not work > if A_LIBRARIES contains PRIVATE: > > find_package(A) > find_package(B) > add_library(C source.c) > target_link_libraries(C ${A_LIBRARIES} ${B_LIBRARIES}) > > Because then all the B_LIBRARIES would be considered to be private > "details" of the public A_LIBRARIES... Also, there's no way to tell > CMake which of the private libraries belongs to which of the public > libraries. > > I think it would be better if a FindXXX.cmake module marked the private > libraries as a property of the public libraries and then let CMake take > it from there (although as of now I wouldn't know on what to set the > property, except if the module created an IMPORTED target for each of > the public libraries, but that bears the possibility of target name > collisions with the importing project). > > Michael > >>> > >>> Hi Michael, > >>> > >>> I don't think you'll need to prefix the library names with either > >>> PRIVATE_ or PUBLIC_. CMake could figure out whether "public1" and > >>> "public2" are shared or static libraries. If they are shared libraries, > >>> then the libraries marked as private ("private1" and "private2") do not > >>> have to be linked in as well. Otherwise they must also be linked in. I > >>> assume that CMake keeps a list internally, of all dependent targets; the > >>> private libs should only be added to that internal list if the public > >>> libs are static libs. > >>> > >>> I don't completely understand your example. Are you suggesting that > >>> you'll run into trouble if you have a library named "PRIVATE"? I think > >>> name clashes will currently occur as well if I name my library "debug", > >>> "optimized", or "general". > >>> > >>> Maybe, it would be better if the FindXXX modules would handle this. On > >>> the other hand, you then depend on third parties to properly update > >>> their FindXXX modules, or have to rewrite them yourselves :-( > >>> > >>> Best regards, > >>> Marcel Loose. > >>> > >> > >> > >> No, it won't work. For example, if FindA.cmake does > >> > >> set(A_LIBRARIES /some/path/libA.so > >> PRIVATE /some/other/path/libX.a /some/other/path/libY.a) > >> > >> and FindB.cmake contains > >> > >> # notice that this is a static library! > >> set(B_LIBRARIES /some/path/libB.a) > >> > >> > >> then the call > >> > >> target_link_libraries(C ${A_LIBRARIES} ${B_LIBRARIES}) > >> > >> expands to (wrapped for legibility > >> > >> target_link_libraries(C > >> /some/path/libA.so > >> PRIVATE /some/other/path/libX.a > >> /some/other/path/libY.a > >> /some/path/libB.a) > >> > >> which is different in meaning from > >> > >> target_link_libraries(C ${B_LIBRARIES} ${A_LIBRARIES}) > >> > >> which becomes > >> > >> target_link_libraries(C > >> /some/path/libB.a > >> /some/path/libA.so > >> PRIVATE > >> /some/other/path/libX.a > >> /some/other/path/libY.a) > >> > >> In the first case libB.a becomes marked as PRIVATE of libA.so! Not very > >> nice if you ask me ;-) > >> > >> Michael > >
Re: [CMake] Proposal: extra option PRIVATE for target_link_libraries
On Wednesday 23 December 2009, Michael Wild wrote: > On 23. Dec, 2009, at 15:03 , Alexander Neundorf wrote: > > On Wednesday 23 December 2009, Michael Wild wrote: > >> On 23. Dec, 2009, at 14:36 , Alexander Neundorf wrote: > >>> On Wednesday 23 December 2009, Marcel Loose wrote: > Hi all, > > I suggested this in the quite long thread "third party library > dependencies", but it may have been overlooked. Hence, I started a new > thread. > > Upon (re)reading the Mandriva page > http://wiki.mandriva.com/en/Overlinking, I was thinking: maybe the > issue of overlinking can be solved more or less the same way as > pkg-config does: i.e. by defining private dependencies. This could be > an extra option to target_link_libraries. > Something like: > > target_link_libraries(mylib public1 public2 PRIVATE private1 private2) > >>> > >>> Assuming that public1 and public2 are libraries also built with cmake, > >>> that can be done already today: > >>> > >>> add_library(public1 ...) > >>> target_link_libraries(public1 private1) > >>> target_link_libraries(public1 LINK_INTERFACE_LIBRARIES "") > >>> > >>> add_library(public2 ...) > >>> target_link_libraries(public2 private2) > >>> target_link_libraries(public2 LINK_INTERFACE_LIBRARIES "") > >>> > >>> install(TARGETS public1 public2 ... EXPORT MyPublicLibs) > >>> install(EXPORT ...) > >>> > >>> > >>> Then later on, when loading these exported targets, you will get what > >>> you want. If public1/2 are shared libs, their "link interface" will be > >>> empty. If they are static, you will link against everything they have > >>> been "linked" against, independent of the LINK_INTERFACE_LIBRARIES > >>> (which is used only for shared libs). > >>> > >>> Alex > >> > >> So, the last step in doing > >> > >> add_library(public1 ...) > >> add_library(public2 ...) > >> target_link_libraries(public2 public1 private1) > >> target_link_libraries(public2 LINK_INTERFACE_LIBRARIES public1) > >> > >> is equivalent to > >> > >> set_target_properties(public2 PROPERTIES LINK_INTERFACE_LIBRARIES > >> "public1") > >> > >> Am I right? > > > > Yes, but if you use > > target_link_libraries(public2 LINK_INTERFACE_LIBRARIES public1) > > it can handle the "optimized" and "debug" keywords, which may be > > contained in some of the _LIBRARY/_LIBRARIES variables. > > > >> So, this should definitely go somewhere on the Wiki, that when one > >> creates a project that does an install(EXPORT ...) and provides a > >> XXX-config.cmake file, that one should carefully use > >> target_link_libraries(... > >> LINK_INTERFACE_LIBRARIES ...) to make things play nicely. > >> > >> This doesn't solve the problem for non-cmake built libraries which are > >> discovered through FindXXX.cmake modules, though. > > > > Well, partly. The FindXXX.cmake module can also set up the library as an > > imported target and set the respective properties manually. > > But I'm not aware of any Findxxx.cmake module which does that currently. > > > > Alex > > That's what I've been referring to earlier in this thread... The only catch > with IMPORTED targets I can make out is that if the author of the > FindXXX.cmake module uses a common name for the target, that it might clash > with a target name in the client project. Perhaps the FindXXX.cmake module > could do (here the case for zlib) > > find_library(ZLIB_LIBRARY z) > # TODO detect whether it is static or shared > add_library(ZLIB_z SHARED IMPORTED) > set_target_properties(ZLIB_z PROPERTIES IMPORTED_LOCATION "${ZLIB_LIBRARY}) > # TODO set up IMPORTED_LINK_INTERFACE_LIBRARIES > set(ZLIB_LIBRARIES "ZLIB_z") > > > What do you think? Yes, it should do exactly that. When exporting libraries, you can have the same effect by specifying a NAMESPACE option with install(EXPORT ... ) About shared or static... I think this is currently hard to do in cmake, AFAIK since it is hard to figure out whether a lib file on Windows is for a shared are static library. 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://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proposal: extra option PRIVATE for target_link_libraries
On Wed, 2009-12-23 at 15:06 +0100, Alexander Neundorf wrote: > On Wednesday 23 December 2009, Marcel Loose wrote: > ... > > Seems I must unconciously have felt that LINK_INTERFACE_LIBRARIES had > > something to do with the problem of overlinking I'm trying to solve > > right now. Funny, this morning I came to the conclusion that I probably > > wouldn't need LINK_INTERFACE_LIBRARIES (see thread: [Q] > > LINK_INTERFACE_LIBRARIES and the like), and now it seems I will. > > > > Guess I'll have to study carefully how this whole import/export and > > interface libs stuff works. Could you point me to some examples? > > It's probably also somewhere in the cmake wiki, but does this help ? > http://techbase.kde.org/Development/CMake_KDE_4_2#How_to_install_libraries_correctly_now > > Alex Thanks Alex, I think I start the grasp the concepts now. It's just like skating; slowly making progress ;-) Best regards, Marcel Loose. ___ 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://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proposal: extra option PRIVATE for target_link_libraries
On 23. Dec, 2009, at 15:14 , Marcel Loose wrote: > On Wed, 2009-12-23 at 14:12 +0100, Michael Wild wrote: >> On 23. Dec, 2009, at 13:28 , Marcel Loose wrote: >> >>> On Wed, 2009-12-23 at 13:09 +0100, Michael Wild wrote: On 23. Dec, 2009, at 12:08 , Marcel Loose wrote: > Hi all, > > I suggested this in the quite long thread "third party library > dependencies", but it may have been overlooked. Hence, I started a new > thread. > > Upon (re)reading the Mandriva page > http://wiki.mandriva.com/en/Overlinking, I was thinking: maybe the issue > of overlinking can be solved more or less the same way as pkg-config > does: i.e. by defining private dependencies. This could be an extra > option to target_link_libraries. > Something like: > > target_link_libraries(mylib public1 public2 PRIVATE private1 private2) > > This would tell CMake that mylib directly depends on public1 and public2 > and should only link in these two libraries when these are shared > object libraries; otherwise private1 and private2 would also need to be > added on the link line. > > The big hurdle to take, of course, is to detect in a > platform-independent way whether the given library is shared or static. > However, a lot of this knowledge is already available in the diverse > Modules/Platform macros, so my feeling is that this should be feasible. > > Best regards, > Marcel Loose. > You would also need a PUBLIC keyword, and then require that all FindXXX.cmake modules prefix their libraries with PUBLIC and PRIVATE. If only the PRIVATE libraries where prefixed, the following would not work if A_LIBRARIES contains PRIVATE: find_package(A) find_package(B) add_library(C source.c) target_link_libraries(C ${A_LIBRARIES} ${B_LIBRARIES}) Because then all the B_LIBRARIES would be considered to be private "details" of the public A_LIBRARIES... Also, there's no way to tell CMake which of the private libraries belongs to which of the public libraries. I think it would be better if a FindXXX.cmake module marked the private libraries as a property of the public libraries and then let CMake take it from there (although as of now I wouldn't know on what to set the property, except if the module created an IMPORTED target for each of the public libraries, but that bears the possibility of target name collisions with the importing project). Michael >>> >>> Hi Michael, >>> >>> I don't think you'll need to prefix the library names with either >>> PRIVATE_ or PUBLIC_. CMake could figure out whether "public1" and >>> "public2" are shared or static libraries. If they are shared libraries, >>> then the libraries marked as private ("private1" and "private2") do not >>> have to be linked in as well. Otherwise they must also be linked in. I >>> assume that CMake keeps a list internally, of all dependent targets; the >>> private libs should only be added to that internal list if the public >>> libs are static libs. >>> >>> I don't completely understand your example. Are you suggesting that >>> you'll run into trouble if you have a library named "PRIVATE"? I think >>> name clashes will currently occur as well if I name my library "debug", >>> "optimized", or "general". >>> >>> Maybe, it would be better if the FindXXX modules would handle this. On >>> the other hand, you then depend on third parties to properly update >>> their FindXXX modules, or have to rewrite them yourselves :-( >>> >>> Best regards, >>> Marcel Loose. >>> >> >> >> No, it won't work. For example, if FindA.cmake does >> >> set(A_LIBRARIES /some/path/libA.so >> PRIVATE /some/other/path/libX.a /some/other/path/libY.a) >> >> and FindB.cmake contains >> >> # notice that this is a static library! >> set(B_LIBRARIES /some/path/libB.a) >> >> >> then the call >> >> target_link_libraries(C ${A_LIBRARIES} ${B_LIBRARIES}) >> >> expands to (wrapped for legibility >> >> target_link_libraries(C >> /some/path/libA.so >> PRIVATE /some/other/path/libX.a >> /some/other/path/libY.a >> /some/path/libB.a) >> >> which is different in meaning from >> >> target_link_libraries(C ${B_LIBRARIES} ${A_LIBRARIES}) >> >> which becomes >> >> target_link_libraries(C >> /some/path/libB.a >> /some/path/libA.so >> PRIVATE >> /some/other/path/libX.a >> /some/other/path/libY.a) >> >> In the first case libB.a becomes marked as PRIVATE of libA.so! Not very nice >> if you ask me ;-) >> >> Michael > > Hi Michael, > > I never suggested that A_LIBRARIES should be set to contain "PRIVATE". I > suggested to add a keyword "PRIVATE" to the target_link_libraries > command. > Ok, but then how does FindA.cmake communicate that libA.a needs some private libraries? Does the user then have to do target_link_librar
Re: [CMake] Proposal: extra option PRIVATE for target_link_libraries
On 23. Dec, 2009, at 15:03 , Alexander Neundorf wrote: > On Wednesday 23 December 2009, Michael Wild wrote: >> On 23. Dec, 2009, at 14:36 , Alexander Neundorf wrote: >>> On Wednesday 23 December 2009, Marcel Loose wrote: Hi all, I suggested this in the quite long thread "third party library dependencies", but it may have been overlooked. Hence, I started a new thread. Upon (re)reading the Mandriva page http://wiki.mandriva.com/en/Overlinking, I was thinking: maybe the issue of overlinking can be solved more or less the same way as pkg-config does: i.e. by defining private dependencies. This could be an extra option to target_link_libraries. Something like: target_link_libraries(mylib public1 public2 PRIVATE private1 private2) >>> >>> Assuming that public1 and public2 are libraries also built with cmake, >>> that can be done already today: >>> >>> add_library(public1 ...) >>> target_link_libraries(public1 private1) >>> target_link_libraries(public1 LINK_INTERFACE_LIBRARIES "") >>> >>> add_library(public2 ...) >>> target_link_libraries(public2 private2) >>> target_link_libraries(public2 LINK_INTERFACE_LIBRARIES "") >>> >>> install(TARGETS public1 public2 ... EXPORT MyPublicLibs) >>> install(EXPORT ...) >>> >>> >>> Then later on, when loading these exported targets, you will get what you >>> want. If public1/2 are shared libs, their "link interface" will be empty. >>> If they are static, you will link against everything they have been >>> "linked" against, independent of the LINK_INTERFACE_LIBRARIES (which is >>> used only for shared libs). >>> >>> Alex >> >> So, the last step in doing >> >> add_library(public1 ...) >> add_library(public2 ...) >> target_link_libraries(public2 public1 private1) >> target_link_libraries(public2 LINK_INTERFACE_LIBRARIES public1) >> >> is equivalent to >> >> set_target_properties(public2 PROPERTIES LINK_INTERFACE_LIBRARIES >> "public1") >> >> Am I right? > > Yes, but if you use > target_link_libraries(public2 LINK_INTERFACE_LIBRARIES public1) > it can handle the "optimized" and "debug" keywords, which may be contained in > some of the _LIBRARY/_LIBRARIES variables. > >> So, this should definitely go somewhere on the Wiki, that when one creates >> a project that does an install(EXPORT ...) and provides a XXX-config.cmake >> file, that one should carefully use target_link_libraries(... >> LINK_INTERFACE_LIBRARIES ...) to make things play nicely. >> >> This doesn't solve the problem for non-cmake built libraries which are >> discovered through FindXXX.cmake modules, though. > > Well, partly. The FindXXX.cmake module can also set up the library as an > imported target and set the respective properties manually. > But I'm not aware of any Findxxx.cmake module which does that currently. > > Alex That's what I've been referring to earlier in this thread... The only catch with IMPORTED targets I can make out is that if the author of the FindXXX.cmake module uses a common name for the target, that it might clash with a target name in the client project. Perhaps the FindXXX.cmake module could do (here the case for zlib) find_library(ZLIB_LIBRARY z) # TODO detect whether it is static or shared add_library(ZLIB_z SHARED IMPORTED) set_target_properties(ZLIB_z PROPERTIES IMPORTED_LOCATION "${ZLIB_LIBRARY}) # TODO set up IMPORTED_LINK_INTERFACE_LIBRARIES set(ZLIB_LIBRARIES "ZLIB_z") What do you think? Also, should there be a way of finding both, static and shared versions? Michael ___ 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://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proposal: extra option PRIVATE for target_link_libraries
On Wed, 2009-12-23 at 14:12 +0100, Michael Wild wrote: > On 23. Dec, 2009, at 13:28 , Marcel Loose wrote: > > > On Wed, 2009-12-23 at 13:09 +0100, Michael Wild wrote: > >> On 23. Dec, 2009, at 12:08 , Marcel Loose wrote: > >> > >>> Hi all, > >>> > >>> I suggested this in the quite long thread "third party library > >>> dependencies", but it may have been overlooked. Hence, I started a new > >>> thread. > >>> > >>> Upon (re)reading the Mandriva page > >>> http://wiki.mandriva.com/en/Overlinking, I was thinking: maybe the issue > >>> of overlinking can be solved more or less the same way as pkg-config > >>> does: i.e. by defining private dependencies. This could be an extra > >>> option to target_link_libraries. > >>> Something like: > >>> > >>> target_link_libraries(mylib public1 public2 PRIVATE private1 private2) > >>> > >>> This would tell CMake that mylib directly depends on public1 and public2 > >>> and should only link in these two libraries when these are shared > >>> object libraries; otherwise private1 and private2 would also need to be > >>> added on the link line. > >>> > >>> The big hurdle to take, of course, is to detect in a > >>> platform-independent way whether the given library is shared or static. > >>> However, a lot of this knowledge is already available in the diverse > >>> Modules/Platform macros, so my feeling is that this should be feasible. > >>> > >>> Best regards, > >>> Marcel Loose. > >>> > >> > >> You would also need a PUBLIC keyword, and then require that all > >> FindXXX.cmake modules prefix their libraries with PUBLIC and PRIVATE. If > >> only the PRIVATE libraries where prefixed, the following would not work if > >> A_LIBRARIES contains PRIVATE: > >> > >> find_package(A) > >> find_package(B) > >> add_library(C source.c) > >> target_link_libraries(C ${A_LIBRARIES} ${B_LIBRARIES}) > >> > >> Because then all the B_LIBRARIES would be considered to be private > >> "details" of the public A_LIBRARIES... Also, there's no way to tell CMake > >> which of the private libraries belongs to which of the public libraries. > >> > >> I think it would be better if a FindXXX.cmake module marked the private > >> libraries as a property of the public libraries and then let CMake take it > >> from there (although as of now I wouldn't know on what to set the > >> property, except if the module created an IMPORTED target for each of the > >> public libraries, but that bears the possibility of target name collisions > >> with the importing project). > >> > >> Michael > > > > Hi Michael, > > > > I don't think you'll need to prefix the library names with either > > PRIVATE_ or PUBLIC_. CMake could figure out whether "public1" and > > "public2" are shared or static libraries. If they are shared libraries, > > then the libraries marked as private ("private1" and "private2") do not > > have to be linked in as well. Otherwise they must also be linked in. I > > assume that CMake keeps a list internally, of all dependent targets; the > > private libs should only be added to that internal list if the public > > libs are static libs. > > > > I don't completely understand your example. Are you suggesting that > > you'll run into trouble if you have a library named "PRIVATE"? I think > > name clashes will currently occur as well if I name my library "debug", > > "optimized", or "general". > > > > Maybe, it would be better if the FindXXX modules would handle this. On > > the other hand, you then depend on third parties to properly update > > their FindXXX modules, or have to rewrite them yourselves :-( > > > > Best regards, > > Marcel Loose. > > > > > No, it won't work. For example, if FindA.cmake does > > set(A_LIBRARIES /some/path/libA.so > PRIVATE /some/other/path/libX.a /some/other/path/libY.a) > > and FindB.cmake contains > > # notice that this is a static library! > set(B_LIBRARIES /some/path/libB.a) > > > then the call > > target_link_libraries(C ${A_LIBRARIES} ${B_LIBRARIES}) > > expands to (wrapped for legibility > > target_link_libraries(C > /some/path/libA.so > PRIVATE /some/other/path/libX.a > /some/other/path/libY.a > /some/path/libB.a) > > which is different in meaning from > > target_link_libraries(C ${B_LIBRARIES} ${A_LIBRARIES}) > > which becomes > > target_link_libraries(C > /some/path/libB.a > /some/path/libA.so > PRIVATE > /some/other/path/libX.a > /some/other/path/libY.a) > > In the first case libB.a becomes marked as PRIVATE of libA.so! Not very nice > if you ask me ;-) > > Michael Hi Michael, I never suggested that A_LIBRARIES should be set to contain "PRIVATE". I suggested to add a keyword "PRIVATE" to the target_link_libraries command. Of course, if you want to abuse CMake, it's always possible. For example, the following CMakeLists.txt file will not be processed by CMake, because I decided in my eternal wisdom (sic) to name one of my libraries "optimized". My OS d
Re: [CMake] Proposal: extra option PRIVATE for target_link_libraries
On Wednesday 23 December 2009, Michael Wild wrote: > On 23. Dec, 2009, at 14:36 , Alexander Neundorf wrote: > > On Wednesday 23 December 2009, Marcel Loose wrote: > >> Hi all, > >> > >> I suggested this in the quite long thread "third party library > >> dependencies", but it may have been overlooked. Hence, I started a new > >> thread. > >> > >> Upon (re)reading the Mandriva page > >> http://wiki.mandriva.com/en/Overlinking, I was thinking: maybe the issue > >> of overlinking can be solved more or less the same way as pkg-config > >> does: i.e. by defining private dependencies. This could be an extra > >> option to target_link_libraries. > >> Something like: > >> > >> target_link_libraries(mylib public1 public2 PRIVATE private1 private2) > > > > Assuming that public1 and public2 are libraries also built with cmake, > > that can be done already today: > > > > add_library(public1 ...) > > target_link_libraries(public1 private1) > > target_link_libraries(public1 LINK_INTERFACE_LIBRARIES "") > > > > add_library(public2 ...) > > target_link_libraries(public2 private2) > > target_link_libraries(public2 LINK_INTERFACE_LIBRARIES "") > > > > install(TARGETS public1 public2 ... EXPORT MyPublicLibs) > > install(EXPORT ...) > > > > > > Then later on, when loading these exported targets, you will get what you > > want. If public1/2 are shared libs, their "link interface" will be empty. > > If they are static, you will link against everything they have been > > "linked" against, independent of the LINK_INTERFACE_LIBRARIES (which is > > used only for shared libs). > > > > Alex > > So, the last step in doing > > add_library(public1 ...) > add_library(public2 ...) > target_link_libraries(public2 public1 private1) > target_link_libraries(public2 LINK_INTERFACE_LIBRARIES public1) > > is equivalent to > > set_target_properties(public2 PROPERTIES LINK_INTERFACE_LIBRARIES > "public1") > > Am I right? Yes, but if you use target_link_libraries(public2 LINK_INTERFACE_LIBRARIES public1) it can handle the "optimized" and "debug" keywords, which may be contained in some of the _LIBRARY/_LIBRARIES variables. > So, this should definitely go somewhere on the Wiki, that when one creates > a project that does an install(EXPORT ...) and provides a XXX-config.cmake > file, that one should carefully use target_link_libraries(... > LINK_INTERFACE_LIBRARIES ...) to make things play nicely. > > This doesn't solve the problem for non-cmake built libraries which are > discovered through FindXXX.cmake modules, though. Well, partly. The FindXXX.cmake module can also set up the library as an imported target and set the respective properties manually. But I'm not aware of any Findxxx.cmake module which does that currently. 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://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proposal: extra option PRIVATE for target_link_libraries
On Wed, 2009-12-23 at 14:36 +0100, Alexander Neundorf wrote: > On Wednesday 23 December 2009, Marcel Loose wrote: > > Hi all, > > > > I suggested this in the quite long thread "third party library > > dependencies", but it may have been overlooked. Hence, I started a new > > thread. > > > > Upon (re)reading the Mandriva page > > http://wiki.mandriva.com/en/Overlinking, I was thinking: maybe the issue > > of overlinking can be solved more or less the same way as pkg-config > > does: i.e. by defining private dependencies. This could be an extra > > option to target_link_libraries. > > Something like: > > > > target_link_libraries(mylib public1 public2 PRIVATE private1 private2) > > Assuming that public1 and public2 are libraries also built with cmake, that > can be done already today: > > add_library(public1 ...) > target_link_libraries(public1 private1) > target_link_libraries(public1 LINK_INTERFACE_LIBRARIES "") > > add_library(public2 ...) > target_link_libraries(public2 private2) > target_link_libraries(public2 LINK_INTERFACE_LIBRARIES "") > > install(TARGETS public1 public2 ... EXPORT MyPublicLibs) > install(EXPORT ...) > > > Then later on, when loading these exported targets, you will get what you > want. If public1/2 are shared libs, their "link interface" will be empty. If > they are static, you will link against everything they have been "linked" > against, independent of the LINK_INTERFACE_LIBRARIES (which is used only for > shared libs). > > Alex Hi Alex, Seems I must unconciously have felt that LINK_INTERFACE_LIBRARIES had something to do with the problem of overlinking I'm trying to solve right now. Funny, this morning I came to the conclusion that I probably wouldn't need LINK_INTERFACE_LIBRARIES (see thread: [Q] LINK_INTERFACE_LIBRARIES and the like), and now it seems I will. Guess I'll have to study carefully how this whole import/export and interface libs stuff works. Could you point me to some examples? Best regards, Marcel Loose. ___ 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://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proposal: extra option PRIVATE for target_link_libraries
On 23. Dec, 2009, at 14:36 , Alexander Neundorf wrote: > On Wednesday 23 December 2009, Marcel Loose wrote: >> Hi all, >> >> I suggested this in the quite long thread "third party library >> dependencies", but it may have been overlooked. Hence, I started a new >> thread. >> >> Upon (re)reading the Mandriva page >> http://wiki.mandriva.com/en/Overlinking, I was thinking: maybe the issue >> of overlinking can be solved more or less the same way as pkg-config >> does: i.e. by defining private dependencies. This could be an extra >> option to target_link_libraries. >> Something like: >> >> target_link_libraries(mylib public1 public2 PRIVATE private1 private2) > > Assuming that public1 and public2 are libraries also built with cmake, that > can be done already today: > > add_library(public1 ...) > target_link_libraries(public1 private1) > target_link_libraries(public1 LINK_INTERFACE_LIBRARIES "") > > add_library(public2 ...) > target_link_libraries(public2 private2) > target_link_libraries(public2 LINK_INTERFACE_LIBRARIES "") > > install(TARGETS public1 public2 ... EXPORT MyPublicLibs) > install(EXPORT ...) > > > Then later on, when loading these exported targets, you will get what you > want. If public1/2 are shared libs, their "link interface" will be empty. If > they are static, you will link against everything they have been "linked" > against, independent of the LINK_INTERFACE_LIBRARIES (which is used only for > shared libs). > > Alex > So, the last step in doing add_library(public1 ...) add_library(public2 ...) target_link_libraries(public2 public1 private1) target_link_libraries(public2 LINK_INTERFACE_LIBRARIES public1) is equivalent to set_target_properties(public2 PROPERTIES LINK_INTERFACE_LIBRARIES "public1") Am I right? So, this should definitely go somewhere on the Wiki, that when one creates a project that does an install(EXPORT ...) and provides a XXX-config.cmake file, that one should carefully use target_link_libraries(... LINK_INTERFACE_LIBRARIES ...) to make things play nicely. This doesn't solve the problem for non-cmake built libraries which are discovered through FindXXX.cmake modules, though. Michael ___ 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://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proposal: extra option PRIVATE for target_link_libraries
On Wednesday 23 December 2009, Marcel Loose wrote: > Hi all, > > I suggested this in the quite long thread "third party library > dependencies", but it may have been overlooked. Hence, I started a new > thread. > > Upon (re)reading the Mandriva page > http://wiki.mandriva.com/en/Overlinking, I was thinking: maybe the issue > of overlinking can be solved more or less the same way as pkg-config > does: i.e. by defining private dependencies. This could be an extra > option to target_link_libraries. > Something like: > > target_link_libraries(mylib public1 public2 PRIVATE private1 private2) Assuming that public1 and public2 are libraries also built with cmake, that can be done already today: add_library(public1 ...) target_link_libraries(public1 private1) target_link_libraries(public1 LINK_INTERFACE_LIBRARIES "") add_library(public2 ...) target_link_libraries(public2 private2) target_link_libraries(public2 LINK_INTERFACE_LIBRARIES "") install(TARGETS public1 public2 ... EXPORT MyPublicLibs) install(EXPORT ...) Then later on, when loading these exported targets, you will get what you want. If public1/2 are shared libs, their "link interface" will be empty. If they are static, you will link against everything they have been "linked" against, independent of the LINK_INTERFACE_LIBRARIES (which is used only for shared libs). 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://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proposal: extra option PRIVATE for target_link_libraries
On 23. Dec, 2009, at 13:28 , Marcel Loose wrote: > On Wed, 2009-12-23 at 13:09 +0100, Michael Wild wrote: >> On 23. Dec, 2009, at 12:08 , Marcel Loose wrote: >> >>> Hi all, >>> >>> I suggested this in the quite long thread "third party library >>> dependencies", but it may have been overlooked. Hence, I started a new >>> thread. >>> >>> Upon (re)reading the Mandriva page >>> http://wiki.mandriva.com/en/Overlinking, I was thinking: maybe the issue >>> of overlinking can be solved more or less the same way as pkg-config >>> does: i.e. by defining private dependencies. This could be an extra >>> option to target_link_libraries. >>> Something like: >>> >>> target_link_libraries(mylib public1 public2 PRIVATE private1 private2) >>> >>> This would tell CMake that mylib directly depends on public1 and public2 >>> and should only link in these two libraries when these are shared >>> object libraries; otherwise private1 and private2 would also need to be >>> added on the link line. >>> >>> The big hurdle to take, of course, is to detect in a >>> platform-independent way whether the given library is shared or static. >>> However, a lot of this knowledge is already available in the diverse >>> Modules/Platform macros, so my feeling is that this should be feasible. >>> >>> Best regards, >>> Marcel Loose. >>> >> >> You would also need a PUBLIC keyword, and then require that all >> FindXXX.cmake modules prefix their libraries with PUBLIC and PRIVATE. If >> only the PRIVATE libraries where prefixed, the following would not work if >> A_LIBRARIES contains PRIVATE: >> >> find_package(A) >> find_package(B) >> add_library(C source.c) >> target_link_libraries(C ${A_LIBRARIES} ${B_LIBRARIES}) >> >> Because then all the B_LIBRARIES would be considered to be private "details" >> of the public A_LIBRARIES... Also, there's no way to tell CMake which of the >> private libraries belongs to which of the public libraries. >> >> I think it would be better if a FindXXX.cmake module marked the private >> libraries as a property of the public libraries and then let CMake take it >> from there (although as of now I wouldn't know on what to set the property, >> except if the module created an IMPORTED target for each of the public >> libraries, but that bears the possibility of target name collisions with the >> importing project). >> >> Michael > > Hi Michael, > > I don't think you'll need to prefix the library names with either > PRIVATE_ or PUBLIC_. CMake could figure out whether "public1" and > "public2" are shared or static libraries. If they are shared libraries, > then the libraries marked as private ("private1" and "private2") do not > have to be linked in as well. Otherwise they must also be linked in. I > assume that CMake keeps a list internally, of all dependent targets; the > private libs should only be added to that internal list if the public > libs are static libs. > > I don't completely understand your example. Are you suggesting that > you'll run into trouble if you have a library named "PRIVATE"? I think > name clashes will currently occur as well if I name my library "debug", > "optimized", or "general". > > Maybe, it would be better if the FindXXX modules would handle this. On > the other hand, you then depend on third parties to properly update > their FindXXX modules, or have to rewrite them yourselves :-( > > Best regards, > Marcel Loose. > No, it won't work. For example, if FindA.cmake does set(A_LIBRARIES /some/path/libA.so PRIVATE /some/other/path/libX.a /some/other/path/libY.a) and FindB.cmake contains # notice that this is a static library! set(B_LIBRARIES /some/path/libB.a) then the call target_link_libraries(C ${A_LIBRARIES} ${B_LIBRARIES}) expands to (wrapped for legibility target_link_libraries(C /some/path/libA.so PRIVATE /some/other/path/libX.a /some/other/path/libY.a /some/path/libB.a) which is different in meaning from target_link_libraries(C ${B_LIBRARIES} ${A_LIBRARIES}) which becomes target_link_libraries(C /some/path/libB.a /some/path/libA.so PRIVATE /some/other/path/libX.a /some/other/path/libY.a) In the first case libB.a becomes marked as PRIVATE of libA.so! Not very nice if you ask me ;-) Michael ___ 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://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proposal: extra option PRIVATE for target_link_libraries
On Wed, 2009-12-23 at 13:09 +0100, Michael Wild wrote: > On 23. Dec, 2009, at 12:08 , Marcel Loose wrote: > > > Hi all, > > > > I suggested this in the quite long thread "third party library > > dependencies", but it may have been overlooked. Hence, I started a new > > thread. > > > > Upon (re)reading the Mandriva page > > http://wiki.mandriva.com/en/Overlinking, I was thinking: maybe the issue > > of overlinking can be solved more or less the same way as pkg-config > > does: i.e. by defining private dependencies. This could be an extra > > option to target_link_libraries. > > Something like: > > > > target_link_libraries(mylib public1 public2 PRIVATE private1 private2) > > > > This would tell CMake that mylib directly depends on public1 and public2 > > and should only link in these two libraries when these are shared > > object libraries; otherwise private1 and private2 would also need to be > > added on the link line. > > > > The big hurdle to take, of course, is to detect in a > > platform-independent way whether the given library is shared or static. > > However, a lot of this knowledge is already available in the diverse > > Modules/Platform macros, so my feeling is that this should be feasible. > > > > Best regards, > > Marcel Loose. > > > > You would also need a PUBLIC keyword, and then require that all FindXXX.cmake > modules prefix their libraries with PUBLIC and PRIVATE. If only the PRIVATE > libraries where prefixed, the following would not work if A_LIBRARIES > contains PRIVATE: > > find_package(A) > find_package(B) > add_library(C source.c) > target_link_libraries(C ${A_LIBRARIES} ${B_LIBRARIES}) > > Because then all the B_LIBRARIES would be considered to be private "details" > of the public A_LIBRARIES... Also, there's no way to tell CMake which of the > private libraries belongs to which of the public libraries. > > I think it would be better if a FindXXX.cmake module marked the private > libraries as a property of the public libraries and then let CMake take it > from there (although as of now I wouldn't know on what to set the property, > except if the module created an IMPORTED target for each of the public > libraries, but that bears the possibility of target name collisions with the > importing project). > > Michael Hi Michael, I don't think you'll need to prefix the library names with either PRIVATE_ or PUBLIC_. CMake could figure out whether "public1" and "public2" are shared or static libraries. If they are shared libraries, then the libraries marked as private ("private1" and "private2") do not have to be linked in as well. Otherwise they must also be linked in. I assume that CMake keeps a list internally, of all dependent targets; the private libs should only be added to that internal list if the public libs are static libs. I don't completely understand your example. Are you suggesting that you'll run into trouble if you have a library named "PRIVATE"? I think name clashes will currently occur as well if I name my library "debug", "optimized", or "general". Maybe, it would be better if the FindXXX modules would handle this. On the other hand, you then depend on third parties to properly update their FindXXX modules, or have to rewrite them yourselves :-( Best regards, Marcel Loose. ___ 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://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Proposal: extra option PRIVATE for target_link_libraries
On 23. Dec, 2009, at 12:08 , Marcel Loose wrote: > Hi all, > > I suggested this in the quite long thread "third party library > dependencies", but it may have been overlooked. Hence, I started a new > thread. > > Upon (re)reading the Mandriva page > http://wiki.mandriva.com/en/Overlinking, I was thinking: maybe the issue > of overlinking can be solved more or less the same way as pkg-config > does: i.e. by defining private dependencies. This could be an extra > option to target_link_libraries. > Something like: > > target_link_libraries(mylib public1 public2 PRIVATE private1 private2) > > This would tell CMake that mylib directly depends on public1 and public2 > and should only link in these two libraries when these are shared > object libraries; otherwise private1 and private2 would also need to be > added on the link line. > > The big hurdle to take, of course, is to detect in a > platform-independent way whether the given library is shared or static. > However, a lot of this knowledge is already available in the diverse > Modules/Platform macros, so my feeling is that this should be feasible. > > Best regards, > Marcel Loose. > You would also need a PUBLIC keyword, and then require that all FindXXX.cmake modules prefix their libraries with PUBLIC and PRIVATE. If only the PRIVATE libraries where prefixed, the following would not work if A_LIBRARIES contains PRIVATE: find_package(A) find_package(B) add_library(C source.c) target_link_libraries(C ${A_LIBRARIES} ${B_LIBRARIES}) Because then all the B_LIBRARIES would be considered to be private "details" of the public A_LIBRARIES... Also, there's no way to tell CMake which of the private libraries belongs to which of the public libraries. I think it would be better if a FindXXX.cmake module marked the private libraries as a property of the public libraries and then let CMake take it from there (although as of now I wouldn't know on what to set the property, except if the module created an IMPORTED target for each of the public libraries, but that bears the possibility of target name collisions with the importing project). Michael ___ 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://www.cmake.org/mailman/listinfo/cmake
[CMake] Proposal: extra option PRIVATE for target_link_libraries
Hi all, I suggested this in the quite long thread "third party library dependencies", but it may have been overlooked. Hence, I started a new thread. Upon (re)reading the Mandriva page http://wiki.mandriva.com/en/Overlinking, I was thinking: maybe the issue of overlinking can be solved more or less the same way as pkg-config does: i.e. by defining private dependencies. This could be an extra option to target_link_libraries. Something like: target_link_libraries(mylib public1 public2 PRIVATE private1 private2) This would tell CMake that mylib directly depends on public1 and public2 and should only link in these two libraries when these are shared object libraries; otherwise private1 and private2 would also need to be added on the link line. The big hurdle to take, of course, is to detect in a platform-independent way whether the given library is shared or static. However, a lot of this knowledge is already available in the diverse Modules/Platform macros, so my feeling is that this should be feasible. Best regards, Marcel Loose. ___ 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://www.cmake.org/mailman/listinfo/cmake