如何使用CMake包含某个Qt安装?

时间:2012-09-20 11:07:46

标签: qt cmake

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

问题是,当使用CMake时,我们只能选择Qt版本,而Qt4 finder决定自己使用什么Qt。那不是正确的。我们需要重定向finder以配置项目第三方目录中特定Qt副本的所有内容。

我尝试为PATHS指定FIND_PACKAGE这样的FIND_PACKAGE( Qt4 REQUIRED PATHS "thirdparty/Qt" )选项:QT_QMAKE_EXECUTABLE但这没有帮助。我试图设置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 变量,但这不起作用。我已经尝试在安装之前将PATM变量所需的QMake路径(它由FindQt4.cmake用来确定所有目录)添加到PATH变量中,但这也无济于事。

有没有办法使用FIND_PACKAGE提供的所有东西但是对于某个Qt拷贝?我真的不想实现所有Qt包装器,手动设置所有定义,包括,dirs等。

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

QT_QMAKE_EXECUTABLE

更新

正如在接受的答案的评论中提到的那样,我设法通过设置qt.conf CMake变量来设置自定义qmake.exe(与添加到OS PATH变量的qmake.exe不同)。但问题是,qmake可执行文件具有到所有Qt模块的硬编码路径。所以我通过提供自定义[Paths] Prefix=.. Documentation=doc Headers=include Libraries=lib Binaries=bin Plugins=plugins Imports=imports Data= Translations= Settings= Examples= Demos= 文件解决了它(正如答案中提到的那样)。我没有在互联网上找到它的任何例子,所以在这里,也许它会帮助某人:

qt.conf
我正好使用了这个。您可以考虑在前缀中指定Qt安装的绝对路径。我只是不想在回购中使用绝对路径,可以将其克隆到任意位置。有关使用{{1}}的详细信息,请参阅this链接。

3 个答案:

答案 0 :(得分:10)

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

这是我使用的习语,因为我已经修复了逻辑,根据配置时已知的变量选择我的QT目录。在这里,我在运行FIND_PACKAGE之前设置变量,因此没有缓存问题。

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进行设置。因此,您可以通过运行qmake并设置QT_INSTALL_PREFIX属性来“修复”Qt安装,如下所示:http://doc.qt.digia.com/4.7-snapshot/qmake-environment-reference.html

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安装。我不确定是否有任何解决方法,但这适用于您的存储库和构建系统的方法超出了范围。

答案 1 :(得分:3)

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

和Occulta一样,我有一个定制的Qt环境,我必须将它用于我的项目。这些是我为了使项目编制而重现的步骤:

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

    include(qt)
    
  2. qt.cmake文件包含Peter的解决方案,附带了额外的东西。使用此配置,我可以使用moc,uic和rcc来管理UI文件,资源文件等。这是我的文件,带有一些注释。如果它们不是严格正确的话,请毫不犹豫地修理它们(CMake的工作方式对我来说仍然是阴天):

    # The path where Qt is.
    SET(QT_ROOT_DIR "path/to/qt")
    
    set(QT_QMAKE_EXECUTABLE ${QT_ROOT_DIR}/osx/bin/qmake)
    
    # Loads CMake macros bound to Qt.
    find_package(Qt4 REQUIRED)
    # Includes used Qt headers.
    include(${QT_USE_FILE})
    
  3. 我还在与qmake可执行文件相同的级别添加了Occulta的qt.conf文件。

  4. 完成这三个步骤后,一切都很顺利。希望这个完整的例子可以帮助别人。

    谢谢你们,你们明显帮助我了!

答案 2 :(得分:1)

这对我有用:

set( QT_ROOT /opt/myqt/ )
set( ENV(CMAKE_PREFIX_PATH) ${QT_ROOT} )
FIND_PACKAGE( Qt4 COMPONENTS QtCore QtGui QtDBUS REQUIRED )

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