Re: [CMake] providing library information, what's the cmake way
At this point of the discussion, I think that we need someone else to join. We both have made strong points for our viewpoints, and neither of us has a perfect solution. On Sunday 05 December 2010 12:48:49 Michael Hertling wrote: On 12/01/2010 05:57 PM, Johannes Zarl wrote: On 12/01/2010 at 16:06, Michael Hertling mhertling at online.de wrote: These variables are well-known and officially recommended for component- less packages only. Nobody bothered to write recommendations for component-packages yet. ${CMAKE_ROOT}/Modules/readme.txt mentions the XXX_YYY_EXECUTABLE and XXX_YY_{LIBRARY,INCLUDE_DIR} variables explicitly, and IMO, wordings as YYY tool that comes with XXX or YY library that is part of the XXX system allow the general terms tool and part to be applied smoothly to the components of a package. Furthermore, the component- specific variables like XXX_FIND_COMPONENTS are handled also, so I do believe that this file is relevant for multi-component packages, too, including the XXX_{LIBRARIES,INCLUDE_DIRS} variables. However, variables like XXX_YYY_{LIBRARIES,INCLUDE_DIRS} are not mentioned at all, i.e. there're completely new and should be well founded. IMO the wording is ambiguous. When I read it, it was obvious to me that the XXX_YYY_LIBRARIES etc. are to be defined. To quote readme.txt: XXX_EXECUTABLE Where to find the XXX tool. XXX_YYY_EXECUTABLE Where to find the YYY tool that comes with XXX. I assumed XXX_YYY_EXECUTABLE as an example, so that not every variable has to be mentioned a second time in its component-specific form. Now that I heard your interpretation and reread readme.txt, it fits the description just as well. Anyway, the ${CMAKE_ROOT}/Modules/readme.txt doesn't handle multi- component packages thouroughly, so I would greatly appreciate any improvements to decrease ambiguities/uncertainties and to reach a consensus. For this reason, I regret that we haven't seen further opinions on this topic, in particular because pretty much every non-trivial package could make good use of a components-aware find module or config file. As I have written above, I totally agree. The problem is that FPHSA simply wasn't created with components in mind. As worthwhile as code-reuse is, it's not a goal in itself. Rather than jump through hoops in order to reuse the existing interface, IMO one should create a good interface for the more complex use-case at hand. To apply FPHSA to a component and, thus, re-use existing code, I just need to define two variables; this is not jumping through hoops. Setting a specific variable for its side-effects before calling a function makes a truly bad interface-style for me. Regardless of the outcome of this discussion, I'll create a patch for the FPHSA module introducing the component-keyword (once, I have time, whenever that is; a totally different topic is whether the patch will be included to cmake). Suppose you have components YYY and ZZZ with ZZZ depending on YYY. When handling ZZZ in the find module, there's a certain probability that you must access the YYY stuff, so one would like to have the XXX_YYY_FOUND variable already defined at this time. This is a sensible assumption, and should be supported by a component- aware FPHSA... With the FPCHSA, the components' FOUND variables are defined in one go at the module's end; hence, one has to check YYY's availability by oneself when it's needed for ZZZ, and FPCHSA will do the same work once more later. Well, there currently does not exist a single line of code for a component-aware FPHSA. If it were to be implemented like this, There wouldn't be much incentive to use it. Instead, IMO, it's convenient to check a component's presence right after the relevant variables have received their values, and for this purpose, FPHSA is entirely sufficient. Apart from the whole defining-variables-for-side-effect thing, yes. Still this would benefit from component-awareness: ... FPHSA(XXX XXX_LIBRARIES XXX_INCLUDE_DIRS) #detect component YYY FPHSA(XXX COMPONENT YYY XXX_YYY_FOO XXX_YYY_BAR) ... find_package( XXX COMPONENTS YYY) target_link_libraries(foo ${YYY_LIBRARIES}) find_package( XXX COMPONENTS ZZZ) target_link_libraries(bar ${ZZZ_LIBRARIES}) At this point, I just realised that I was being inconsistent. After all, the components do depend on the whole package. So YYY_LIBRARIES should also contain XXX_LIBRARIES. If I understand correctly, you intend to populate XXX_YYY_LIBRARIES, e.g., with its own value XXX_YYY_LIBRARY *and all* its prerequisite components' values, too? If so, you will end up with many repeatedly mentioned libraries on the link command line unless there're hardly any inter-component dependencies. Suppose ZZZ depends on YYY, so I have to admit that I didn't encounter a use-case with inter-component dependencies before this discussion, so my thoughts on this might be called developing.
Re: [CMake] providing library information, what's the cmake way
On Sunday 05 Dec 2010 6:16:35 pm Michael Hertling wrote: On 11/30/2010 05:53 AM, Kishore wrote: On Tuesday 23 Nov 2010 5:27:56 pm Johannes Zarl wrote: Another somehow related topic seems to be import/export of targets. Should a LibraryConfig.cmake or FindLibrary.cmake file create imported targets for the library? Thanks for this thread. It has helped. However, i am still not clear about the use of the export/import feature. I thought that libraries built with cmake would not need to write their Find*.cmake or *Config.cmake modules as they could simply use the EXPORT feature. No, the file created and installed by INSTALL(EXPORT ...) - casually denoted as a targets file - contains information about the targets provided by the package. The targets are set up as IMPORTED in the targets file, and the latter must be included by *Config.cmake which is still necessary. This is meant as a more flexible alternative to explicit paths in XXX_LIBRARIES variables, e.g.; with targets files, XXX_LIBRARIES contains the imported targets instead of the targets' paths, so the different build types can be handled much better at link time. The actual paths of the imported targets are specified by means of IMPORTED_LOCATION properties in the targets file, too. Thanks Michael. I think i have this somewhat figured out now. Will use and see if i have more doubts. -- Cheers! Kishore ___ 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] providing library information, what's the cmake way
On 12/01/2010 05:57 PM, Johannes Zarl wrote: On 12/01/2010 at 16:06, Michael Hertling mhertling at online.de wrote: FIND_PACKAGE(XXX COMPONENTS YYY) ... ADD_SUBDIRECTORY(subdir) ... TARGET_LINK_LIBRARIES(AAA ${XXX_LIBRARIES}) TARGET_LINK_LIBRARIES(BBB ${XXX_LIBRARIES} ${XXX_YYY_LIBRARIES}) In subdir/CMakeLists.txt: FIND_PACKAGE(XXX COMPONENTS ZZZ) ... TARGET_LINK_LIBRARIES(subBBB ${XXX_LIBRARIES} ${XXX_ZZZ_LIBRARIES}) As I mentioned above, I would expect XXX_LIBRARIES to contain only the base library, and find_package calls to act accumulatively. If I understand correctly, you'd like to have a set of variables like XXX_*_{LIBRARIES,INCLUDE_DIRS,...} for each component instead of one comprehensive set XXX_{LIBRARIES,INCLUDE_DIRS,...} for the entire package including the components; this hasn't been obvious to me. Correct. The downside of your approach is that you have to mention component- specific variables at various locations: For each component denoted in the FIND_PACKAGE() invocation, you would usually have to mention - XXX_*_INCLUDE_DIRS in INCLUDE_DIRECTORIES() - XXX_*_LIBRARIES in TARGET_LINK_LIBRARIES() - XXX_*_DEFINITIONS in ADD_DEFINITIONS() Which is less work than saving all three values for each target that I create. It's not necessary to save these variables for each target. Typically, it's necessary if there's more than one target in the CMakeLists.txt, and two or more of them use the same package with a different set of components; by far, this does not hold for all cases. Besides, when loading multiple packages for multiple targets, it's not uncommon to collect libraries in target-specific target_LIBRARIES variables as well as one collects a target's sources in target_SOURCES, so the only remaining overhead is an additional FIND_PACKAGE() call which is inexpensive: FIND_PACKAGE(A) SET(T1_LIBRARIES ${A_LIBRARIES}) SET(T2_LIBRARIES ${A_LIBRARIES}) FIND_PACKAGE(B COMPONENTS B1) LIST(APPEND T1_LIBRARIES ${B_LIBRARIES}) FIND_PACKAGE(B COMPONENTS B2) # -- That's all. LIST(APPEND T2_LIBRARIES ${B_LIBRARIES}) ... TARGET_LINK_LIBRARIES(T1 ${T1_LIBRARIES}) TARGET_LINK_LIBRARIES(T2 ${T2_LIBRARIES}) A similar point might be applied to XXX_{INCLUDE_DIRS,DEFINITIONS}. in addition to the package's base stuff, i.e. roughly speaking, with n components you need to reference 3+3n variables. These 3+3n variables have to be defined, anyways (the find module needs them internally, if it wants to compose XXX_INCLUDE_DIRS etc.). Here, it's the user I have in mind, who possibly doesn't want to fourfold specify each set of components requested from a package. Still, referencing the 3+3n variables are less work than having to define _and_ reference 3N variables (with N being the number of targets in your project). The need to save the results of a FIND_PACKAGE() call may come up for targets within the same CMakeLists.txt file, but not unconditionally for each of a project's targets. Additionally, this measure is taken only if it's really necessary whereas your approach compels the user to always refer to each component four times. Look at one of the simplest configurations - one target and one package with two components - the two approaches manifest like: FIND_PACKAGE(XXX COMPONENTS YYY ZZZ) ADD_DEFINITIONS(${XXX_DEFINITIONS} ${XXX_YYY_DEFINITIONS} ${XXX_ZZZ_DEFINITIONS}) INCLUDE_DIRECTORIES(${XXX_INCLUDE_DIRS} ${XXX_YYY_INCLUDE_DIRS} ${XXX_ZZZ_INCLUDE_DIRS}) ADD_EXECUTABLE(...) TARGET_LINK_LIBRARIES(... ${XXX_LIBRARIES} ${XXX_YYY_LIBRARIES} ${XXX_ZZZ_LIBRARIES}) versus FIND_PACKAGE(XXX COMPONENTS YYY ZZZ) ADD_DEFINITIONS(${XXX_DEFINITIONS}) INCLUDE_DIRECTORIES(${XXX_INCLUDE_DIRS}) ADD_EXECUTABLE(...) TARGET_LINK_LIBRARIES(... ${XXX_LIBRARIES}) It's quite obvious which approach means less work, and having only one target in a CMakeLists.txt is no configuration I would denote as rare. IMO, this thwarts the idea of a multi-component package: Specifying components to adjust the well-known and officially recommended package-related variables like XXX_LIBRARIES. These variables are well-known and officially recommended for component- less packages only. Nobody bothered to write recommendations for component-packages yet. ${CMAKE_ROOT}/Modules/readme.txt mentions the XXX_YYY_EXECUTABLE and XXX_YY_{LIBRARY,INCLUDE_DIR} variables explicitly, and IMO, wordings as YYY tool that comes with XXX or YY library that is part of the XXX system allow the general terms tool and part to be applied smoothly to the components of a package. Furthermore, the component- specific variables like XXX_FIND_COMPONENTS are handled also, so I do believe that this file is relevant for multi-component packages, too, including the XXX_{LIBRARIES,INCLUDE_DIRS} variables. However, variables like XXX_YYY_{LIBRARIES,INCLUDE_DIRS} are not mentioned at all, i.e. there're completely new and should be well founded. Anyway, the ${CMAKE_ROOT}/Modules/readme.txt doesn't
Re: [CMake] providing library information, what's the cmake way
On 11/30/2010 05:53 AM, Kishore wrote: On Tuesday 23 Nov 2010 5:27:56 pm Johannes Zarl wrote: Another somehow related topic seems to be import/export of targets. Should a LibraryConfig.cmake or FindLibrary.cmake file create imported targets for the library? Thanks for this thread. It has helped. However, i am still not clear about the use of the export/import feature. I thought that libraries built with cmake would not need to write their Find*.cmake or *Config.cmake modules as they could simply use the EXPORT feature. No, the file created and installed by INSTALL(EXPORT ...) - casually denoted as a targets file - contains information about the targets provided by the package. The targets are set up as IMPORTED in the targets file, and the latter must be included by *Config.cmake which is still necessary. This is meant as a more flexible alternative to explicit paths in XXX_LIBRARIES variables, e.g.; with targets files, XXX_LIBRARIES contains the imported targets instead of the targets' paths, so the different build types can be handled much better at link time. The actual paths of the imported targets are specified by means of IMPORTED_LOCATION properties in the targets file, too. It would be really helpful if someone could explain the proper use of these features. In [1,2], the machinery is explained quite well. Regards, Michael [1]http://www.cmake.org/Wiki/CMake_2.6_Notes#Exporting_from_an_Installation_Tree [2]http://www.cmake.org/Wiki/CMake_2.6_Notes#Packaging_and_Exporting ___ 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] providing library information, what's the cmake way
On Wednesday 01 December 2010 17:57:45 Johannes Zarl wrote: Back to my proposed FPCHSA: My initial goal was to provide an interface which does as much work as possible for you, maybe at the price of restricted variable naming. So let's come up with a better interface: I do want to restrict the possible prefix for modules, because I really do think it is a good practice (and a practice worth enforcing) to require a common package prefix and one prefix for each component): FPCHSA( XXX DEFAULT_MSG LIBRARY INCLUDE_DIR DEFINITIONS COMPONENT YYY DEFAULT_MSG LIBRARY INCLUDE_DIR DEFINITIONS COMPONENT ZZZ DEFAULT_MSG INCLUDE_DIR OTHER_VAR ) This is far noisier than the initial approach, but still much easier to read and more compact to write that the FPHSA approach outlined above (3 lines vs. 7 lines). Even without the namespace-enforcement it would be readable: FPCHSA( XXX DEFAULT_MSG XXX_LIBRARY XXX_INCLUDE_DIR XXX_DEFINITIONS COMPONENT YYY DEFAULT_MSG XXX_YYY_LIBRARY XXX_YYY_INCLUDE_DIR XXX_YYY_DEFINITIONS COMPONENT ZZZ DEFAULT_MSG XXX_YYY_INCLUDE_DIR XXX_YYY_OTHER_VAR ) This signature should even be downwards-compatible with FPHSA. Btw. I just read the documentation for the new FPHSA: I do think that the COMPONENT keyword would actually fit in quite well into the new interface. I guess the FindPackageHandleStandardArgs-maintainer is reading this list: What do you think about adding component support? Cheers, Johannes ___ 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] providing library information, what's the cmake way
On 11/30/2010 01:32 PM, Johannes Zarl wrote: - Do multiple consecutive FIND_PACKAGE(XXX ...) invocations act in an accumulative manner on the invocation-specific variables? Generally speaking, I would say: yes. At least this is the way of the least surprise for the user, as in sufficiently complex projects a package may be included at different places with different arguments. For the same reason, I'd tend to the opposite; look at the following: FIND_PACKAGE(XXX COMPONENTS YYY) ... ADD_SUBDIRECTORY(subdir) In subdir/CMakeLists.txt: FIND_PACKAGE(XXX COMPONENTS ZZZ) ... TARGET_LINK_LIBRARIES(... ${XXX_LIBRARIES}) Here, the target is also linked against XXX_YYY_LIBRARY as the latter is inherited via XXX_LIBRARIES from the parent directory, but if the target only needs XXX_ZZZ_LIBRARY it will possibly be overlinked. Although this can be avoided by resetting XXX_LIBRARIES before each FIND_PACKAGE() invocation, I don't think that's the way one would like to go. IMO, the invocation-specific results of any FIND_PACKAGE() call should depend solely on the parameters passed in and the well-known variables like CMAKE_PREFIX_PATH. The downside is that one must possibly process or save the results before they could be overwritten, e.g.: FIND_PACKAGE(XXX REQUIRED YYY) SET(LIBRARIES ${XXX_LIBRARIES}) FIND_PACKAGE(XXX COMPONENTS ZZZ) LIST(APPEND LIBRARIES ${XXX_LIBRARIES}) ... TARGET_LINK_LIBRARIES(... ${LIBRARIES}) Since such related calls to FIND_PACKAGE(XXX ...) usually occur nearby each other within the same CMakeLists.txt, this little penalty should be acceptable whereas accumulated XXX_LIBRARIES and the like may have far reaching and surprising effects, especially in complex projects. Funny enough, my example is almost the same: FIND_PACKAGE(XXX COMPONENTS YYY) ... ADD_SUBDIRECTORY(subdir) ... TARGET_LINK_LIBRARIES(AAA ${XXX_LIBRARIES}) TARGET_LINK_LIBRARIES(BBB ${XXX_LIBRARIES} ${XXX_YYY_LIBRARIES}) In subdir/CMakeLists.txt: FIND_PACKAGE(XXX COMPONENTS ZZZ) ... TARGET_LINK_LIBRARIES(subBBB ${XXX_LIBRARIES} ${XXX_ZZZ_LIBRARIES}) As I mentioned above, I would expect XXX_LIBRARIES to contain only the base library, and find_package calls to act accumulatively. If I understand correctly, you'd like to have a set of variables like XXX_*_{LIBRARIES,INCLUDE_DIRS,...} for each component instead of one comprehensive set XXX_{LIBRARIES,INCLUDE_DIRS,...} for the entire package including the components; this hasn't been obvious to me. Nevertheless, what do you understand by accumulative in this regard, i.e. what accumulates in which variables if FIND_PACKAGE() is invoked multiple times and each component has an independent set of variables separate from the package's base stuff? If it was otherwise, then target AAA would be overlinked, and BBB would probably fail to link. Even without the ADD_SUBDIRECTORY the situation would be far from ideal: in order to avoid overlinking of BBB I have to make an additional find_package invocation. In a worst-case scenario one would need multiple find_package invocations for the same packages before each target! At first, BBB could not fail to link due to the FIND_PACKAGE() in the subdir/CMakeLists.txt because the XXX_LIBRARIES variable in the parent directory is not modified unless the find module uses the PARENT_SCOPE option of SET(), but there's no reason to do so as it is pretty unwise. In contrast, the potential overlinking of AAA is a point, indeed, as it is generally with multiple targets, each depending on an individual set of components, within the same CMakeLists.txt. Here, I'd actually need to call FIND_PACKAGE() multiple times and immediately process/save the variables like XXX_LIBRARIES if they're really invocation-specifically populated, but I'm in doubt whether this can be reckoned as far from ideal. Note that because of CMake's caching, repeated invocations of FIND_PACKAGE() don't tend to be expensive, so FIND_PACKAGE(XXX COMPONENTS base) TARGET_LINK_LIBRARIES(AAA ${XXX_LIBRARIES}) FIND_PACKAGE(XXX COMPONENTS base YYY) TARGET_LINK_LIBRARIES(BBB ${XXX_LIBRARIES}) is nothing I'd be afraid of. Moreover, in subdir/CMakeLists.txt, you have to call FIND_PACKAGE() anew anyway, as you've also when mixing optional and required components with a usage of the REQUIRED flag. The accumulative scenario of find_package without side-effects of the components on the XXX_LIBRARIES is far more transparent: If you link against XXX_LIBRARIES, you know exactly what you are linking against, regardless of who called find_package(XXX) with whatever components since you did your find_package call. You don't even have to backup your XXX_LIBRARIES and other variables, because they are not altered. The downside of your approach is that you have to mention component- specific variables at various locations: For each component denoted in the FIND_PACKAGE() invocation, you would usually have to mention - XXX_*_INCLUDE_DIRS in
Re: [CMake] providing library information, what's the cmake way
On 12/01/2010 at 16:06, Michael Hertling mhertl...@online.de wrote: FIND_PACKAGE(XXX COMPONENTS YYY) ... ADD_SUBDIRECTORY(subdir) ... TARGET_LINK_LIBRARIES(AAA ${XXX_LIBRARIES}) TARGET_LINK_LIBRARIES(BBB ${XXX_LIBRARIES} ${XXX_YYY_LIBRARIES}) In subdir/CMakeLists.txt: FIND_PACKAGE(XXX COMPONENTS ZZZ) ... TARGET_LINK_LIBRARIES(subBBB ${XXX_LIBRARIES} ${XXX_ZZZ_LIBRARIES}) As I mentioned above, I would expect XXX_LIBRARIES to contain only the base library, and find_package calls to act accumulatively. If I understand correctly, you'd like to have a set of variables like XXX_*_{LIBRARIES,INCLUDE_DIRS,...} for each component instead of one comprehensive set XXX_{LIBRARIES,INCLUDE_DIRS,...} for the entire package including the components; this hasn't been obvious to me. Correct. Nevertheless, what do you understand by accumulative in this regard, i.e. what accumulates in which variables if FIND_PACKAGE() is invoked multiple times and each component has an independent set of variables separate from the package's base stuff? Ok, accumulative maybe wasn't the best choice of words. What I mean it that subsequent find_package calls don't overwrite previous values. I.e. the components accumulate, not the contents of some variable. In other words, I would expect these two statements: find_package(XXX REQUIRED YYY) find_package(XXX COMPONENTS ZZZ) to give me a working environment in which I can safely use XXX, YYY and, if XXX_ZZZ_FOUND is true, ZZZ. If it was otherwise, then target AAA would be overlinked, and BBB would probably fail to link. Even without the ADD_SUBDIRECTORY the situation would be far from ideal: in order to avoid overlinking of BBB I have to make an additional find_package invocation. In a worst-case scenario one would need multiple find_package invocations for the same packages before each target! At first, BBB could not fail to link due to the FIND_PACKAGE() in the subdir/CMakeLists.txt because the XXX_LIBRARIES variable in the parent directory is not modified unless the find module uses the PARENT_SCOPE option of SET(), but there's no reason to do so as it is pretty unwise. You are right. I didn't think about the scope. In contrast, the potential overlinking of AAA is a point, indeed, as it is generally with multiple targets, each depending on an individual set of components, within the same CMakeLists.txt. Here, I'd actually need to call FIND_PACKAGE() multiple times and immediately process/save the variables like XXX_LIBRARIES if they're really invocation-specifically populated, but I'm in doubt whether this can be reckoned as far from ideal. Note that because of CMake's caching, repeated invocations of FIND_PACKAGE() don't tend to be expensive, so FIND_PACKAGE(XXX COMPONENTS base) TARGET_LINK_LIBRARIES(AAA ${XXX_LIBRARIES}) FIND_PACKAGE(XXX COMPONENTS base YYY) TARGET_LINK_LIBRARIES(BBB ${XXX_LIBRARIES}) is nothing I'd be afraid of. Moreover, in subdir/CMakeLists.txt, you have to call FIND_PACKAGE() anew anyway, as you've also when mixing optional and required components with a usage of the REQUIRED flag. The accumulative scenario of find_package without side-effects of the components on the XXX_LIBRARIES is far more transparent: If you link against XXX_LIBRARIES, you know exactly what you are linking against, regardless of who called find_package(XXX) with whatever components since you did your find_package call. You don't even have to backup your XXX_LIBRARIES and other variables, because they are not altered. The downside of your approach is that you have to mention component- specific variables at various locations: For each component denoted in the FIND_PACKAGE() invocation, you would usually have to mention - XXX_*_INCLUDE_DIRS in INCLUDE_DIRECTORIES() - XXX_*_LIBRARIES in TARGET_LINK_LIBRARIES() - XXX_*_DEFINITIONS in ADD_DEFINITIONS() Which is less work than saving all three values for each target that I create. in addition to the package's base stuff, i.e. roughly speaking, with n components you need to reference 3+3n variables. These 3+3n variables have to be defined, anyways (the find module needs them internally, if it wants to compose XXX_INCLUDE_DIRS etc.). Still, referencing the 3+3n variables are less work than having to define _and_ reference 3N variables (with N being the number of targets in your project). IMO, this thwarts the idea of a multi-component package: Specifying components to adjust the well-known and officially recommended package-related variables like XXX_LIBRARIES. These variables are well-known and officially recommended for component- less packages only. Nobody bothered to write recommendations for component-packages yet. BTW, what's the essential difference between a multi- component package as you outline it and multiple single-component packages, one for each component and another one for the base? One find_package call instead of n calls. Easier
Re: [CMake] providing library information, what's the cmake way
On 11/29/2010 02:28 PM, Johannes Zarl wrote: Sorry for the late response, but your mail was simply to long for a swift response... No problem, this topic is not exactly trivial. On 11/26/2010 at 05:47, Michael Hertling mhertl...@online.de wrote: On 11/24/2010 04:51 PM, Johannes Zarl wrote: About the components question again: I played around a bit, and I think I now more or less have comprehended this. I guess for a package XXX with components YYY and ZZZ, one could set variables XXX_HAS_YYY and XXX_HAS_ZZZ and then use a loop like this one in the XXXConfig.cmake file: foreach( component ${XXX_FIND_COMPONENTS} ) if ( XXX_HAS_${component}) set ( XXX_${component}_FOUND TRUE ) else( XXX_HAS_${component}) if ( ${XXX_FIND_REQUIRED}) message(FATAL_ERROR Required component ${component} not found!) elseif ( NOT XXX_FIND_QUIETLY) message(STATUS Component ${component} not found!) endif ( ${XXX_FIND_REQUIRED}) endif ( XXX_HAS_${component}) endforeach( component ) Correct? While that's a possible approach it lacks the invocation-specific variables, i.e. XXX_{INCLUDE_DIRS,LIBRARIES,DEFINITIONS}, and in some cases, these can't be assembled in a simple component-wise manner, see below. Moreover, there are further questions w.r.t. multi-component packages and their config files: Does this mean that XXX_LIBRARIES etc. should normally incorporate the settings for the components as well? [...] Yes, of course, if FIND_PACKAGE(XXX ...) returns successfully one would expect XXX_LIBRARIES to hold all libraries necessary to link against in order to use all components enabled by the FIND_PACKAGE() invocation, i.e. the libraries provided by the components themselves as well as their prerequisites. [...] IMO this can't work if you call find_package several times with different components. [...] This is one of those questions to deal with when it comes to multi- component packages: Does FIND_PACKAGE(XXX ...) act accumulatively? [...] Also, this would make it impossible to link to the base library alone, i.e. without the components... One might consider the base library as a component by itself, perhaps enabled automatically by resolving inter-component dependencies. As an alternative, one could a priori populate XXX_LIBRARIES et al. with the base library stuff and add the components' contributions as required. Furthermore, a package doesn't need to have a dedicated base library, e.g. Boost hasn't, and if you don't specify any components the Boost_LIBRARIES variable remains empty. - Does the config file provide the component-specific variables like XXX_YYY_FOUND for each available component or for the requested ones only, i.e. can you rely on XXX_ZZZ_FOUND to have a definite value if you just said FIND_PACKAGE(XXX COMPONENTS YYY)? With your foregoing approach, you can't. That's alright, but should be mentioned in the package's documentation. Imagine the following scenario: There's one installation of XXX for the native system and another one for cross compiling purposes. The latter has YYY and ZZZ while the former has YYY only. Due to FIND_PACKAGE()'s ability to search for config files in various locations, such a coexistence is easily possible. Now, a FIND_PACKAGE(XXX COMPONENTS YYY ZZZ) for the cross compilation XXX returns with XXX_ZZZ_FOUND=TRUE, but does a subsequent invocation of FIND_PACKAGE(XXX COMPONENTS YYY) within the same scope for the native XXX return with XXX_ZZZ_FOUND=FALSE, or does XXX_ZZZ_FOUND=TRUE still hold from the previous invocation? Both alternatives are fine, but the user should know the score. Thanks, I hadn't thought of this. So the code-snippet above should contain a set ( XXX_${component}_FOUND ${component}-NOTFOUND ). Yes, one would expect that FOUND variables for requested components receive defined values in all cases - positive as well as negative. Besides, it's a good style to refer to any component-related variables only if the particular component has been requested explicitly. Ok, so a better style would be to only set the XXX_HAS_* variables at first (maybe unsetting them at the end of the config file?), and then to conditionally set the XXX_YYY_INCLUDE_DIRS etc. if XXX_YYY_FOUND is true. Here, I meant it is a good *user* style to rely only on variables related to explicitly requested components; maybe a bit ambiguous. - Handling of inter-component dependencies: Imagine the user just says FIND_PACKAGE(XXX COMPONENTS ZZZ), but ZZZ needs YYY. If YYY is to be enabled automatically the config file must know about the dependency and cannot simply add the ZZZ-specific variables to the invocation- specific ones; the YYY-specific variables must be mentioned, too. I don't really see this as a problem. Although the code at hand lacks support for this kind of dependencies, in most cases you won't need it. And if you as the config file writer
Re: [CMake] providing library information, what's the cmake way
On 11/30/2010 at 11:39, Michael Hertling mhertl...@online.de wrote: Does this mean that XXX_LIBRARIES etc. should normally incorporate the settings for the components as well? [...] Yes, of course, if FIND_PACKAGE(XXX ...) returns successfully one would expect XXX_LIBRARIES to hold all libraries necessary to link against in order to use all components enabled by the FIND_PACKAGE() invocation, i.e. the libraries provided by the components themselves as well as their prerequisites. About that one would expect: I would be rather stumped and scratching my head if I saw this behaviour. But I'll get to that below... [...] IMO this can't work if you call find_package several times with different components. [...] This is one of those questions to deal with when it comes to multi- component packages: Does FIND_PACKAGE(XXX ...) act accumulatively? Yes. Again, for a detailed explanation see below... [...] Also, this would make it impossible to link to the base library alone, i.e. without the components... One might consider the base library as a component by itself, perhaps enabled automatically by resolving inter-component dependencies. As an alternative, one could a priori populate XXX_LIBRARIES et al. with the base library stuff and add the components' contributions as required. Furthermore, a package doesn't need to have a dedicated base library, e.g. Boost hasn't, and if you don't specify any components the Boost_LIBRARIES variable remains empty. Which is to be expected, given that Boost is mostly a headers-only library. Still, after your find_package call for Boost alone, you can use all Boost core libraries. -- Johannes Zarl Virtual Reality Services Johannes Kepler University Informationsmanagement Altenbergerstrasze 69 4040 Linz, Austria Phone: +43 732 2468-8321 johannes.z...@jku.at http://vrc.zid.jku.at - Handling of inter-component dependencies: Imagine the user just says FIND_PACKAGE(XXX COMPONENTS ZZZ), but ZZZ needs YYY. If YYY is to be enabled automatically the config file must know about the dependency and cannot simply add the ZZZ-specific variables to the invocation- specific ones; the YYY-specific variables must be mentioned, too. I don't really see this as a problem. Although the code at hand lacks support for this kind of dependencies, in most cases you won't need it. And if you as the config file writer need it, you obviously know you have dependencies and that you have to write code supporting those dependencies. Usually, handling of such dependencies means enabling some components the user hasn't requested explicitly, so it's quite straight forward, in fact. However, I've mentioned these dependencies to point out that the invocation-specific variables like XXX_LIBRARIES sometimes can't be assembled by a simple iteration over XXX_FIND_COMPONENTS; instead, the dependencies must be resolved first. BTW, do you know an example with a component A depending on B only if C is enabled? ;) No, but you are posing questions that make my head hurt (in a good-ish way ;-) - Do multiple consecutive FIND_PACKAGE(XXX ...) invocations act in an accumulative manner on the invocation-specific variables? Generally speaking, I would say: yes. At least this is the way of the least surprise for the user, as in sufficiently complex projects a package may be included at different places with different arguments. For the same reason, I'd tend to the opposite; look at the following: FIND_PACKAGE(XXX COMPONENTS YYY) ... ADD_SUBDIRECTORY(subdir) In subdir/CMakeLists.txt: FIND_PACKAGE(XXX COMPONENTS ZZZ) ... TARGET_LINK_LIBRARIES(... ${XXX_LIBRARIES}) Here, the target is also linked against XXX_YYY_LIBRARY as the latter is inherited via XXX_LIBRARIES from the parent directory, but if the target only needs XXX_ZZZ_LIBRARY it will possibly be overlinked. Although this can be avoided by resetting XXX_LIBRARIES before each FIND_PACKAGE() invocation, I don't think that's the way one would like to go. IMO, the invocation-specific results of any FIND_PACKAGE() call should depend solely on the parameters passed in and the well-known variables like CMAKE_PREFIX_PATH. The downside is that one must possibly process or save the results before they could be overwritten, e.g.: FIND_PACKAGE(XXX REQUIRED YYY) SET(LIBRARIES ${XXX_LIBRARIES}) FIND_PACKAGE(XXX COMPONENTS ZZZ) LIST(APPEND LIBRARIES ${XXX_LIBRARIES}) ... TARGET_LINK_LIBRARIES(... ${LIBRARIES}) Since such related calls to FIND_PACKAGE(XXX ...) usually occur nearby each other within the same CMakeLists.txt, this little penalty should be acceptable whereas accumulated XXX_LIBRARIES and the like may have far reaching and surprising effects, especially in complex projects. Funny enough, my example is almost the same: FIND_PACKAGE(XXX COMPONENTS YYY) ... ADD_SUBDIRECTORY(subdir) ... TARGET_LINK_LIBRARIES(AAA ${XXX_LIBRARIES}) TARGET_LINK_LIBRARIES(BBB
Re: [CMake] providing library information, what's the cmake way
Sorry for the late response, but your mail was simply to long for a swift response... On 11/26/2010 at 05:47, Michael Hertling mhertl...@online.de wrote: On 11/24/2010 04:51 PM, Johannes Zarl wrote: About the components question again: I played around a bit, and I think I now more or less have comprehended this. I guess for a package XXX with components YYY and ZZZ, one could set variables XXX_HAS_YYY and XXX_HAS_ZZZ and then use a loop like this one in the XXXConfig.cmake file: foreach( component ${XXX_FIND_COMPONENTS} ) if ( XXX_HAS_${component}) set ( XXX_${component}_FOUND TRUE ) else( XXX_HAS_${component}) if ( ${XXX_FIND_REQUIRED}) message(FATAL_ERROR Required component ${component} not found!) elseif ( NOT XXX_FIND_QUIETLY) message(STATUS Component ${component} not found!) endif ( ${XXX_FIND_REQUIRED}) endif ( XXX_HAS_${component}) endforeach( component ) Correct? While that's a possible approach it lacks the invocation-specific variables, i.e. XXX_{INCLUDE_DIRS,LIBRARIES,DEFINITIONS}, and in some cases, these can't be assembled in a simple component-wise manner, see below. Moreover, there are further questions w.r.t. multi-component packages and their config files: Does this mean that XXX_LIBRARIES etc. should normally incorporate the settings for the components as well? IMO this can't work if you call find_package several times with different components. Also, this would make it impossible to link to the base library alone, i.e. without the components... - Does the config file provide the component-specific variables like XXX_YYY_FOUND for each available component or for the requested ones only, i.e. can you rely on XXX_ZZZ_FOUND to have a definite value if you just said FIND_PACKAGE(XXX COMPONENTS YYY)? With your foregoing approach, you can't. That's alright, but should be mentioned in the package's documentation. Imagine the following scenario: There's one installation of XXX for the native system and another one for cross compiling purposes. The latter has YYY and ZZZ while the former has YYY only. Due to FIND_PACKAGE()'s ability to search for config files in various locations, such a coexistence is easily possible. Now, a FIND_PACKAGE(XXX COMPONENTS YYY ZZZ) for the cross compilation XXX returns with XXX_ZZZ_FOUND=TRUE, but does a subsequent invocation of FIND_PACKAGE(XXX COMPONENTS YYY) within the same scope for the native XXX return with XXX_ZZZ_FOUND=FALSE, or does XXX_ZZZ_FOUND=TRUE still hold from the previous invocation? Both alternatives are fine, but the user should know the score. Thanks, I hadn't thought of this. So the code-snippet above should contain a set ( XXX_${component}_FOUND ${component}-NOTFOUND ). Besides, it's a good style to refer to any component-related variables only if the particular component has been requested explicitly. Ok, so a better style would be to only set the XXX_HAS_* variables at first (maybe unsetting them at the end of the config file?), and then to conditionally set the XXX_YYY_INCLUDE_DIRS etc. if XXX_YYY_FOUND is true. - Handling of inter-component dependencies: Imagine the user just says FIND_PACKAGE(XXX COMPONENTS ZZZ), but ZZZ needs YYY. If YYY is to be enabled automatically the config file must know about the dependency and cannot simply add the ZZZ-specific variables to the invocation- specific ones; the YYY-specific variables must be mentioned, too. I don't really see this as a problem. Although the code at hand lacks support for this kind of dependencies, in most cases you won't need it. And if you as the config file writer need it, you obviously know you have dependencies and that you have to write code supporting those dependencies. Update/FYI: I just tried tried to write generic code to deal with dependencies, and its not as straightforward as I thought it is. Assuming that there are no circular dependencies, you could recursively add the dependencies to the XXX_FIND_COMPONENTS variable and remove the duplicates afterwards. Then you can use the above code to set XXX_*_FOUND, and afterwards, you have to recursively add the libraries/defines/include_dirs of the depended upon components to each component's includes (this is the tricky part IMO). I guess it is far easier to write this in a non-generic way... - Do multiple consecutive FIND_PACKAGE(XXX ...) invocations act in an accumulative manner on the invocation-specific variables? Generally speaking, I would say: yes. At least this is the way of the least surprise for the user, as in sufficiently complex projects a package may be included at different places with different arguments. FIND_PACKAGE(XXX REQUIRED YYY) FIND_PACKAGE(XXX COMPONENTS ZZZ) Ah, this is how it's done. I was wondering why a call like find_package(XXX COMPONENTS ZZZ REQUIRED YYY) sets both XXX_YYY_REQUIRED and XXX_ZZZ_REQUIRED. When turning towards find modules, the
Re: [CMake] providing library information, what's the cmake way
On 11/29/2010 at 14:28, Johannes Zarl johannes.z...@jku.at wrote: On 11/26/2010 at 05:47, Michael Hertling mhertl...@online.de wrote: See [1] for a former discussion of several aspects regarding multi-component packages. [...] [1] http://www.mail-archive.com/cmake@cmake.org/msg28431.html Looks interesting. I will have to read that discussion... Ok. Now I that I have read that whole thread, I think I more or less agree with you, Michael. Also, I've found this mail from Brad King quite informative: http://www.mail-archive.com/cmake@cmake.org/msg28666.html Have a nice evening, Johannes -- Johannes Zarl Virtual Reality Services Johannes Kepler University Informationsmanagement Altenbergerstrasze 69 4040 Linz, Austria Phone: +43 732 2468-8321 johannes.z...@jku.at http://vrc.zid.jku.at ___ 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] providing library information, what's the cmake way
On Tuesday 23 Nov 2010 5:27:56 pm Johannes Zarl wrote: Another somehow related topic seems to be import/export of targets. Should a LibraryConfig.cmake or FindLibrary.cmake file create imported targets for the library? Thanks for this thread. It has helped. However, i am still not clear about the use of the export/import feature. I thought that libraries built with cmake would not need to write their Find*.cmake or *Config.cmake modules as they could simply use the EXPORT feature. It would be really helpful if someone could explain the proper use of these features. And is there any documentation on how to create a LibraryConfig.cmake file with support for components? -- Cheers! Kishore ___ 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] providing library information, what's the cmake way
On 25-11-2010 at 17:34, in message 201011251734.55788.johannes.z...@jku.at, Johannes Zarl johannes.z...@jku.at wrote: I took the liberty and compiled such a compatibility matrix here: http://www.cmake.org/Wiki/CMake_Version_Compatibility_Matrix It's a draft and does not (yet) contain information about properties and variables, but if this idea receives general consent I could complete the information. What do you think? Is this worth the effort, or would no one ever bother to update the information? NICE !! I think this is really handy and definitely worth the effort. However, how's keeping http://www.cmake.org/Wiki/CMake_Released_Versions up-to-date? Since, you're matrix is just a user-friendly representation of that information. 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] providing library information, what's the cmake way
2010/11/25 Johannes Zarl johannes.z...@jku.at: On Wednesday 24 November 2010 19:03:21 David Cole wrote: On Wed, Nov 24, 2010 at 12:58 PM, Tyler Roscoe ty...@cryptio.net wrote: On Wed, Nov 24, 2010 at 11:41:46AM -0500, David Cole wrote: On Wed, Nov 24, 2010 at 11:34 AM, Rolf Eike Beer e...@sf-mail.de wrote: So I think it is _really_ necessary to go through all the CMake documentation items and add a line about when which feature was added. Adding that information in the documentation would be good, I agree. (Although quite time consuming and costly for somebody...) Perhaps a good compromise is simply to add version information to all new CMake commands/variables/properties that are added henceforth? Thanks, tyler That does sound like a good idea. From the information in http://www.cmake.org/Wiki/CMake_Released_Versions and using some shell-scripts to create the diffs between all neighbor-versions, it's not too much work to create a compatibility matrix for the documented features. May be it can be fully automated suche that adding a column for each new CMake release would take minimum time? I took the liberty and compiled such a compatibility matrix here: http://www.cmake.org/Wiki/CMake_Version_Compatibility_Matrix It's a draft and does not (yet) contain information about properties and variables, but if this idea receives general consent I could complete the information. What do you think? Is this worth the effort, or would no one ever bother to update the information? I like it too, I think it's very handy. Concerning the update I think I will be done (and I may help) if some scripts pre-digest the informations to be laid out. -- Erk Membre de l'April - « promouvoir et défendre le logiciel libre » - http://www.april.org ___ 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] providing library information, what's the cmake way
On Friday 26 November 2010 10:49:01 Eric Noulard wrote: From the information in http://www.cmake.org/Wiki/CMake_Released_Versions and using some shell-scripts to create the diffs between all neighbor-versions, it's not too much work to create a compatibility matrix for the documented features. May be it can be fully automated suche that adding a column for each new CMake release would take minimum time? Unfortunately, I don't think that's possible. After all, the information has to be gathered comparing the textual output of cmake --help-full. While most differences are pretty straightforward to interpret (at least for a human reader), sometimes the documentation changes and you really have to read the different versions and decide if there really was a change in behaviour, or if it's just a documentation change. I took the liberty and compiled such a compatibility matrix here: http://www.cmake.org/Wiki/CMake_Version_Compatibility_Matrix It's a draft and does not (yet) contain information about properties and variables, but if this idea receives general consent I could complete the information. What do you think? Is this worth the effort, or would no one ever bother to update the information? I like it too, I think it's very handy. Concerning the update I think I will be done (and I may help) if some scripts pre-digest the informations to be laid out. I don't have any time for this matter before next Thursday, but regarding the positive reactions on this list I will certainly complete the matrix. Eric: I can send you the shell-scripts if you want to have a look... Have a nice weekend, Johannes ___ 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] providing library information, what's the cmake way
On 24-11-2010 at 17:34, in message ddc068a445e2cc6dcf015e9b84217da0.squir...@webmail.sf-mail.de, Rolf Eike Beer e...@sf-mail.de wrote: On Wed, Nov 24, 2010 at 6:57 AM, Rolf Eike Beer e...@sf-mail.de wrote: In KDE we have a macro MACRO_WRITE_BASIC_CMAKE_VERSION_FILE() which helps with creating a basic version-info file which should be installed along with the Config-file. It consists of MacroWriteBasicCMakeVersionFile.cmake and BasicFindPackageVersion.cmake.in which you can find in http://websvn.kde.org/trunk/KDE/kdelibs/cmake/modules/ . I wonder why you use get_filename_component(_currentListFileDir ${CMAKE_CURRENT_LIST_FILE} PATH) in there instead of CMAKE_CURRENT_LIST_DIR. Probably because CMAKE_CURRENT_LIST_DIR was just invented and is only in CMake 2.8.3... get_filename_component works with several versions of CMake, and does not require 2.8.3 or later. So I think it is _really_ necessary to go through all the CMake documentation items and add a line about when which feature was added. Everyone looks into his local CMake documentation and uses what he finds in there. And then it breaks on older versions. You currently have no chance to know what works but to install all older versions and do a binary search in the documentation. That simply does not scale. Eike That's what CMAKE_MINIMUM_REQUIRED() is for. If you're developing with CMake 2.8.2, and you want to make sure that you don't use any features that are not supported by CMake prior to version 2.8.2, you should put this at the top of your CMakeLists.txt file: CMAKE_MINIMUM_REQUIRED(VERSION 2.8.2) But you do have a point. It would really help people developing CMake files to know whether they can use a given command or not if they want to support, say, CMake 2.6.0. To be honest, the people at Kitware don't make that an easy job, because almost every patch-release contains new features :-( 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] providing library information, what's the cmake way
2010/11/25 Marcel Loose lo...@astron.nl: Everyone looks into his local CMake documentation and uses what he finds in there. And then it breaks on older versions. You currently have no chance to know what works but to install all older versions and do a binary search in the documentation. That simply does not scale. Eike That's what CMAKE_MINIMUM_REQUIRED() is for. If you're developing with CMake 2.8.2, and you want to make sure that you don't use any features that are not supported by CMake prior to version 2.8.2, you should put this at the top of your CMakeLists.txt file: CMAKE_MINIMUM_REQUIRED(VERSION 2.8.2) Unless I'm wrong this is NOT ensuring what you said. This statement will make CMake shout at you if you try to use CMake version less than the specified version: If the current version of CMake is lower than that required it will stop processing the project and report an error. When a version higher than 2.4 is specified the command implicitly invokes cmake_policy(VERSION major[.minor[.patch]]) which sets the cmake policy version level to the version specified. When version 2.4 or lower is given the command implicitly invokes so the minimum required version is checked and the corrresponding policy is enforced. BUT... this does NOT ensure that while requiring minimum 2.8.2 and you are currently using 2.8.3 (or any later version) your 2.8.3 will behave as if it was 2.8.2. If a new CMake command and/or option for an existing command has been added between 2.8.2 and 2.8.3 but is not subject to some policy then if you use it you won't get a warning. but you'll break your user using CMake 2.8.2. I think that's why Dave said: If you want to support CMake 2.6.4 (or whatever previous version you require, for whatever reason), then you should be using *that* version for your local development, and have that be the cmake_minimum_required version. And use that version to look up documentation... But you do have a point. It would really help people developing CMake files to know whether they can use a given command or not if they want to support, say, CMake 2.6.0. Thus my proposal based on Tyler idea to attach a list of version to each CMake command/variables/properties which contains the first CMake version which included the feature followed by the list of CMake version which modified the behavior/feature. To be honest, the people at Kitware don't make that an easy job, because almost every patch-release contains new features :-( May be they are too-responsive to user request :-] -- Erk Membre de l'April - « promouvoir et défendre le logiciel libre » - http://www.april.org ___ 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] providing library information, what's the cmake way
On Wednesday 24 November 2010 19:03:21 David Cole wrote: On Wed, Nov 24, 2010 at 12:58 PM, Tyler Roscoe ty...@cryptio.net wrote: On Wed, Nov 24, 2010 at 11:41:46AM -0500, David Cole wrote: On Wed, Nov 24, 2010 at 11:34 AM, Rolf Eike Beer e...@sf-mail.de wrote: So I think it is _really_ necessary to go through all the CMake documentation items and add a line about when which feature was added. Adding that information in the documentation would be good, I agree. (Although quite time consuming and costly for somebody...) Perhaps a good compromise is simply to add version information to all new CMake commands/variables/properties that are added henceforth? Thanks, tyler That does sound like a good idea. From the information in http://www.cmake.org/Wiki/CMake_Released_Versions and using some shell-scripts to create the diffs between all neighbor-versions, it's not too much work to create a compatibility matrix for the documented features. I took the liberty and compiled such a compatibility matrix here: http://www.cmake.org/Wiki/CMake_Version_Compatibility_Matrix It's a draft and does not (yet) contain information about properties and variables, but if this idea receives general consent I could complete the information. What do you think? Is this worth the effort, or would no one ever bother to update the information? cheers, Johannes ___ 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] providing library information, what's the cmake way
On Thursday 25 November 2010, Johannes Zarl wrote: On Wednesday 24 November 2010 19:03:21 David Cole wrote: On Wed, Nov 24, 2010 at 12:58 PM, Tyler Roscoe ty...@cryptio.net wrote: On Wed, Nov 24, 2010 at 11:41:46AM -0500, David Cole wrote: On Wed, Nov 24, 2010 at 11:34 AM, Rolf Eike Beer e...@sf-mail.de wrote: So I think it is _really_ necessary to go through all the CMake documentation items and add a line about when which feature was added. Adding that information in the documentation would be good, I agree. (Although quite time consuming and costly for somebody...) Perhaps a good compromise is simply to add version information to all new CMake commands/variables/properties that are added henceforth? Thanks, tyler That does sound like a good idea. From the information in http://www.cmake.org/Wiki/CMake_Released_Versions and using some shell-scripts to create the diffs between all neighbor-versions, it's not too much work to create a compatibility matrix for the documented features. I took the liberty and compiled such a compatibility matrix here: http://www.cmake.org/Wiki/CMake_Version_Compatibility_Matrix It's a draft and does not (yet) contain information about properties and variables, but if this idea receives general consent I could complete the information. What do you think? Is this worth the effort, or would no one ever bother to update the information? I think it's cool :-) I for one update the http://www.cmake.org/Wiki/CMake_Released_Versions page manually after each release. 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] providing library information, what's the cmake way
On 11/24/2010 04:51 PM, Johannes Zarl wrote: Hi, On 11/23/2010 at 21:25, Alexander Neundorf a.neundorf-w...@gmx.net wrote: CMAKE_MODULE_PATH is only for finding Find-modules, not for finding the actual packages or Config-files. For that you can set CMAKE_PREFIX_PATH. CMake uses each directory contained in CMAKE_PREFIX_PATH for all its find_program/file/path/library/package() calls to search in the respective subdirectories for the executables/files/libraries/Config-files. Thanks for this information! Knowing this greatly simplifies the whole find_package stuff... And is there any documentation on how to create a LibraryConfig.cmake file with support for components? In KDE we have a macro MACRO_WRITE_BASIC_CMAKE_VERSION_FILE() which helps with creating a basic version-info file which should be installed along with the Config-file. It consists of MacroWriteBasicCMakeVersionFile.cmake and BasicFindPackageVersion.cmake.in which you can find in http://websvn.kde.org/trunk/KDE/kdelibs/cmake/modules/ . Nice to have some reusable code for versioning... About the components question again: I played around a bit, and I think I now more or less have comprehended this. I guess for a package XXX with components YYY and ZZZ, one could set variables XXX_HAS_YYY and XXX_HAS_ZZZ and then use a loop like this one in the XXXConfig.cmake file: foreach( component ${XXX_FIND_COMPONENTS} ) if ( XXX_HAS_${component}) set ( XXX_${component}_FOUND TRUE ) else( XXX_HAS_${component}) if ( ${XXX_FIND_REQUIRED}) message(FATAL_ERROR Required component ${component} not found!) elseif ( NOT XXX_FIND_QUIETLY) message(STATUS Component ${component} not found!) endif ( ${XXX_FIND_REQUIRED}) endif ( XXX_HAS_${component}) endforeach( component ) Correct? While that's a possible approach it lacks the invocation-specific variables, i.e. XXX_{INCLUDE_DIRS,LIBRARIES,DEFINITIONS}, and in some cases, these can't be assembled in a simple component-wise manner, see below. Moreover, there are further questions w.r.t. multi-component packages and their config files: - Does the config file provide the component-specific variables like XXX_YYY_FOUND for each available component or for the requested ones only, i.e. can you rely on XXX_ZZZ_FOUND to have a definite value if you just said FIND_PACKAGE(XXX COMPONENTS YYY)? With your foregoing approach, you can't. That's alright, but should be mentioned in the package's documentation. Imagine the following scenario: There's one installation of XXX for the native system and another one for cross compiling purposes. The latter has YYY and ZZZ while the former has YYY only. Due to FIND_PACKAGE()'s ability to search for config files in various locations, such a coexistence is easily possible. Now, a FIND_PACKAGE(XXX COMPONENTS YYY ZZZ) for the cross compilation XXX returns with XXX_ZZZ_FOUND=TRUE, but does a subsequent invocation of FIND_PACKAGE(XXX COMPONENTS YYY) within the same scope for the native XXX return with XXX_ZZZ_FOUND=FALSE, or does XXX_ZZZ_FOUND=TRUE still hold from the previous invocation? Both alternatives are fine, but the user should know the score. Besides, it's a good style to refer to any component-related variables only if the particular component has been requested explicitly. - Handling of inter-component dependencies: Imagine the user just says FIND_PACKAGE(XXX COMPONENTS ZZZ), but ZZZ needs YYY. If YYY is to be enabled automatically the config file must know about the dependency and cannot simply add the ZZZ-specific variables to the invocation- specific ones; the YYY-specific variables must be mentioned, too. - Do multiple consecutive FIND_PACKAGE(XXX ...) invocations act in an accumulative manner on the invocation-specific variables? E.g., does FIND_PACKAGE(XXX COMPONENTS YYY) FIND_PACKAGE(XXX COMPONENTS ZZZ) result in XXX_LIBRARIES=${XXX_YYY_LIBRARY} ${XXX_ZZZ_LIBRARY}, or does the second invocation overwrite the results of the first? Again, both alternatives are fine, but should be documented. That's important when there are required and optional components to handle: Imagine YYY is required while ZZZ is optional for the user; one might tend to say FIND_PACKAGE(XXX REQUIRED YYY) FIND_PACKAGE(XXX COMPONENTS ZZZ) instead of FIND_PACKAGE(XXX COMPONENTS YYY ZZZ) IF(NOT XXX_YYY_FOUND) MESSAGE(FATAL_ERROR ...) ENDIF() When turning towards find modules, the situation becomes even more complicated. From a user's perspective, find modules and config files should behave the same, but the formers can't know which components are available, so they must look for them; this gives rise to questions like: - Meaning of the REQUIRED and QUIET options: When a find module looks for any component the effects of REQUIRED and QUIET depend on whether the component has been requested explicitly or not. If it hasn't, the find module mustn't bail out if the component
Re: [CMake] providing library information, what's the cmake way
In KDE we have a macro MACRO_WRITE_BASIC_CMAKE_VERSION_FILE() which helps with creating a basic version-info file which should be installed along with the Config-file. It consists of MacroWriteBasicCMakeVersionFile.cmake and BasicFindPackageVersion.cmake.in which you can find in http://websvn.kde.org/trunk/KDE/kdelibs/cmake/modules/ . I wonder why you use get_filename_component(_currentListFileDir ${CMAKE_CURRENT_LIST_FILE} PATH) in there instead of CMAKE_CURRENT_LIST_DIR. Eike ___ 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] providing library information, what's the cmake way
On Wed, Nov 24, 2010 at 6:57 AM, Rolf Eike Beer e...@sf-mail.de wrote: In KDE we have a macro MACRO_WRITE_BASIC_CMAKE_VERSION_FILE() which helps with creating a basic version-info file which should be installed along with the Config-file. It consists of MacroWriteBasicCMakeVersionFile.cmake and BasicFindPackageVersion.cmake.in which you can find in http://websvn.kde.org/trunk/KDE/kdelibs/cmake/modules/ . I wonder why you use get_filename_component(_currentListFileDir ${CMAKE_CURRENT_LIST_FILE} PATH) in there instead of CMAKE_CURRENT_LIST_DIR. Eike ___ 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 Probably because CMAKE_CURRENT_LIST_DIR was just invented and is only in CMake 2.8.3... get_filename_component works with several versions of CMake, and does not require 2.8.3 or later. ___ 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] providing library information, what's the cmake way
On Wed, Nov 24, 2010 at 6:57 AM, Rolf Eike Beer e...@sf-mail.de wrote: In KDE we have a macro MACRO_WRITE_BASIC_CMAKE_VERSION_FILE() which helps with creating a basic version-info file which should be installed along with the Config-file. It consists of MacroWriteBasicCMakeVersionFile.cmake and BasicFindPackageVersion.cmake.in which you can find in http://websvn.kde.org/trunk/KDE/kdelibs/cmake/modules/ . I wonder why you use get_filename_component(_currentListFileDir ${CMAKE_CURRENT_LIST_FILE} PATH) in there instead of CMAKE_CURRENT_LIST_DIR. Probably because CMAKE_CURRENT_LIST_DIR was just invented and is only in CMake 2.8.3... get_filename_component works with several versions of CMake, and does not require 2.8.3 or later. So I think it is _really_ necessary to go through all the CMake documentation items and add a line about when which feature was added. Everyone looks into his local CMake documentation and uses what he finds in there. And then it breaks on older versions. You currently have no chance to know what works but to install all older versions and do a binary search in the documentation. That simply does not scale. Eike ___ 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] providing library information, what's the cmake way
On Wed, Nov 24, 2010 at 11:34 AM, Rolf Eike Beer e...@sf-mail.de wrote: On Wed, Nov 24, 2010 at 6:57 AM, Rolf Eike Beer e...@sf-mail.de wrote: In KDE we have a macro MACRO_WRITE_BASIC_CMAKE_VERSION_FILE() which helps with creating a basic version-info file which should be installed along with the Config-file. It consists of MacroWriteBasicCMakeVersionFile.cmake and BasicFindPackageVersion.cmake.in which you can find in http://websvn.kde.org/trunk/KDE/kdelibs/cmake/modules/ . I wonder why you use get_filename_component(_currentListFileDir ${CMAKE_CURRENT_LIST_FILE} PATH) in there instead of CMAKE_CURRENT_LIST_DIR. Probably because CMAKE_CURRENT_LIST_DIR was just invented and is only in CMake 2.8.3... get_filename_component works with several versions of CMake, and does not require 2.8.3 or later. So I think it is _really_ necessary to go through all the CMake documentation items and add a line about when which feature was added. Everyone looks into his local CMake documentation and uses what he finds in there. And then it breaks on older versions. You currently have no chance to know what works but to install all older versions and do a binary search in the documentation. That simply does not scale. Eike ___ 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 Adding that information in the documentation would be good, I agree. (Although quite time consuming and costly for somebody...) But the best practice should be this: If you are using CMake 2.8.3 exclusively to develop features in your source tree's CMakeLists files (or included .cmake scripts) then you need to say cmake_minimum_required(VERSION 2.8.3) just to be on the safe side. If you want to support CMake 2.6.4 (or whatever previous version you require, for whatever reason), then you should be using *that* version for your local development, and have that be the cmake_minimum_required version. And use that version to look up documentation... David ___ 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] providing library information, what's the cmake way
On Wed, Nov 24, 2010 at 11:41:46AM -0500, David Cole wrote: On Wed, Nov 24, 2010 at 11:34 AM, Rolf Eike Beer e...@sf-mail.de wrote: So I think it is _really_ necessary to go through all the CMake documentation items and add a line about when which feature was added. Adding that information in the documentation would be good, I agree. (Although quite time consuming and costly for somebody...) Perhaps a good compromise is simply to add version information to all new CMake commands/variables/properties that are added henceforth? Thanks, tyler ___ 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] providing library information, what's the cmake way
On Wed, Nov 24, 2010 at 12:58 PM, Tyler Roscoe ty...@cryptio.net wrote: On Wed, Nov 24, 2010 at 11:41:46AM -0500, David Cole wrote: On Wed, Nov 24, 2010 at 11:34 AM, Rolf Eike Beer e...@sf-mail.de wrote: So I think it is _really_ necessary to go through all the CMake documentation items and add a line about when which feature was added. Adding that information in the documentation would be good, I agree. (Although quite time consuming and costly for somebody...) Perhaps a good compromise is simply to add version information to all new CMake commands/variables/properties that are added henceforth? Thanks, tyler That does sound like a good idea. ___ 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] providing library information, what's the cmake way
2010/11/24 David Cole david.c...@kitware.com: On Wed, Nov 24, 2010 at 12:58 PM, Tyler Roscoe ty...@cryptio.net wrote: On Wed, Nov 24, 2010 at 11:41:46AM -0500, David Cole wrote: On Wed, Nov 24, 2010 at 11:34 AM, Rolf Eike Beer e...@sf-mail.de wrote: So I think it is _really_ necessary to go through all the CMake documentation items and add a line about when which feature was added. Adding that information in the documentation would be good, I agree. (Although quite time consuming and costly for somebody...) Perhaps a good compromise is simply to add version information to all new CMake commands/variables/properties that are added henceforth? Thanks, tyler That does sound like a good idea. +1 for this, even if it does not solve all evolution problem like when IF command was added the IF(TARGET ...) or IF(POLICY ...) I don't remember when (may the 2.4 -- 2.6 switch) basically IF command existed before and after the evolution but its capability was enhanced. May be adding a list of version for each command may be covering this like IF -- start, 2.4.8, 2.6.2, 2.8.3 meaning that IF command was there since start and evolved in 2.4.8, 2.6.2, 2.8.3 releases. If ones want to know the difference one can go and pick up each such release in order to generate documentation diff. May looks fancy but not knowing that command has not all the feature it currently has is interesting too. Note with that kind of list I can automatically generate a per-command diff of documentation using my private CMake binary collection :-] -- Erk Membre de l'April - « promouvoir et défendre le logiciel libre » - http://www.april.org ___ 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] providing library information, what's the cmake way
Sorry for hijacking this thread, but I'm wondering about this for some time, too. (And the information in the doc/wiki is somewhat dated and/or ambiguous [1,2,3,4]). I will just go on and write my thoughts and what I (think I) know, in the hope that somebody corrects those things I got wrong. So summarizing the previous mesage in the thread, one can say: + cmake aware packages should provide LibraryConfig.cmake scripts (and optionally LibraryVersion.cmake scrips), just like they would provide pkg-config files. + developers should create FindLibrary.cmake scripts for packages they are using that are not cmake aware. I think that information should be transported more clearly, because in practice most cmake based software provides a FindLibrary.cmake file for itself. Also, I could not find a definitive answer on where these packages should put the LibraryConfig.cmake script. If I read the search paths in [1] correctly, the preferred paths are: + prefix/ on windows + prefix/(share|lib)/cmake/name*/ on linux, and + prefix/name.framework/Resources/ on Apple We have have every library and library-version in its own prefix and use shell modules[5] to provide the correct environment that a user wants. Is there any way to let cmake know about specific prefix directories it should be aware of? Unfortunately, the CMAKE_MODULE_PATH variable has to be manually set, and not influenced by the environment. Something like the PKG_CONFIG_PATH environment variable for pkg-config would be really nice to have in cmake. Another somehow related topic seems to be import/export of targets. Should a LibraryConfig.cmake or FindLibrary.cmake file create imported targets for the library? And is there any documentation on how to create a LibraryConfig.cmake file with support for components? Cheers, Johannes [1] http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:find_package [2] http://www.cmake.org/Wiki/CMake_HowToFindInstalledSoftware [3] http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries [4] http://www.cmake.org/Wiki/CMake:Improving_Find*_Modules [5] http://modules.sourceforge.net/ -- Johannes Zarl Virtual Reality Services Johannes Kepler University Informationsmanagement Altenbergerstrasze 69 4040 Linz, Austria Phone: +43 732 2468-8321 johannes.z...@jku.at http://vrc.zid.jku.at ___ 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] providing library information, what's the cmake way
On Mon, Nov 22, 2010 at 10:37 PM, Michael Hertling mhertl...@online.de wrote: [snip] This seems like a common situation, so I'm wondering what the common solution is. 'hope that helps. Thanks, yes that helps a lot. I figured there must be some method like this. @Johannes Zarl: hijack away, I'm also interested in your questions. :) Ian ___ 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