上次写了一篇《C++大型项目管理:通用CMake框架的架构奥秘》 的文章,有读者私信反馈,讲的有些深入,能否做更详细的介绍。当时答应了,于是便有了这篇文章的产生,期望能更好的帮助学习者。

0 导言

本文假设读者了解CMake的基础语法。

本文适合C++相关项目。

1 概述

相比传统CMake,现代CMake强化了模块化、标准化的设计思想,提供了大量基于target的设计模式。

编写现代CMake的几个重要思想:

  1. 核心是Target(构建目标)
  2. 像编程一样认真对待CMake代码
  3. 模块化
    1. 利用CMake提供的Public传播等特性自动管理依赖等关系
    2. 避免全局更改,而是使用带有作用域的target相关函数

本文内容:

  • CMake项目结构
  • CMakeLists写法参考

2 CMake项目结构

2.1 目录结构

对于只有单个库的仓库,项目结构如下:

<project_name>/
├── .gitignore
├── CMakeLists.txt
├── README.md
├── inc
│   └── <project_name>
│       └── foo.h
├── src
│   ├── CMakeLists.txt
│   └── foo.cpp
├── tests
│   ├── CMakeLists.txt
│   └── test_foo.cpp
├── cmake
│   ├── FindBar.cmake
│   └── Custom.cmake
└── ext
    ├── submodule1/
    └── submodule2/

其中各个文件夹的命名并不强制,只是一种推荐。例如inc也可以使用include,tests和test也可以互换,ext也可以换成诸如thirdparty等命名。命名清晰即可。

也可以根据需求添加文件夹,如doc,script等。

重要的文件(夹)作用:

  • 项目根目录下的CMakeLists.txt被称为主CMakeLists;
  • inc包含项目导出的头文件。inc下需要放置一个和项目同名的文件夹,并将头文件放置在其中;
    • 非导出的头文件可以自行处置。比如新开一个pri文件夹,或是直接放在src中;
  • src包含项目的源码;在src下需要有一个CMakeLists.txt;
  • tests包含测试代码;同样需要CMakeLists.txt;
  • cmake文件夹包含CMake相关的脚本,包括查找包的脚本和项目使用到的工具脚本;
  • ext包含项目用到的三方库;
    • 一个推荐的方式是git submodule。

注意inc中并没有CMakeLists.txt。这是因为安装编好的库的时候一般是要将inc内的内容拷到系统include目录的。

对于有多个子项目的仓库,参考结构如下:

<project_name>/
├── .gitignore
├── CMakeLists.txt
├── README.md
├── subproj1
│   ├── inc
│   ├── src
│   └── CMakeLists.txt
├── subproj2
│   ├── inc
│   ├── src
│   └── CMakeLists.txt
├── cmake
└── ext

其中各个子项目的结构可以参考单库仓库。

2.2 主CMakeLists

主CMakeLists是项目根目录下的CMakeLists.txt。该文件包含的主要内容:

  • 项目整体配置
  • 项目子文件夹

具体的target等应在各个子文件夹中的CMakeLists中定义。

以下是一个简单的示例:

## 最低版本要求
cmake_minimum_required(VERSION 3.20)
# 也可以指定一个范围
# cmake_minimum_required(VERSION 3.20...3.22)
 
## 项

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部