[CMake] Apply FIND_PACKAGE_HANDLE_STANDARD_ARGS() on COMPONENTS

Alexander Neundorf a.neundorf-work at gmx.net
Thu Apr 22 15:55:20 EDT 2010


On Thursday 22 April 2010, Michael Hertling wrote:
> On 04/21/2010 09:13 PM, Alexander Neundorf wrote:
> > On Tuesday 20 April 2010, Michael Hertling wrote:
> >> Dear CMake community, dear CMake developers,
> >
> > ...
> >
> >> There's another aspect related to this I'd like to comment on: During
> >> the abovementioned considerations on the bug tracker and the mailing
> >> list, the question has arisen if it's reasonable to set XXX_FOUND to
> >> FALSE if any of the requested components aren't found. As for myself,
> >> I'd say: No, it isn't. Let's have a look at the following scenario:
> >>
> >> Package XXX normally provides components YY1 and YY2, but for some
> >> reason, only YY1 is installed. Moreover, XXX provides a config file
> >> XXXConfig.cmake. Now, a project's CMake script requests both YY1/2 by
> >> FIND_PACKAGE(XXX COMPONENTS YY1 YY2). As Brad King has pointed out in
> >> <http://www.mail-archive.com/cmake@cmake.org/msg15952.html>, finding a
> >> config file results in XXX_FOUND to be set to TRUE automatically. Thus,
> >> the absence of YY2 does not mean the absence of XXX as a whole in any
> >> case, and, notwithstanding, the requesting CMake script should have a
> >> chance to proceed even if YY2 isn't available, i.e. the following seems
> >> reasonable: XXX_YY1_FOUND=TRUE, XXX_YY2_FOUND=FALSE *but*
> >> XXX_FOUND=TRUE.
> >
> > I think I don't agree here.
> > If I say
> > find_package(XXX COMPONENTS YY1 YY2 REQUIRED)
> > I think it makes a lot of sense to interpret this as "search package XXX,
> > and I need YY1 and YY2 from it".
>
> OK, the presence of the REQUIRED option makes everything clear: A find
> module or a config file bails out if anything is missing - no worry
> about the final value of XXX_FOUND. The actual questions arise if
> REQUIRED is absent.
>
> > What other reason would I have to give YY1 and YY2 there otherwise ?
>
> Perhaps, because YY2 is optional and I do not want FIND_PACKAGE() to
> look for unrequested components, but that's merely my personal habit.
>
> > If it still succeeds if they are not found, why should I list them then ?
>
> It is possible for FIND_PACKAGE() - w/o REQUIRED - to succeed although
> listed components aren't found, and *this* is what I'm worrying about.
> As Brad King has pointed out in the abovementioned post, FIND_PACKAGE()
> in config mode sets XXX_FOUND to TRUE if the config file is found and
> processed without errors, and there's nothing one can do against it -


Well, find_package() could be enhanced to set this considering the specified 
COMPONENTS. There hasn't been much discussion about how the COMPONENTS 
arguments should be interpreted until now.


> unless explicitly terminating the config file which would not be
> expected if REQUIRED is absent. Thus, revisiting your question: It's
> possible for it to succeed although they are not found, and this is,
> IMHO, not a result of a faultily implemented config file and also the
> reason why I recommended against setting XXX_FOUND to FALSE in a find
> module if not all requested components are present; XXX_FOUND should,
> perhaps, be interpreted in a different manner.
>
> Core question reworded: Is it acceptable to obtain a different setting
> from FIND_PACKAGE() depending on loading a find module or a config file?
>
> > I think by default (no COMPONENTS specified) all components should be
> > searched. [...]
>
> Or none. Just spontaneously:
>
> - Searching a component could possibly be quite expensive.
> - Populating XXX_{DEFINITIONS,LIBRARIES,INCLUDE_DIRS} with all settings
>   to use the whole thing? E.g., FindQt4 behaves different: Just Core+GUI.
> - Again, Brad King from above: "Perhaps the project finding Foo just
>   wants to load some documentation files from it [...]", i.e. no
>   interest in components at all, but only in Foo_ROOT_DIR, e.g.
>
> But, in my opinion, these questions should be a module designer's affair.
>
> > [...] By listing components you can say "I am ok if at least these are
> > found". [...]
>
> Or "Look for these, and ignore any others.", but --> module designer.
>
> > [...] (the man page doesn't say anything about how the "COMPONENTS"
> > should be interpreted).
>
> Regrettably, that's right. For me, the sole reference
>
> "A package-specific list of components may be listed after the REQUIRED
> option or after the COMPONENTS option *if no REQUIRED option is given*."
>
> sounds a little bit like COMPONENTS and REQUIRED are intended to be
> mutually exclusive, and, indeed, FIND_PACKAGE(... REQUIRED ...) and
> FIND_PACKAGE(... COMPONENTS ... REQUIRED) seem not to provide a sole
> difference for the find module, only FIND_PACKAGE(... COMPONENTS ...)
> without REQUIRED does. Furthermore, one can read in Modules/readme.txt:
>
> "The set of components listed after *either* the REQUIRED option or the
> COMPONENTS option will be specified in a XXX_FIND_COMPONENTS variable."
>
> Perhaps, we can get some clarifications w.r.t. the particular intention
> of the COMPONENTS option, especially when REQUIRED isn't mentioned, too.
>
> Finally, an example: I have endangered my Qt installation by saying
> "# mv libQtXml.so{,.bak}" for testing the following CMakeLists.txt:
>
> CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
> PROJECT(QT_COMPONENT_TEST)
> FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtXml REQUIRED)
> MESSAGE("QT4_FOUND: <${QT4_FOUND}>")
> MESSAGE("QT_QTCORE_FOUND: <${QT_QTCORE_FOUND}>")
> MESSAGE("QT_QTGUI_FOUND: <${QT_QTGUI_FOUND}>")
> MESSAGE("QT_QTXML_FOUND: <${QT_QTXML_FOUND}>")
>
> When run from a clean directory - no cache and the like - it yields:
>
> [...]
> QT4_FOUND: <YES>
> QT_QTCORE_FOUND: <1>
> QT_QTGUI_FOUND: <1>
> QT_QTXML_FOUND: <>
> [...]

Hmm, not for me ( and I also didn't remember such behaviour):
ammer:~/src/tests/findqt4/b262$ cat ../CMakeLists.txt
cmake_minimum_required(VERSION 2.6)

find_package(Qt4 COMPONENTS QtXML)

message(STATUS "QT_QTXML_FOUND ${QT_QTXML_FOUND}")
message(STATUS "QT_QTXML_LIBRARY ${QT_QTXML_LIBRARY}")
hammer:~/src/tests/findqt4/b262$ /opt/cmake-2.6.2-Linux-i386/bin/cmake ..
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Looking for Q_WS_X11
-- Looking for Q_WS_X11 - found
-- Looking for Q_WS_WIN
-- Looking for Q_WS_WIN - not found.
-- Looking for Q_WS_QWS
-- Looking for Q_WS_QWS - not found.
-- Looking for Q_WS_MAC
-- Looking for Q_WS_MAC - not found.
-- Found Qt-Version 4.6.0
-- Found OpenSSL: /usr/lib/libssl.so
-- Looking for _POSIX_TIMERS
-- Looking for _POSIX_TIMERS - found
-- QT_QTXML_FOUND 1
-- QT_QTXML_LIBRARY /opt/kde-qt/lib/libQtXml.so
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/src/tests/findqt4/b262


Alex


More information about the CMake mailing list