CMake Find Modules, HINTS, and NO_DEFAULT_PATH

Brad King brad.king at kitware.com
Mon Jun 9 22:41:42 CEST 2008


Hi Folks,

In response to this discussion:

  http://mail.kde.org/pipermail/kde-buildsystem/2008-June/004747.html
  http://mail.kde.org/pipermail/kde-buildsystem/2008-June/004744.html

I've committed some find_* command changes in CMake to make the search
order more intuitive (specific-to-general).  An explanation of the
changes is below.

I'd appreciate if some of you try CMake HEAD from CVS to see if
everything works as expected and that no existing KDE projects break.
When all is well with the changes we'll merge them for inclusion in a
CMake 2.6 patch release.  Then when KDE bumps the required version to
2.6 this feature will be available to its Find* modules.

Consider the call

  find_library(FOO_LIB foo PATHS /some/hard/coded/path)

This hard-coded path is just a *guess* and should be used only as a last
resort.  This is why CMake favors system library locations over the
PATHS option.  On the other hand the call:

  find_library(FOO_LIB foo PATHS ${BAR_TOLD_ME_FOO_MIGHT_BE_HERE})

provides a path that should be preferred over the system path because it
is more specific.  Currently CMake does not distinguish this case and
still prefers the system paths.  As a work-around, many Find* modules
are using a two-call approach:

  find_library(FOO_LIB foo PATHS ${BAR_TOLD_ME_FOO_MIGHT_BE_HERE}
               NO_DEFAULT_PATH)
  find_library(FOO_LIB foo)

The problem with this is that it prevents users from being able to
override the *hint* that is provided by ${BAR...} by setting
CMAKE_PREFIX_PATH.  Also, we (cmake authors) would prefer people not use
NO_DEFAULT_PATH unless the provided PATHS are known to contain the library.

The solution I've committed to CMake HEAD in CVS is to distinguish
"hint" paths from "guess" paths.  For compatibility the PATHS option
must continue to mean "guess".  I've added a new HINTS option that is
interpreted as "hint" paths.  This allows the above code to be written

  find_library(FOO_LIB foo HINTS ${BAR_TOLD_ME_FOO_MIGHT_BE_HERE})

The provided hint is preferred over system locations but not over the
cmake-specific user environment variables or cache entries.  I've
already converted most of the Find* modules provided by CMake to take
advantage of this feature.

As suggested by David Faure, I've also flipped the order of
CMAKE_PREFIX_PATH (and related variables) so that the setting from the
cache (or command line) is preferred over the environment version.  The
new order is now

  1.) CMAKE_PREFIX_PATH from cmake variable (typically on command line)
  2.) CMAKE_PREFIX_PATH from environment (typically in ~/.bashrc)
  3.) HINTS option listed in command
  4.) PATH or LIB or other common system environment variables
  5.) CMAKE_SYSTEM_PREFIX_PATH from cmake variable
  6.) PATHS option listed in command

-Brad


More information about the Kde-buildsystem mailing list