如何使用 CMake 包含某个 Qt 安装? [英] How to include a certain Qt installation using CMake?

查看:20
本文介绍了如何使用 CMake 包含某个 Qt 安装?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在每台开发 PC 上都有大量 Qt 副本——每个项目在第三方目录中都有自己的 Qt 副本.这是因为每个项目都是用自己的 Qt 开发和测试的;一个常见的情况是,我们需要为某个项目自定义构建 Qt.因此,由于上面提到的,我们有一个单独的 SVN 存储库用于保存各种 Qt 构建,并且在每个 Qt 项目中都有一个外部存储库,它指的是这些构建中的一个.

We have plenty Qt copies on every dev PC - each project has its own Qt copy in the thirdparties directory. That's done due to each project is developed and tested with its own Qt; an often case is that we need a custom build of Qt for some project. So due to mentioned above we have a separate SVN repo for holding various Qt builds and an external in each Qt project, which refers to one among those builds.

问题是,在使用 CMake 时,我们只能选择 Qt 的一个版本,而 Qt4 finder 会自行决定使用哪个 Qt.这不是正确的.我们需要重定向查找器以配置项目第三方目录中特定 Qt 副本的所有内容.

The problem is, when using CMake we can only select a version of Qt and the Qt4 finder decides what Qt to use by itself. And that's not the correct one. We need to redirect the finder to configure all stuff for a particular Qt copy in project's third parties directory.

我尝试为 FIND_PACKAGE 指定 PATHS 选项,如下所示:FIND_PACKAGE(Qt4 REQUIRED PATHS "thirdparty/Qt" ) 但是那没有帮助.我试图设置 QT_QMAKE_EXECUTABLE 变量,但是没有用.我已经尝试在安装之前将所需的 QMake 路径(FindQt4.cmake 使用它来确定所有目录)添加到 PATH 变量中,但也没有帮助.

I've tried to specify the PATHS option for FIND_PACKAGE like that: FIND_PACKAGE( Qt4 REQUIRED PATHS "thirdparty/Qt" ) but that didn't help. I have tried to set the QT_QMAKE_EXECUTABLE variable, but that didn't work. I've tried to add the required QMake's path (it's used by the FindQt4.cmake to determine all directories) to the PATH variable before the installed one, but that didn't help too.

有没有办法使用 FIND_PACKAGE 提供的所有东西,但对于某个 Qt 副本?我真的不想实现所有 Qt 包装器,手动设置所有定义、包含、目录等.

Is there a way to use all the stuff which the FIND_PACKAGE provides but for a certain Qt copy? I really don't want to implement all Qt wrappers, set all definitions, includes, dirs, etc manually.

这是我的 CMake 项目.也许这会有所帮助:

Here is my CMake project. Maybe that will help:

CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )

#############################################################################

MACRO( ADD_FILES_TO_FILTER rootFilterName rootFilterPath files )
    FOREACH( curFile ${files} )
        FILE( RELATIVE_PATH curFilter "${CMAKE_CURRENT_SOURCE_DIR}/${rootFilterPath}" "${CMAKE_CURRENT_SOURCE_DIR}/${curFile}" )
        FILE( RELATIVE_PATH test "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${curFile}" )
        GET_FILENAME_COMPONENT( curFilter ${curFilter} PATH )
        SET( curFilter "${rootFilterName}/${curFilter}" )
        STRING( REPLACE "/" "\\" curFilter ${curFilter} )
        SOURCE_GROUP( ${curFilter} FILES ${curFile} )
    ENDFOREACH( curFile )
ENDMACRO( ADD_FILES_TO_FILTER rootFilterName rootFilterPath files )

MACRO( TO_RELATIVE_PATHS filePaths )
    SET( resPaths "" )
    FOREACH( curPath ${${filePaths}} )
        FILE( RELATIVE_PATH relPath ${CMAKE_CURRENT_SOURCE_DIR} ${curPath} )
        SET( resPaths ${resPaths} ${relPath} )
    ENDFOREACH( curPath )
    SET( ${filePaths} ${resPaths} )
ENDMACRO( TO_RELATIVE_PATHS filePaths )

######################################################################

# Define project settings
PROJECT( RealTimeCapture )
FIND_PACKAGE( Qt4 REQUIRED PATHS "thirdparty/Qt" )
SET( BOOST_ROOT "thirdparty/boost" )
FIND_PACKAGE( Boost REQUIRED )

