[CMake] Suggesting to FindQT4.cmake where to find QT4
Clinton Stimpson
clinton at elemtech.com
Fri May 29 10:24:27 EDT 2009
Adolfo RodrÃguez wrote:
> On Fri, May 29, 2009 at 5:48 AM, Clinton Stimpson
> <clinton at elemtech.com <mailto: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
> <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.
>
Yes, that's doable right now.
But, I was actually hoping for something that worked automatic like
CMAKE_PREFIX_PATH.
Not something extra people have to code into their Find*.cmake files or
extra things they have to do with their find_* calls.
Also, I was thinking of a cmake variable, not an environment variable.
Clint
More information about the CMake
mailing list