ubuntu下用cmake编译Qt5(保姆级教程)

  • Post author:
  • Post category:其他


0 废话在前

近日想要同时使用Qt和Opencv来完成一个小项目,但是在Qtcreator里面配置Opencv太麻烦,而且考虑到以后也有可能加入更多的第三方库,因此干脆用cmake来进行管理。

目前CSDN上的教程基本都是一大抄,并且有许多错误之处,因此干脆自己摸索着写了一版。

观看本教程之前,最好


有一定的cmake和Qt编程基础


1 Qt编译过程

众所周知,C++编译四大步骤:预处理、编译、汇编、链接。

Qt当然也逃不出这四步,但是Qt也要增加一个步骤。原因在于Qt有其相应的语法扩展,比如在使用到自定义的信号与槽函数的时候,我们需要在头文件中定义类时需要在头部加上“Q_OBJECT”这个宏,但标准的C++编译器可看不懂这是什么意思,因此需要在第一步预处理之前先使用Qt的预编译器MOC来处理Qt中的扩展语法,比如Q_OBJECT,slot,signal,emit等。

举个简单的例子就是,如果你的头文件中含有Q_OBJECT这个宏,那么标准的C++编译器会在预处理的时候会将这个头文件原封不动的放入源文件之中,同时也会记录Q_OBJECT这个宏,注意,仅仅是记录,编译器不知道这是什么意思,只是先不报错,最后会再链接这一步当中去链接的其他文件中找这个宏的定义,因此MOC的作用就是生成一个新的.cpp文件,具体定义了这个宏,最后在链接到我们的源文件之中,编译器就能通过这个文件知道这个宏是什么意思了。

大致过程如图所示。

那么对于.ui以及.qrc文件该怎么编译呢?实际上,Qt也提供了UIC和RCC两中处理,前者将.ui文件转换成.h文件,后者将.qrc文件转换成.cpp文件。于是整个Qt的编译过程如图所示。

2 cmake文件编写

工作空间下工程目录如图所示。

bin:存放可执行文件

build:存放编译过程中产生的文件

include:存放自定义的头文件

qrc:存放.qrc文件

src:存放源代码.cpp文件

ui:存放.ui文件

具体写法如下:

cmake_minimum_required(VERSION 3.10.0)

project(Build_Qt_Demo)

#开启MOC、RCC和UIC,则会在预处理之前先进行MOC、RCC和UIC操作
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

#设置UIC的查找路径,UIC默认会在引用ui头文件的源代码路径下查找ui文件,而我们的ui文件存放在/ui文件夹下
set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_SOURCE_DIR}/ui)

#设置可执行文件的输出路径,默认在哪个路径编译则会放在哪个路径,而我们是在/build下编译,要存放在/bin路径
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)

#查找需要的Qt包
find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED)

#将各个文件夹下的所有文件打包
FILE(GLOB ${PROJECT_NAME}_SOURCES "./src/*.cpp")
FILE(GLOB ${PROJECT_NAME}_UI "./ui/*.ui")
FILE(GLOB ${PROJECT_NAME}_QRC "./qrc/*.qrc")
FILE(GLOB ${PROJECT_NAME}_HEADER "./include/*")

#将/include路径包含到查找头文件路径
include_directories(${PROJECT_SOURCE_DIR}/include)

#直接将上述的所有文件进行编译和内部链接,ui和qrc以及包含Qt扩展语法的文件由于开启了开启MOC、RCC和UIC,因此会被自行处理
add_executable(${PROJECT_NAME}
          ${${PROJECT_NAME}_UI}
          ${${PROJECT_NAME}_SOURCES}
          ${${PROJECT_NAME}_QRC}
          ${${PROJECT_NAME}_HEADER}
          )       

#和Qt的库进行链接
target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Gui Qt5::Widgets)

需要注意的是,很多教程分别使用如下命令来进行MOC、RCC和UIC操作。

#调用预编译器MOC,需要使用 QT5_WRAP_CPP宏
QT5_WRAP_CPP(${PROJECT_NAME}_SOURCE_MOC ${${PROJECT_NAME}_SOURCE})

#使用UIC处理.ui文件
QT5_WRAP_UI(${PROJECT_NAME}_UI_HEADER ${${PROJECT_NAME}_UI})

#使用RCC处理.qrc文件
QT5_ADD_RESOURCES(${PROJECT_NAME}_RCC ${${PROJECT_NAME}_UIC})

实际上以上操作全部多余,在高版本的cmake中只要开启了MOC、RCC和UIC过后完全不需要这个个操作了。

3 运行

进入/build文件夹,在该文件夹下打开终端输入以下命令即可。

cmake .. && make

随后在/bin目录下便可看到可执行文件。



版权声明:本文为qq_42823342原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。