用CMake管理自己的程序(一)

本文详细解析CMakeLists.txt的基本概念,包括命令、变量和包的应用,以一个Qt程序为例,演示如何设置CMAKE版本、工程名称、使用find_package管理Qt库,以及如何使用自定义变量和内置变量组织源代码和链接依赖。

前言

CMake是一个非常常用的构建管理软件,本质上它并不负责程序的构建,但是会为程序构建提供足够多的信息,以便生成一个当前平台支持的make文件或工程文件。
CMake的使用可以分为两大部分:程序构建与程序管理
程序构建是指如何通过CMake生成一个平台支持的make文件或工程文件,CMake还自带一个GUI程序帮忙做这件事,比较简单就不多说了。程序管理是指如何用CMake去组织一个程序中的各个文件,将其当作工程文件的过程,主要就是搞明白CMakeList.txt这个文件要如何编写。这篇文章主要针对的是程序管理。

基础概念

在CMake用作工程管理的时候,我们需要了解CMakeLists.txt文件中几个基础概念:

  • 命令
    也就是CMake中的“函数”,我们可以通过命令进行各种各样的操作,大部分情况下,我们使用命令都是为了设置“变量”。
  • 变量
    可以是内部变量,也可以是自定义变量。变量最终会在编译期起到各式各样的作用。比如有的变量可以用来指定编译过程中要自动化的执行哪些操作,有些变量是告诉编译器编译一个程序要用哪些源代码等等。

  • 由第三方库提供的,方便用户在CMake中快速指定依赖库的方法。不使用包的时候,就需要人工指定某个库所在的路径和库的名称了。

下面我们可以通过一个例子来更好的理解如何用CMake管理程序

一个Qt程序

如果大家使用QtCreator创建一个新程序并选择使用CMake而不是qmake管理的时候,QtCreator会自动的为我们生成一个CMake文件(CMakeLists.txt),初看这个CMake非常的复杂,不过不用怕,让我们化简一下(真正需要的时候还可以再加回去):
考虑到我们使用Qt5,那么所有里面的Qt6部分都可以化简,考虑我们不用Android,Android相关的部分也要化简, 不考虑MACOS,化简,最终结果就是:
简单的CMakeLists.txt
让我们分析一下:
第1行很简单就能理解,设置cmake的最小允许的版本。因为cmake有很多个版本,不同版本之间的功能有所不同,为了能够正确使用,我们就需要限制一个最小的版本。Qt默认限制的是3.5,这个基本不需要修改。
第3行,就是定义我们工程的名称,版本号以及使用的语言。CXX就是c++语言。
从第5行开始到12行结束,我们使用了set命令,设置了各种各样的变量,从变量的名字我们就可以大概了解这些变量的作用:CMAKE表示CMAKE内置的变量,基本上就是设置了查找文件的时候要包含当前目录,开启自动UIC,开启自动MOC,开启自动RCC(这些都是Qt在编译过程中要用到的预处理工具),然后设定了C++标准是C++11,并且设置了强制C++标准.
第14行,我们使用find_package命令来查找Qt5提供的组件Widgets(可以用空格分割以便同时查找其它的组件,例如Sql,Network等),也就是Qt5中相应的库文件。这个查找结果保存在了Qt5这个变量中,我们以后会使用得到。
注意:Qt5是一个固定的名字,他就是表示了Qt5,换成别的名字就会导致cmake去查找其它的包,所以为了找到Qt5,我们只能用这个名字。最后的REQUIRED表示Qt5是必须的,如果找不到这个库,就会编译失败。(考虑到c接口的库是动态加载的,也就是说找不到也不会导致编译失败,只是运行时功能缺失而已。但是Qt库由于是C++接口,找不到就会直接编译失败。)
16行到20行,我们使用set命令设置了一个叫做PROJECT_SOURCES的变量,这个变量不是CMAKE开头的,很显然,是一个自定义变量,它可以起名叫做任何名字,但是之所以叫做PROJECT_SOURCES,就是因为我们接下来要定义的,就是我们工程中,都要包含哪些源代码。使用换行作为分隔符,我们一共添加了4个文件作为我们的源代码,其中还有一个ui文件。注意,当我们要设置多个文件的时候,我们可以使用空格或换行作为分割。
23行到25行,我们使用add_executable命令,添加一个可执行程序,名字叫做test,这个程序的所有源码,则由PROJECT_SOURCES这个变量提供,不过不使用变量,则可以像变量设置一样,通过空格或换行分割提供。
最后,第27行,我们通过target_link_libraries命令告诉cmake,test这个可执行程序需要的第三方库是Qt5中的Widgets,也就是之前find_package命令查找到的Qt5这个包中Widgets模块。

