[CMake] Suggesting to FindQT4.cmake where to find QT4

Jed Brown jed at 59A2.org
Fri May 29 04:53:56 EDT 2009


Adolfo Rodríguez wrote:
> On Fri, May 29, 2009 at 5:48 AM, Clinton Stimpson <clinton at elemtech.com>wrote:

>> I think what is being asked here is a good idea.  There is already
>> the CMAKE_PREFIX_PATH which gives find_package(Qt4) a prefix to work
>> from.  If I set it to one of my other Qt4, directories, it finds that
>> Qt installation fine.  But maybe adding something like a
>> QT4_PREFIX_PATH to have find_package(Qt4) prefer another directory
>> first and MPI_PREFIX_PATH to have find_package(MPI) prefer yet a
>> different directory would be nice.

MPIHOME is a pseudo-standard here, but I agree.

>> Maybe even extend that so if one did
>> find_program(MYVAR_EXECUTABLE ...)
>> find_library(MYVAR_LIBRARY ...)
>> a user of a CMakeLists.txt file containing that could set
>> MYVAR_PREFIX_PATH.
>>
>> Or maybe use MYVAR_DIR so the same variable works when cmake config files
>> are found by find_package().
>>
>> Maybe another step would be to detect if MYVAR_DIR changed, and remove all
>> dependent variables and do a re-find.
>>
>> I see that FindBoost.cmake has a BOOST_ROOT that tries to do the above, but
>> a standard mechanism for all find_* would be better.

It looks like FindBoost tries to respect environment variables, but
doesn't try to recover if BOOST_ROOT changes.  For that, you need the
sort of logic in FindQt4 (QT_QMAKE_CHANGED) or in my modules (FindPETSc,
etc).  It's remarkable frustrating to make robust.

>> Or does cmake already have a standard way of doing this?

Not that I know of, see

  http://www.cmake.org/Wiki/CMake:Improving_Find*_Modules#Dependent_cache_variables

> I do something like this when looking for simple packages (thanks to Greg
> Peele for a cool tip on this):
> 
> # Get hint from environment variable (if any)
> if(DEFINED ENV{FOO_ROOT_DIR})
>   set(FOO_ROOT_DIR "$ENV{FOO_ROOT_DIR}" CACHE PATH "FOO base directory
> location (optional, used for nonstandard installation paths)" FORCE)
>   mark_as_advanced(FOO_ROOT_DIR)
> endif()

This is bad because if the user had a messy environment, the
FOO_ROOT_DIR will be set to the wrong value.  They will edit this value
in cmake-gui and it will be wiped out when they press Configure.  They
will have to quit cmake-gui and fix their environment to deal with this.
In other words, it should not be FORCE and FOO_ROOT_DIR should not be
advanced (it's the intended way for the user to interact with the find
process, so users need to know that it exists).

> # Search path for nonstandard locations
> if(FOO_ROOT_DIR)
>   set(FOO_INCLUDE_PATH PATHS ${FOO_ROOT_DIR}/include NO_DEFAULT_PATH)
>   set(FOO_LIBRARY_PATH PATHS ${FOO_ROOT_DIR}/lib NO_DEFAULT_PATH)
> endif()
> 
> # Find headers and libraries
> find_path(FOO_INCLUDE_DIR NAMES foo/FOO.h ${FOO_INCLUDE_PATH})
> find_library(FOO_LIBRARY NAMES FOO ${FOO_LIBRARY_PATH})

FOO_INCLUDE_DIR and FOO_LIBRARY will not be updated if the user changed
FOO_ROOT_DIR, thus creating an inconsistent build.  Without language
support, FindFoo needs to internally cache the last value of
FOO_ROOT_DIR in order to detect if it has changed.  If so,
FOO_INCLUDE_DIR, FOO_LIBRARY, and FOO_FOUND need to be FORCE cleared
before they are searched for again.  This reset needs to include all
internal variables, such as those used by CHECK_C_SOURCE_RUNS
(${VAR}_COMPILED and ${VAR}_EXITCODE) because these checks need to be
re-run.  As you can see, this crosses module boundaries and is a lot of
work to maintain.


Jed

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 260 bytes
Desc: OpenPGP digital signature
URL: <http://www.cmake.org/pipermail/cmake/attachments/20090529/6207e970/attachment-0001.pgp>


More information about the CMake mailing list