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

Adolfo Rodríguez dofo79 at gmail.com
Fri May 29 04:03:24 EDT 2009


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

> Jed Brown wrote:
>
>> Alexander Neundorf wrote:
>>
>>
>>> On Monday 25 May 2009, Jed Brown wrote:
>>>
>>>
>>>> Bill Hoffman wrote:
>>>>
>>>>
>>>>> You can also set QMake on the cmake command line as well:
>>>>>
>>>>> cmake -DQT_QMAKE_EXECUTABLE=/path/to/qmake ../source
>>>>>
>>>>>
>>>> Yeah, I'm much less concerned with this particular case as with the
>>>> philosophy that the correct way to select installations is by modifying
>>>> PATH.  Frustratingly, a new user will fire up cmake and get the wrong
>>>> version (they're not even aware of exactly what the dependencies are,
>>>> let alone the naming convention for the cache variable that will get the
>>>> correct version).  So they interactively change a couple paths and
>>>> reconfigure.  Lo and behold, they now have an inconsistent state because
>>>> the cache wasn't flushed when they changed QT_QMAKE_EXECUTABLE (I don't
>>>> know if this is the case with Qt, but is is with most packages).
>>>>
>>>>
>>> ...
>>>
>>>
>>>> Using PATH and falling back on peculiarly named variables (hopefully
>>>> only one non-advanced variable per package, so that it's unambiguous)
>>>>
>>>>
>>> With the new cmake-gui this is now much easier :-)
>>>
>>>
>>
>> CMake gui is nice and it's easier to edit variables.  For this case, I
>> think the only way it makes a difference is that you can go to advanced
>> grouped mode and wipe out a whole group easily.  Some packages have
>> dependencies, so this isn't a complete solution, but it does make a big
>> difference.  I wrote the following before noticing that it was easy to
>> clear groups, but I think it's still somewhat relevant.
>>
>>
>> The user doesn't know the name of special variables (like
>> QT_QMAKE_EXECUTABLE) until they press Configure.  If the wrong version
>> is found on the first pass, it's typically too late to change the path.
>> (There isn't a concept of dependent cache variables so very few Find*
>> modules can clean up after an incorrect version is found.  There is an
>> implicit assumpition that if *any* installation is found, it is the one
>> the user wanted.  FindQt4 might be a very rare exception to this.  I
>> haven't tested its robustness since I don't use it, but I see a lot of
>> QT_QMAKE_CHANGED logic so the author is at least trying to handle this.)
>>
>> So they have to flush the cache and define the special variable *before*
>> CMake shows them that the variable exists.  Until packages can robustly
>> support changing their path *after* the first pass finds an undesired
>> version, I think that recognizing semi-standard environment variables
>> like QTDIR would be good policy (e.g. the user is much more likely to
>> guess QTDIR than QT_QMAKE_EXECUTABLE if they are unfamiliar with CMake
>> and only know that the your package needs Qt).
>>
>>
> I don't think of QTDIR as anything of a standard anymore.  It was necessary
> in Qt3 to make the qmake build system work.
> Anyway...  read below.
>
>  Also, instead of setting PATH to /opt/qt-a.b.c/bin/ you can also set
>>> CMAKE_PREFIX_PATH to /opt/qt-a.b.c/, also to a list of directories, which
>>> cmake will search in the order you specified.
>>>
>>>
>>
>> I know about these, but they have global scope and are thus not a
>> solution to the problem I stated.  You need to be able to specify
>> install paths *independently*.  As a concrete example, suppose different
>> versions of MPI are installed at /usr and /usr/local.  Similarly,
>> suppose different versions of Qt are installed at /usr and /usr/local.
>> I'm not claiming this is the best organization, but it's not terribly
>> uncommon or pathological, so some users will have this situation and
>> it's none of our business to tell them to reinstall just to build our
>> package.
>>
>> Qt and MPI are independent packages so their selection cannot be
>> dependent.  Modifying variables like PATH or CMAKE_PREFIX_PATH will
>> choose versions for both of these packages.  FindMPI.cmake cannot be set
>> independently, so if I wanted to get MPI from /usr, I have to put /usr
>> first in PATH/CMAKE_PREFIX_PATH.  A new user will not know this in
>> advance.  To get Qt from /usr/local, I can set QT_QMAKE_EXECUTABLE, but
>> a new user won't know this before running CMake (gui) and looking at the
>> options.  If they are lucky, they will get the correct MPI on the first
>> pass, and although the incorrect Qt is found, they can change
>> QT_QMAKE_EXECUTABLE and the QT_QMAKE_CHANGED logic will work correctly
>> to give them a consistent build.  If the wrong MPI is found, they have
>> no choice but to delete the cache, modify some global state (PATH or
>> similar) and try again.  Note that very few Find* modules can recover
>> from finding an incorrect package (it takes a lot of work, you basically
>> have to work around the cache).  In addition, not many have a single
>> variable to control which installation is found, thus necessitating
>> global control which creates the locking problem.
>>
>>
>>
> 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.
>
> 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.
> Or does cmake already have a standard way of doing this?


This link [1] suggests that the correct name for the variable should be
QT$_ROOT_DIR (instead of QT4_PREFIX_PATH or QT4_ROOT)

[1]
http://public.kitware.com/cgi-bin/viewcvs.cgi/Modules/readme.txt?root=CMake&view=markup

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()

# 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})

... then you can use FindPackageHandleStandardArgs or whatever you like the
most.

I know that FindQT4 is a _lot_ more complicated than this, but anyway, I
find the FOO_ROOT_DIR (env. or cmake) variable very useful.

Cheers,

Adolfo



>
>
> Clint
>
>
>
> _______________________________________________
> 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
>



-- 
Adolfo Rodríguez Tsouroukdissian

Robotics engineer
PAL ROBOTICS S.L
http://www.pal-robotics.com
Tel. +34.93.414.53.47
Fax.+34.93.209.11.09
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20090529/08f90534/attachment.htm>


More information about the CMake mailing list