复习

set命令: 可以设置各种各样变量的值。如果一个变量是一个文件列表,则文件之间可以使用空格或换行分割
find_package命令:可以用于查找第三方库。如果不使用该命令查找包,则最终指定目标依赖的库的时候,就需要手动的写明库的路径和文件名了。
add_executable命令:指定工程中一个可执行程序的名字,以及编译这个可执行程序所需要的所有的源文件。对于Qt程序来说,ui文件,qrc文件也属于源文件的一部分,也需要一并指定。

CMAKE_XXXXX变量:CMAKE开头的变量是CMAKE的内置变量,基本上其含义都可以“望文生义”,可以根据需要设置。其中为了要编译Qt程序,特别的需要设置 CMAKE_AUTOUICCMAKE_AUTOMOCCMAKE_AUTORCC 这三个变量的值为ON,也就是开启自动调用uid,moc与rcc。

### 如何使用 Qt 和 CMake 管理程序结构 在现代软件开发中,使用 CMake 和 Qt 结合可以高效地管理复杂的程序结构。以下是如何通过 CMake 来组织和构建个基于 Qt 的项目。 #### 1. 基础概念 CMake个跨平台的构建工具,用于生成 Makefile 或工程文件,从而简化构建流程[^1]。Qt 提供了 qmake 工具来管理 Qt 项目的构建过程,但随着项目的复杂性增加,CMake 成为了更灵活的选择[^3]。 #### 2. CMakeLists.txt 文件配置 CMake 使用 `CMakeLists.txt` 文件来描述项目的结构和依赖关系。以下是配置 Qt 项目的基本步骤: - **设置最低版本要求** 首先需要指定 CMake 的最低版本要求,确保兼容性。 ```cmake cmake_minimum_required(VERSION 3.15) ``` - **定义项目名称** 定义项目的名称和编程语言。 ```cmake project(MyQtProject LANGUAGES CXX) ``` - **查找 Qt 模块** 使用 `find_package` 命令加载 Qt 模块。例如: ```cmake find_package(Qt5 COMPONENTS Core Widgets REQUIRED) ``` - **添加可执行文件** 使用 `add_executable` 添加主程序文件,并将源文件列出。 ```cmake add_executable(${PROJECT_NAME} main.cpp mainwindow.cpp mainwindow.h) ``` - **链接 Qt 库** 将 Qt 的库与目标链接起来。 ```cmake target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Widgets) ``` #### 3. 引入资源文件(qrc) 如果项目中有资源文件(如图片、图标等),可以通过 `qt5_add_resources` 命令将其编译为 C++ 代码[^2]。 ```cmake set(RESOURCES resources.qrc) qt5_add_resources(QRC_RESOURCES ${RESOURCES}) add_executable(${PROJECT_NAME} main.cpp mainwindow.cpp mainwindow.h ${QRC_RESOURCES}) ``` #### 4. 引入第三方库 若项目需要引入第三方库,可以使用 `link_directories` 或 `target_link_libraries` 来指定库路径和链接库文件[^5]。 ```cmake link_directories(/path/to/thirdparty/libs) target_link_libraries(${PROJECT_NAME} PRIVATE thirdpartylib) ``` #### 5. 组织多模块项目 对于大型项目,可以将不同功能模块分离到不同的子目录中,并通过 `add_subdirectory` 命令引入。 ```cmake add_subdirectory(modules/module1) add_subdirectory(modules/module2) ``` #### 6. 完善构建规则 通过 `target_*` 系列命令,可以进步完善构建规则,例如指定头文件路径、编译选项等[^4]。 ```cmake target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/include) target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra) ``` ### 示例代码 以下是个完整的 `CMakeLists.txt` 示例: ```cmake cmake_minimum_required(VERSION 3.15) project(MyQtProject LANGUAGES CXX) # 查找 Qt 模块 find_package(Qt5 COMPONENTS Core Widgets REQUIRED) # 添加资源文件 set(RESOURCES resources.qrc) qt5_add_resources(QRC_RESOURCES ${RESOURCES}) # 添加可执行文件 add_executable(${PROJECT_NAME} main.cpp mainwindow.cpp mainwindow.h ${QRC_RESOURCES} ) # 链接 Qt 库 target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Widgets) # 引入第三方库 link_directories(/path/to/thirdparty/libs) target_link_libraries(${PROJECT_NAME} PRIVATE thirdpartylib) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值