# Collect all required files for build
FILE( GLOB_RECURSE headers RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/RTCF/include/*.h" )
FILE( GLOB_RECURSE sources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/RTCF/src/*.cpp" )
FILE( GLOB_RECURSE resources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.qrc" )
FILE( GLOB_RECURSE forms RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.ui" )

# Preprocess all Qt files
QT4_WRAP_CPP( header_mocs ${headers} )
QT4_WRAP_UI( form_headers ${forms} )
QT4_ADD_RESOURCES( resources_rcc ${resources} )

# Convert all generated files paths to relative ones
TO_RELATIVE_PATHS( header_mocs )
TO_RELATIVE_PATHS( form_headers )
TO_RELATIVE_PATHS( resources_rcc )

# Create executable
ADD_EXECUTABLE( RealTimeCapture ${headers} ${sources} ${header_mocs} ${form_headers} ${resources_rcc} )
SET_TARGET_PROPERTIES( RealTimeCapture PROPERTIES COMPILE_FLAGS "/Zc:wchar_t-" )

# Set filters for project according to its namespaces
FILE( RELATIVE_PATH buildDir ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} )
ADD_FILES_TO_FILTER( "Headers" "src/RTCF/include" "${headers}" )
ADD_FILES_TO_FILTER( "Sources" "src/RTCF/src" "${sources}" )
ADD_FILES_TO_FILTER( "Generated" "${buildDir}/src/RTCF/include" "${header_mocs}" )
ADD_FILES_TO_FILTER( "Forms" "${buildDir}/src/RTCF/include" "${form_headers}" )
ADD_FILES_TO_FILTER( "Resources" "${buildDir}" "${resources_rcc}" )

# Set additional include directories
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} )
INCLUDE_DIRECTORIES( "src" )
INCLUDE_DIRECTORIES( "src/RTCF/include" )
INCLUDE_DIRECTORIES( "thirdparty" )

# Configure Qt
SET( QT_USE_QTNETWORK TRUE )
SET( QT_USE_QTSQL TRUE )
SET( QT_USE_QTSCRIPT TRUE )
SET( QT_USE_QTXML TRUE )
SET( QT_USE_QTWEBKIT TRUE )
INCLUDE( ${QT_USE_FILE} )
ADD_DEFINITIONS( ${QT_DEFINITIONS} )
TARGET_LINK_LIBRARIES( RealTimeCapture ${QT_LIBRARIES} )

# Add boost support
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR} )
TARGET_LINK_LIBRARIES( RealTimeCapture ${Boost_LIBRARIES} )

# Add other libs include dirs
INCLUDE_DIRECTORIES( "thirdparty/SimpleCrypt" )
INCLUDE_DIRECTORIES( "thirdparty/id3lib/include" )
INCLUDE_DIRECTORIES( "thirdparty/libtwitcurl" )
INCLUDE_DIRECTORIES( "thirdparty/curl-7.24.0/curl/include" )
INCLUDE_DIRECTORIES( "thirdparty/log4qt/include" )
INCLUDE_DIRECTORIES( "thirdparty/fervor-auto" )

# Add defines
ADD_DEFINITIONS( RealTimeCapture -DQUAZIP_STATIC )
ADD_DEFINITIONS( RealTimeCapture -DBUILDING_LIBCURL )
ADD_DEFINITIONS( RealTimeCapture -DID3LIB_LINKOPTION=1 )
ADD_DEFINITIONS( -DUNICODE -D_UNICODE ) #enable unicode support

更新

正如在已接受答案的评论中提到的那样,我通过设置 QT_QMAKE_EXECUTABLE CMake 变量设法设置了自定义 qmake.exe(与添加到 OS PATH 变量的那个不同).但问题是,qmake 可执行文件具有所有 Qt 模块的硬编码路径.所以我通过提供一个自定义的 qt.conf 文件来解决它(正如答案中提到的那样).我在互联网上没有找到任何例子,所以在这里,也许它会帮助某人:

As it's mentioned in the comments to the accepted answer, I've managed to set a custom qmake.exe (different from the one added to the OS PATH variable) by setting the QT_QMAKE_EXECUTABLE CMake variable. But the problem was, the qmake executable has hardcoded paths to all Qt's modules. So I have solved it by providing a custom qt.conf file (as it's mentioned in the answer). I haven't found any examples of it in the internet, so here it is, maybe it will help someone:

[Paths]
Prefix=..
Documentation=doc
Headers=include
Libraries=lib
Binaries=bin
Plugins=plugins
Imports=imports
Data=
Translations=
Settings=
Examples=
Demos=

我正是使用了这个.不过,您可以考虑在前缀中指定 Qt 安装的绝对路径.我只是不想在 repo 中使用绝对路径,它可以被克隆到任意位置.有关使用 qt.conf 的详细信息,请参阅链接.

I used exactly this. You can consider specifying an absolute path to the Qt install in the prefix though. I just didn't want to use an absolute path in a repo, which can be cloned in an arbitrary location. See this link about details on using qt.conf.

推荐答案

QT_QMAKE_EXECUTABLE 您走在正确的轨道上.该变量是一个缓存变量,所以简单地设置它是行不通的……除非您通过 GUI 更改它,或者在第一次运行 cmake 之前,或者在 CMakeCache.txt 中,或者使用 CACHE 更改它,否则缓存的值会一直存在和 FORCE 选项SET.

You're on the right track with QT_QMAKE_EXECUTABLE. That variable is a cache variable, so simply setting it won't work... the cached value will stick around unless you change it via the GUI, or before running cmake the first time, or in CMakeCache.txt, or with the CACHE and FORCE options to SET.

这是我使用的习惯用法,因为我有固定的逻辑来根据配置时已知的变量选择我的 QT 目录.在这里,我在运行 FIND_PACKAGE 之前设置了变量,所以没有缓存问题.

Here's the idiom I use, since I have fixed logic to choose my QT directory based on variables known at configure time. Here, I set the variable before ever running FIND_PACKAGE, so no cache issues.

IF(WIN32 AND ${CMAKE_SIZEOF_VOID_P} MATCHES 8)
  # Hardcode a location for a QT toolkit compiled for Win64.  By overriding QT_QMAKE, all the rest is found
  # Choose any version of QT found in the 64-bit tools area
  FILE(GLOB QTROOTS c:/Tools_x64/Qt/*/bin)     # */
  FIND_PROGRAM(QT_QMAKE_EXECUTABLE NAMES qmake qmake4 qmake-qt4 qmake-mac PATHS ${QTROOTS})
