CMake:如何使用不同版本的 Qt 库进行编译?

Dog*_*ath 4 c++ qt cmake

如何让 CMake 使用 Qt4.8 或 Qt5 有条件编译?换句话说,如果 Qt5 可用,则使用 Qt5 进行编译。否则,如果 Qt4.8 可用,请使用它。

在我的 CMake 中,我有:

find_package(Qt5 COMPONENTS Core Gui Widgets...)
Run Code Online (Sandbox Code Playgroud)

这对于我的 Qt5 构建来说效果很好,但是如何使用 Qt4.8 构建相同的软件呢?

我需要包含主版本号的内容,例如:

find_package(Qt $QT_VERSION_MAJOR...)
Run Code Online (Sandbox Code Playgroud)

或使用条件,例如:

result = find_package(Qt 5...)
if (!result) then find_package(Qt4 ...)
Run Code Online (Sandbox Code Playgroud)

或者以某种方式检测当前安装的 Qt 版本。

我在安装了 Qt4.8 的机器上得到的错误是(不出所料):

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
Run Code Online (Sandbox Code Playgroud)

这里最好的方法是什么?

u-2*_*235 6

使用find_packageNAME命令选项自动选择可用的 Qt 版本相当容易。问题是 Qt4 和 Qt5 对于相同的模块有不同的名称。

# 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})
Run Code Online (Sandbox Code Playgroud)

另一个问题是 Qt 函数也有不同的名称,例如qt4_add_resourcesqt5_add_resources。这是一个很好的理由来怀疑您的项目是否真的需要 Qt4 支持。

更新

我们可以创建 Qt 函数别名(正如Qt 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 ()
Run Code Online (Sandbox Code Playgroud)