On 09/19/2011 10:01 PM, Anton Deguet wrote: > Hi Michael, > > Sorry, I mistakenly trashed your previous answer, thank you for both replies. > > It looks like I am not the first one to raise that question. If I understand > well, the primary issue is to agree on the semantic of: > > find_package (xyz COMPONENTS c1 c2) > if (xyz_FOUND) …
Exactly. > > xyz_FOUND can mean: > - xyz has been found and since you asked for components c1 and c2, please > check the variables xyz_c1_FOUND and xyz_c2_FOUND to see if these components > are available > - xyz has been found along with c1 and c2 > > I would personally prefer the second approach as it makes it easy to test if > everything has been found as required. [...] Suppose c2 is missing but optional, i.e. you can successfully configure your project without it. What's the meaning of xyz_FOUND==FALSE/TRUE? xyz_FOUND==FALSE *because* c2 is requested but missing? xyz_FOUND==TRUE *although* c2 is missing but optional? IMO, both alternatives might be considered as justified, so the only unambiguous and caprice-free interpretation of xyz_FOUND for a multi- component package is the one finally agreed on in [1], i.e. xyz_FOUND must not comprise any of xyz's components. Note that the handling of optional components - along with required ones - must be dealt with for multi-component packages, but it doesn't raise issues in the single-component case. > [...] Maybe there is yet another variable to indicate that all components > have been found, say xyz_FOUND_AS_REQUIRED. That would allow users to write > simpler code: > > if (xyz_FOUND AND xyz_c1_FOUND AND xyz_c2_FOUND) > > would become: > > if (xyz_FOUND_AS_REQUIRED) > > Ultimately I will stick to the recommended approach. The same could be quite easily achieved with a supplementary function, say CHECK_PACKAGE_COMPONENTS(RESULT PACKAGE CMPNT1 CMPNT2 CMPNT3 ...): FIND_PACKAGE(xyz COMPONENTS c1 c2) CHECK_PACKAGE_COMPONENTS(xyz_c1_c2_FOUND xyz c1 c2) IF(xyz_c1_c2_FOUND) ... Basically, CHECK_PACKAGE_COMPONENTS() ANDs ${PACKAGE}_FOUND and ${PACKAGE}_${CMPNTi}_FOUND together and returns the result. This would also render a collective handling of required and optional components elegant and systematic: FIND_PACKAGE(xyz COMPONENTS req1 req2 req3 opt1 opt2 opt3) CHECK_PACKAGE_COMPONENTS(xyz_req_FOUND xyz req1 req2 req3) IF(NOT xyz_req_FOUND) MESSAGE(FATAL_ERROR ...) ELSE() FOREACH(i IN ITEMS opt1 opt2 opt3) CHECK_PACKAGE_COMPONENTS(xyz_opt${i}_FOUND xyz opt${i}) IF(xyz_opt${i}_FOUND) ... # enable optional component opt${i} ENDIF() ENDFOREACH() ENDIF() > The second aspect of the issue (and this is what I initially encountered) is > the different behavior of find_package for either a module find or a config > file. I wrote a CMake file/scripts that sets xyz_FOUND and used it for both > cases, i.e. installed it as either Findxyz.cmake or xyz-config.cmake. It was > a bit disconcerting to have my xyz_FOUND variable overwritten in one case and > not the other. [...] The bare essentials are that FIND_PACKAGE(xyz ...) must not behave differently w.r.t. module mode and config mode, i.e. the meaning of xyz_FOUND must be the same in both modes. Its meaning in config mode is clear and forced by FIND_PACKAGE(): Config file found ==> package found, i.e. xyz_FOUND==TRUE. The config file can not declare its own package as absent; this would not make any sense. While that's quite evident for single-component packages, it's the multi-component case which is complicating things, but the proper interpretation is quite clear, too: Config mode forces xyz_FOUND==TRUE if the config file is found, regardless which components are actually present, and module mode must follow, i.e. xyz_FOUND==FALSE if the package is not found at all, but else, don't rely on any component being present because of xyz_FOUND==TRUE. In other words: xyz_FOUND must not comprise components, that's the only interpretation which is consistent in all cases, IMO. > [...] I understand that this is strongly tied to the defined/accepted meaning > of xyz_FOUND and I was apparently mis-using it. But ... maybe … the > find_package could be slightly modified: > - send a warning to the user (developer message) if the variable xyz_FOUND is > modified/set by the file xyz-config.cmake > - more subtle and might have implications I don't foresee, if after loading > the file xyz-config.cmake find_package realizes that xyz_FOUND has been set, > let it as is. That would allow me to keep using xyz_FOUND incorrectly :-) What I'd really like to see rather than a modification of the - well designed - FIND_PACKAGE() function is a broad discussion about multi- component packages and their find modules and config files, ideally resulting in a reasonable consensus and official recommendations in Modules/readme.txt. Multi-component packages raise several issues that are unknown to single-component ones, and although there has been some discussions about this topic yet, cf. [2], the agreement on how to handle things properly seems to be quite weak within the CMake community. IMO, this is regrettable because many of the non- trivial packages are multi-component in nature; e.g., even a simple library package could be considered as consisting of the components "static" and "shared", which would terminate the regularly upcoming question how to find the static library instead of the usually pre- ferred shared one. > Again, thank you for your answer. > > Anton Regards, Michael [1] http://www.mail-archive.com/cmake@cmake.org/msg28431.html [2] http://www.mail-archive.com/cmake@cmake.org/msg32836.html > On Sep 19, 2011, at 2:21 PM, Michael Hertling wrote: > >> On 09/19/2011 07:09 PM, Anton Deguet wrote: >>> Hello, >>> >>> I haven't heard anything following my previous post. Is there any chance >>> someone could provide some guidance? >>> >>> Sincerely, >>> >>> Anton >>> >>> On Aug 29, 2011, at 6:02 PM, Anton Deguet wrote: >>> >>>> Hello, >>>> >>>> I am trying to use the following syntax: >>>> find_package (xyz REQUIRED xyz1 xyz2) using a config file, i.e. NOT >>>> Findxyz.cmake. >>>> >>>> I have a file named xyz-config.cmake that contains some code to check if >>>> the required components are available or not (based on how xyz was >>>> compiled). Ideally I would like the find_package command to set xyz_FOUND >>>> to false if: >>>> - xyz-config.cmake file is not found (that's working by default) >>>> OR >>>> - xyz-config.cmake file is found BUT one or more component is missing >>>> >>>> In my xyz-config.cmake, I tried: >>>> - set (xyz_FOUND FALSE) # overall package not found as required >>>> - set (xyz2_FOUND FALSE) # component not found, hoping find_package would >>>> compare this to the list xyz_FIND_COMPONENTS >>>> >>>> But in all cases, it seems that find_package resets xyz_FOUND to 1 as long >>>> as the file xyz-config.cmake is found. Is there a way to set xyz_FOUND to >>>> 0 within xyz-config.cmake? >>>> >>>> Anton >> >> Second try: http://www.mail-archive.com/cmake@cmake.org/msg37840.html >> >> Regards, >> >> 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