ENDIF()

把这个放在 FIND_PACKAGE(Qt4) 之前

Put this before FIND_PACKAGE( Qt4 )

根据评论中的新信息进行

EDITING based on new information in comments:

哦,我现在和你在一起.你有多少损坏的 Qt 安装.FindQt 模块将始终使用 qmake 可执行文件来发现 Qt 树的设置.Qmake 将这些信息存储在一组持久属性"中,可以使用 qmake -query 查询,并使用 qmake -set 设置.因此,您可以通过运行 qmake 并设置 QT_INSTALL_PREFIX 属性来修复"Qt 安装,如下所述:http://doc.qt.digia.com/4.7-snapshot/qmake-environment-reference.html

Oh, I'm with you now. You have what amount to broken Qt installations. The FindQt module will always use the qmake executable to discover the settings for the Qt tree. Qmake stores this information in a set of "persistent properties", which can be queried with qmake -query, and set with qmake -set. So you can "fix" a Qt installation by running it's qmake and setting the QT_INSTALL_PREFIX property, as documented here: http://doc.qt.digia.com/4.7-snapshot/qmake-environment-reference.html

qmake -set "QT_INSTALL_PREFIX" /path/to/qt/

或者,在一个旧的 SO 问题中 qmake 和 QT_INSTALL_PREFIX.如何为 Qt 库选择新位置?,未接受的答案使用 qt.conf 覆盖 QT 前缀.

Or, in an old SO question qmake and QT_INSTALL_PREFIX. How can I select a new location for Qt library?, a non-accepted answer uses qt.conf to override the QT prefix.

这两种解决方案都涉及修改 Qt 安装.我不确定有什么办法可以解决这个问题,但是如何将其融入您的存储库和构建系统超出了此处的范围.

Both of these solutions involve modifying the Qt installation. I'm not sure there's any way around this, but how this fits into your repository and build system is out of scope here.

这篇关于如何使用 CMake 包含某个 Qt 安装?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