首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用CMake包含特定的Qt安装?

如何使用CMake包含特定的Qt安装?
EN

Stack Overflow用户
提问于 2012-09-20 19:07:46
回答 3查看 28.5K关注 0票数 21

我们在每个开发PC上都有大量的Qt副本-每个项目在thirdparties目录中都有自己的Qt副本。这是因为每个项目都是用自己的Qt开发和测试的;一个常见的情况是,我们需要为一些项目定制一个Qt构建。因此,由于上面提到的,我们有一个单独的SVN repo来保存各种Qt版本,以及每个Qt项目中的一个外部版本,它引用了这些构建中的一个。

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

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

除了特定的Qt副本之外,有没有办法使用FIND_PACKAGE提供的所有东西?我真的不想手动实现所有的Qt包装器,设置所有的定义、包含、目录等。

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

代码语言:javascript
复制
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文件(正如答案中提到的)解决了这个问题。我还没有在互联网上找到任何这样的例子,所以这里是它,也许它会对某些人有所帮助:

代码语言:javascript
复制
[Paths]
Prefix=..
Documentation=doc
Headers=include
Libraries=lib
Binaries=bin
Plugins=plugins
Imports=imports
Data=
Translations=
Settings=
Examples=
Demos=

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-09-20 22:42:01

有了QT_QMAKE_EXECUTABLE,您就走上了正确的道路。该变量是一个缓存变量,所以简单地设置它是行不通的…除非你通过图形用户界面改变它,或者在第一次运行cmake之前,或者在CMakeCache.txt中,或者在缓存和强制选项为SET的情况下,否则缓存值会一直存在。

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

代码语言:javascript
复制
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 )之前

根据评论中的新信息进行编辑:

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

代码语言:javascript
复制
qmake -set "QT_INSTALL_PREFIX" /path/to/qt/

或者,在旧的SO问题qmake and QT_INSTALL_PREFIX. How can I select a new location for Qt library?中,未被接受的答案使用qt.conf覆盖QT前缀。

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

票数 10
EN

Stack Overflow用户

发布于 2013-06-06 18:58:15

如果可以的话,我想完成/确认这里所说的一些信息,并给出一个完整的例子。

像Occulta一样,我有一个定制的Qt环境,我必须在我的项目中使用它。以下是我为编译该项目而重现的步骤:

  1. 我的项目的CMakeLists.txt,已经拥有了所有的CMake内容,只包含一个'qt.cmake‘文件

include(qt)

  • The qt.cmake文件包含Peter的解决方案,并使用附加内容进行装饰。有了这个配置,我可以使用moc、uic和rcc来管理UI文件、资源文件等。如果它们不是严格正确的,请毫不犹豫地修复它们(对我来说,CMake的工作方式仍然是模糊的):Qt所在的路径。SET(QT_ROOT_DIR "path/ to / Qt ") set(QT_QMAKE_EXECUTABLE ${QT_ROOT_DIR}/osx/bin/qmake) #加载绑定到Qt的CMake宏。Find_package(需要Qt4)#包含使用的Qt标头。include(${QT_USE_FILE})

  • I还在与qmake可执行文件相同的级别添加了Occulta的qt.conf文件。

完成这三个步骤后,一切都很顺利。希望这个完整的例子能对某些人有所帮助。

谢谢你们,很明显你们帮了我大忙!

票数 3
EN

Stack Overflow用户

发布于 2014-02-26 18:16:48

这是对我有效的方法:

代码语言:javascript
复制
set( QT_ROOT /opt/myqt/ )
set( ENV(CMAKE_PREFIX_PATH) ${QT_ROOT} )
FIND_PACKAGE( Qt4 COMPONENTS QtCore QtGui QtDBUS REQUIRED )

这将更改PATH环境变量,但我还没有找到其他方法。其他的答案对我不起作用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12511370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档