当前位置: 首页 > news >正文

Cmake相关概念

目录

前言

1. CMake 的基本概念

2. CMake 的基本结构

3. CMake 的核心命令

3.1. cmake_minimum_required

3.2. project

3.3. set

3.4. add_executable 和 add_library

3.5. target_include_directories

3.7. find_package

4. 构建和使用 CMake

4.1. 编写 CMakeLists.txt

4.2. 配置和生成构建文件

4.3. 编译项目

5. 高级 CMake 特性

5.1. 配置头文件

5.2. 使用自定义命令

5.3. 支持多种构建类型

6. 跨平台构建

7. CMake 常用命令总结

8. 复杂项目的组织


前言

CMake 是一个跨平台的构建系统生成工具,用于管理编译过程的自动化,特别适用于大型、复杂的 C/C++ 项目。与 Makefile 不同的是,CMake 可以生成适用于不同平台的构建系统,如 Makefiles、Visual Studio 项目文件等。CMake 的配置文件通常是 CMakeLists.txt,它包含项目的构建规则。

1. CMake 的基本概念

CMake 的核心功能是生成构建系统。CMake 使用一种称为“生成器”的工具,根据配置文件生成适合特定平台的构建文件,如 Makefile 或 Visual Studio 项目文件。

  • CMakeLists.txt:这是 CMake 的配置文件,定义了项目结构、依赖关系、编译选项等。
  • 构建目录(Build Directory):CMake 将生成的构建文件放在这个目录中,通常与源代码目录分开。
  • 生成器(Generator):指 CMake 用于生成构建文件的工具,如 Unix Makefiles、Ninja、Visual Studio 等。

2. CMake 的基本结构

一个简单的 CMakeLists.txt 文件通常包含以下内容:

cmake_minimum_required(VERSION 3.10)
project(MyProject)set(CMAKE_CXX_STANDARD 11)add_executable(my_program main.cpp utils.cpp)

解释:

  • cmake_minimum_required:指定 CMake 的最低版本要求。
  • project:定义项目的名称。
  • set:设置变量,这里指定 C++ 标准为 C++11。
  • add_executable:指定要生成的可执行文件及其源文件。

3. CMake 的核心命令

3.1. cmake_minimum_required

这个命令定义了项目所需的最低 CMake 版本。确保用户使用的 CMake 版本不低于这个版本。

cmake_minimum_required(VERSION 3.10)

3.2. project

定义项目名称及其元数据(如语言类型等)。这个命令会自动定义一些变量,如 PROJECT_NAMEPROJECT_SOURCE_DIR 等。

project(MyProject VERSION 1.0 LANGUAGES CXX)

3.3. set

用于设置变量值。在 CMake 中,变量通常用 CMAKE_ 前缀标识系统变量,而用户自定义变量可以自行命名。

set(CMAKE_CXX_STANDARD 11)

3.4. add_executableadd_library

  • add_executable:指定要生成的可执行文件。
  • add_library:指定要生成的库文件(静态库或动态库)。
add_executable(my_program main.cpp utils.cpp)
add_library(my_library SHARED mylib.cpp)

参数说明:

  • SHARED:生成动态库。
  • STATIC:生成静态库(默认)。
  • OBJECT:生成对象文件。

3.5. target_include_directories

指定目标的头文件搜索路径。通常用于包含外部库的头文件路径。

target_include_directories(my_program PRIVATE ${CMAKE_SOURCE_DIR}/include)

参数说明:

  • PRIVATE:只对该目标有效。
  • PUBLIC:对该目标和依赖该目标的其他目标有效。
  • INTERFACE:只对依赖该目标的其他目标有效。

为目标指定链接的库。这可以包括静态库、动态库或系统库。

target_link_libraries(my_program PRIVATE my_library)

3.7. find_package

查找并引入外部库或包。CMake 支持多种查找模块,如 FindBoost.cmakeFindOpenCV.cmake 等。

find_package(Boost REQUIRED COMPONENTS filesystem)
target_link_libraries(my_program PRIVATE Boost::filesystem)

参数说明:

  • REQUIRED:如果未找到包,则终止配置。
  • COMPONENTS:指定要查找的组件。

4. 构建和使用 CMake

假设我们有一个包含 main.cpputils.cpp 的简单项目,并且头文件在 include/ 目录中。

4.1. 编写 CMakeLists.txt

cmake_minimum_required(VERSION 3.10)project(MyProject VERSION 1.0 LANGUAGES CXX)set(CMAKE_CXX_STANDARD 11)include_directories(${CMAKE_SOURCE_DIR}/include)add_executable(my_program src/main.cpp src/utils.cpp)target_include_directories(my_program PRIVATE ${CMAKE_SOURCE_DIR}/include)

4.2. 配置和生成构建文件

在项目根目录下创建一个 build/ 目录,并在其中执行 CMake 命令:

mkdir build
cd build
cmake ..

这个过程会生成 Makefile 或其他平台的构建文件。

4.3. 编译项目

使用生成的构建文件来编译项目:

make

执行完这条命令后,my_program 可执行文件将生成在 build/ 目录中。

5. 高级 CMake 特性

5.1. 配置头文件

CMake 可以生成配置头文件,通常用于定义一些编译时的常量。

configure_file(${CMAKE_SOURCE_DIR}/config.h.in${CMAKE_BINARY_DIR}/config.h
)target_include_directories(my_program PRIVATE ${CMAKE_BINARY_DIR})

config.h.in 的内容可能如下:

