本文默认朋友们都已经掌握了CMake
的基本操作,也可以再去笔者的CMake专栏瞄一眼,或者上CMake官方文档学一圈再回来。
对于在CMake
中使用Qt
,我们可以先想一下一个Qt
程序需要配置哪些内容。
首先需要搬出来Qt
的几个编译工具:moc、uic、rcc
,这几个工具在Qt Assistant
中都可以直接搜索到介绍页面,这里简单说一下各自都干什么的:
moc
:元对象编译器(Meta Object Compiler
),用来处理带有Q_OBJECT
宏的类。我们在声明class
的时候,继承QObject
,再私有声明Q_OBJECT
宏就可以使用Qt
的信号和槽了,实际上是Qt
利用moc
将各个类所需要的元对象代码(meta-object code
)补充好了;
moc
读取一个头文件,补充其中带有Q_OBJECT
宏类的元对象代码,一般生成一个moc_ClassName.cpp
文件。
uic
:用户界面编译器(User Interface Compiler
),用来编译ui
界面文件的;rcc
:资源编译器(Resource Compiler
),把qrc
文件编译成对应的C++
代码;所以在CMake
工程中使用Qt
首先要搞明白如何调用这些工具。
然后,类似所有第三方库的使用,在CMake
中如何链接Qt
的库,找到对应的头文件也需要我们搞清楚。
下面我们带着这些问题继续。
首先对于moc uic rcc
这几位大佬,处理起来竟然出奇地简单:
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
设置了这几个变量后,会在需要时自动调用这几个编译器,不得不说这还是十分人性化的。
在添加exe
时的语法也很易于理解:
add_executable(TestQtCMake
WIN32
src/main.cpp
src/mainwindow.cpp
src/mainwindow.h
src/mainwindow.ui
)
但其中的WIN32
参数可能需要提示一下:如果提供了WIN32
,则将设置WIN32_EXECUTABLE
变量为ON
,此时将生成一个界面程序而不是控制台程序。
然后是添加库,使用了find_package()
函数,官方说明见此处。这里简要说明用法如下:
find_package(Qt5 COMPONENTS Widgets REQUIRED)
首先,要使用find_package()
函数,需要提供一个.cmake
文件,如何让CMake
知道这个文件,可以采用两种办法:
CMAKE_PREFIX_PATH
,值为Qt5安装位置,这是官方Qt-CMake
教程中的推荐做法;CMake
中Qt5_DIR
变量,值为Qt5Config.cmake
文件的位置。可以使用Everything
搜一下文件位置,笔者这里举例:set(Qt5_DIR D:/APPs/Qt/5.14.2/5.14.2/msvc2017_64/lib/cmake/Qt5/)
从上方目录可以看出来,这个.cmake
文件是不同Qt版本和不同编译平台都有一套,所以对于官方推荐做法笔者并不是很推荐,难不成当需要换平台的时候还去改环境变量?
另外,其中有几个关键词:
REQUIRED
:必须找到该库,找不到就报错;COMPONENTS
:从库中找子模块,此处找的是Widgets
;有一点值得提出的是:在qmake
工程中的QT += core widgets
语句也是添加模块,这些模块其实就是库文件,windows
平台可以在Qt
安装目录下找到Qt5Core.lib
文件,如笔者的目录是:
D:\APPs\Qt\5.14.2\5.14.2\msvc2017_64\lib
最后别忘了将Qt
库链接到可执行文件:
target_link_libraries(TestQtCMake Qt5::Widgets)
在官方文档中,还有这么一个小片段:当CMake
版本小于3.7.0
时,将CMAKE_INCLUDE_CURRENT_DIR
变量设置为ON
。
if(CMAKE_VERSION VERSION_LESS "3.7.0")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif()
该变量的含义为:将 CMAKE_CURRENT_SOURCE_DIR
和 CMAKE_CURRENT_BINARY_DIR
添加到包含目录中,这对out-of-source
编译很有帮助。具体可参考官方说明。
笔者的猜想是为了把rcc moc uic
的输出文件添加进生成对象。但是为何在CMake
版本小于3.7.0
才设置,不是很明白。查看CMake
官方3.6.3
和3.8.2
版本对于该变量的解释也没看出区别来,希望知道的朋友能给个提示~~~
此处贴上在CMake
中使用Qt5
的完整CMakeLists.txt
文件,大家可以看看是否每一句都完全掌握了:
# cmake最低要求
cmake_minimum_required( VERSION 3.1.0 )
# 设置moc rcc uic
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
# 求大家解惑
if(CMAKE_VERSION VERSION_LESS "3.7.0")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif()
# 声明一个项目
project(QtCMakeProject)
# 提供位置定位.cmake文件
set(Qt5_DIR D:/APPs/Qt/5.14.2/5.14.2/msvc2017_64/lib/cmake/Qt5/)
# 查找Qt库
find_package(Qt5 COMPONENTS Widgets REQUIRED)
# 添加可执行文件,注意添加WIN32,否则有一个控制台黑框
add_executable(TestQtCMake
WIN32
src/main.cpp
src/mainwindow.cpp
src/mainwindow.h
src/mainwindow.ui
)
# 链接Qt库
target_link_libraries(TestQtCMake Qt5::Widgets)
总算弄完了,cmake ..
之后赶紧跑VS
里面编译运行一下试试:
对于缺少dll
文件,处理起来应该是相当熟悉了,可以在环境变量中设置Path
,把Qt
的bin
目录添加进来,如笔者此处添加:
D:\APPs\Qt\5.14.2\5.14.2\msvc2017_64\bin
但windows
平台也可以使用官方的windeployqt
工具,它就在上述bin
目录下,传入exe
文件路径就可以将该exe
依赖的Qt
文件全部打包到目录下,如一开始目录下的文件:
右键->在此处打开powershell
窗口,输入命令:
D:\APPs\Qt\5.14.2\5.14.2\msvc2017_64\bin\windeployqt.exe .\TestQtCMake.exe
等待1~2s
执行结束,目录下变成了:
这下就可以愉快地运行了,虽然啥也没有……
要在CMake
中使用Qt
,需要做以下步骤:
CMAKE_AUTO***
为ON
以启用自动rcc uic moc
编译器;QT5_DIR
变量定位.cmake
文件,使用find_package()
函数定位Qt
的库文件,使用target_link_libraries()
函数链接Qt
库;windeployqt
工具打包依赖项。有兴趣可以再参考一下Qt
官方教程:Get started with CMake。
后续计划参考笔者的另一篇文章:用于创建CMake-MSVC工程的Python脚本,写个Python
脚本来完成本文的工作。
如有错误欢迎指正,共同进步~