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

Clinton Stimpson clinton at elemtech.com
Thu May 28 23:48:39 EDT 2009


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?

Clint




More information about the CMake mailing list