#define PROJECT_VERSION_MAJOR @MyProject_VERSION_MAJOR@
#define PROJECT_VERSION_MINOR @MyProject_VERSION_MINOR@

CMake 会用实际的版本号替换 @...@ 中的内容。

5.2. 使用自定义命令

自定义命令可以执行特定任务,如代码生成或数据转换。

add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/generated.cppCOMMAND python generate_code.py > ${CMAKE_BINARY_DIR}/generated.cppDEPENDS generate_code.py
)

这个命令将在构建时调用 generate_code.py 脚本生成 generated.cpp

5.3. 支持多种构建类型

CMake 支持多种构建类型,如 DebugReleaseMinSizeRelRelWithDebInfo。可以通过 CMAKE_BUILD_TYPE 变量进行控制。

cmake -DCMAKE_BUILD_TYPE=Release ..

可以在 CMakeLists.txt 中设置默认的构建类型:

set(CMAKE_BUILD_TYPE Release)

6. 跨平台构建

CMake 的强大之处在于它的跨平台性。CMake 可以为不同的开发环境生成相应的构建文件:

  • Unix 系统:生成 Unix Makefile。
  • Windows 系统:生成 Visual Studio 项目文件或 NMake Makefiles。
  • macOS 系统:生成 Xcode 项目文件。

在 Windows 上使用 Visual Studio:

cmake -G "Visual Studio 16 2019" ..

7. CMake 常用命令总结

  • cmake_minimum_required:设置最低 CMake 版本要求。
  • project:定义项目名称及语言。
  • set:设置变量。
  • add_executable / add_library:定义可执行文件或库。
  • target_include_directories:设置头文件搜索路径。
  • target_link_libraries:设置链接的库。
  • find_package:查找并引入外部库。
  • include_directories:添加头文件目录。
  • configure_file:生成配置文件。
  • add_custom_command:添加自定义构建命令。
  • add_subdirectory:添加子目录,使其包含的 CMakeLists.txt 文件参与构建。

8. 复杂项目的组织

在复杂项目中,通常会将代码组织为多个子模块,每个子模块都有自己的 CMakeLists.txt 文件。主 CMakeLists.txt 通过 add_subdirectory 将这些模块引入。

示例:

项目结构如下:

MyProject/
│
├── src/
│   ├── main.cpp
│   └── utils.cpp
├── include/
│   └── utils.h
├── lib/
│   ├── CMakeLists.txt
│   └── mylib.cpp
├── CMakeLists.txt
└── build/

CMakeLists.txt 文件:

cmake_minimum_required(VERSION 3.10)
project(MyProject VERSION 1.0 LANGUAGES CXX)set(CMAKE_CXX_STANDARD 11)add_subdirectory(lib)include_directories(${CMAKE_SOURCE_DIR}/include)add_executable(my_program src/main.cpp src/utils.cpp)target_link_libraries(my_program PRIVATE mylib)

lib/CMakeLists.txt 文件:

add_library(mylib STATIC mylib.cpp)

这个项目将 lib 目录作为一个子模块进行编译,并将其链接到主程序中。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • HikariCP源码分析之源码环境搭建
  • 优化MySQL性能的方法
  • C#知识|语法拾遗:分支结构、循环
  • spark-sql 写入paimon主键表报错 Cannot write nullable values to non-null column
  • MegaCLI和H750阵列卡不匹配导致的服务夯死
  • 第二证券:两融账户开通需要的条件?证券两融开户?
  • Android中几种线程交互方式
  • uniapp开发安卓app--安卓低版本(4.4)不显示echarts图表问题解决思路
  • DataX
  • ES6 -- 总结 03
  • Linux网络编程——C/C++Web服务器(二):IO多路复用select/poll/epoll实现服务器监听多客户端事件
  • Java 使用 POI 导出Excel,实现单元格内容为下拉选项
  • 《计算机操作系统》(第4版)第10章 多处理机操作系统 复习笔记
  • Elasticsearch对象映射
  • 神经网络算法 - 一文搞懂Back Propagation(反向传播)
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • canvas绘制圆角头像
  • Centos6.8 使用rpm安装mysql5.7
  • conda常用的命令
  • HTTP请求重发
  • js写一个简单的选项卡
  • Lsb图片隐写
  • Node项目之评分系统(二)- 数据库设计
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • RxJS: 简单入门
  • Spring Boot快速入门(一):Hello Spring Boot
  • vue-cli在webpack的配置文件探究
  • 基于HAProxy的高性能缓存服务器nuster
  • 简单易用的leetcode开发测试工具(npm)
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 一个项目push到多个远程Git仓库
  • 怎么将电脑中的声音录制成WAV格式
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #Datawhale AI夏令营第4期#AIGC方向 文生图 Task2
  • (003)SlickEdit Unity的补全
  • (C++)栈的链式存储结构(出栈、入栈、判空、遍历、销毁)(数据结构与算法)
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (独孤九剑)--文件系统
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (每日一问)基础知识:堆与栈的区别
  • (图)IntelliTrace Tools 跟踪云端程序
  • (一)utf8mb4_general_ci 和 utf8mb4_unicode_ci 适用排序和比较规则场景
  • (转)Oracle存储过程编写经验和优化措施
  • (转载)深入super,看Python如何解决钻石继承难题
  • .mat 文件的加载与创建 矩阵变图像? ∈ Matlab 使用笔记
  • .NET 8.0 中有哪些新的变化?
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .net core 的缓存方案
  • .net 调用php,php 调用.net com组件 --