Home > Back-end >  CMake: How to compile with different library versions of Qt?
CMake: How to compile with different library versions of Qt?

Time:02-16

How do you get CMake to compile conditionally with Qt4.8 or Qt5? In other words, if Qt5 is available then compile with Qt5. Otherwise if Qt4.8 is available use that.

In my CMake, I have:

find_package(Qt5 COMPONENTS Core Gui Widgets...)

This works fine with my Qt5 builds, but how do I get the same software to build with Qt4.8?

I need something that contains the major version number, eg.:

find_package(Qt $QT_VERSION_MAJOR...)

or to use a condition, such as:

result = find_package(Qt 5...)
if (!result) then find_package(Qt4 ...)

or somehow detect the currently install Qt version.

The error I get for the machine with Qt4.8 installed is (unsurprisingly):

CMake Error at CMakeLists.txt:54 (find_package):
  By not providing "FindQt5.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "Qt5", but
  CMake did not find one.

  Could not find a package configuration file provided by "Qt5" with any of
  the following names:

    Qt5Config.cmake

What is the best approach here?

CodePudding user response:

Automatically selecting an available version of Qt is fairly easy with the NAME option of the find_package command. The problem is that Qt4 and Qt5 have different names for the same modules.

# We first try to find the main module of Qt4, Qt5 or Qt6
find_package(QT NAMES Qt4 Qt5 Qt6 REQUIRED)
set(QT Qt${QT_VERSION_MAJOR})

# We prepare lists of modules and libraries for different
# versions of Qt
if (QT_VERSION_MAJOR EQUAL 4)
    set(APP_QT_MODULES QtCore QtNetwork QtGui QtXml)
    set(APP_QT_TARGETS Qt4::QtCore Qt4::QtNetwork Qt4::QtGui Qt4::QtXml)
else ()
    set(APP_QT_MODULES Core Network PrintSupport Widgets Xml)
    set(APP_QT_TARGETS ${QT}::Core ${QT}::Network ${QT}::PrintSupport ${QT}::Widgets ${QT}::Xml)
endif ()

# Here everything is simple - find the modules we need.
find_package(${QT} REQUIRED ${APP_QT_MODULES})

. . .
. . .

# And at last don't forget to add libraries.
add_executable(my_app app.cpp main.cpp window.cpp)
target_link_libraries(my_app ${APP_QT_TARGETS})

Another problem is that Qt functions have different names too, for example qt4_add_resources and qt5_add_resources. And this is a good reason to wonder whether or not you really need Qt4 support in your project.

Update

We can make Qt function aliases (as is done in Qt since version 5.15).

if (QT_VERSION VERSION_LESS 5.15)
    macro(qt_wrap_cpp)
        ${QT}_wrap_cpp(${ARGV})
    endmacro()

    macro(qt_add_resources)
        ${QT}_add_resources(${ARGV})
    endmacro()

    macro(qt_generate_moc)
        ${QT}_generate_moc(${ARGV})
    endmacro()
endif ()
  • Related