# cmake-tutorial **Repository Path**: demon0511/cmake-tutorial ## Basic Information - **Project Name**: cmake-tutorial - **Description**: CMake学习^^ - **Primary Language**: C++ - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-07-08 - **Last Updated**: 2023-07-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: cmake, Cpp ## README # CMake学习 [TOC] # 0 准备 ## 0.1 实验环境 - 主机:Windows - 命令行:WSL(Windows Subsystem for Linux), Ubuntu-20.04 - 依赖:Cmake3.20.0(构建工具),gcc9.4.0(编译工具) ```bash # Cmake3.20.0 (Unbuntu22版本会自动安装最新版,但20版本需要手动安装) cd $HOME sudo apt update sudo apt install -y libssl-dev wget https://github.com/Kitware/CMake/releases/download/v3.20.0/cmake-3.20.0-linux-x86_64.tar.gz tar -xzvf cmake-3.20.0-linux-x86_64.tar.gz echo 'export PATH="$HOME/cmake-3.20.0-linux-x86_64/bin:$PATH"' >> ~/.bashrc source ~/.bashrc cmake --version # gcc sudo apt-get install gcc ``` ## 0.2 教程链接 [CMake实践应用专题 - 知乎 (zhihu.com)](https://www.zhihu.com/column/c_1369781372333240320) [CMake 良心教程,教你从入门到入魂 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/500002865) # 1 CMake构建 > [CMake应用:基础篇 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/367808125) > > [CMake 良心教程,教你从入门到入魂 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/500002865) > > [冷风 - 知乎 (zhihu.com)](https://www.zhihu.com/people/sprout37/posts) ## 1.1 CMake/Makefile/gcc的关系 - gcc(GNU Compiler Collection)将源文件编译(Compile)成可执行文件或者库文件 - 当需要编译的东西很多时,需要说明先编译什么,后编译什么,这个过程称为构建(Build)。常用的工具是make,对应的定义构建过程的文件为`Makefile` - 由于编写Makefile对于大型项目又比较复杂,通过CMake就可以使用更加简洁的语法定义构建的流程,CMake定义构建过程的文件为`CMakeLists.txt` ## 1.2 cmake命令 - CMake提供cmake、ctest和cpack三个命令行工具分别负责构建、测试和打包。本文只介绍cmake命令,通过`cmake --help`可以看到cmake命令的使用方法,以下列举常见使用方法和可选参数: - Usage(3种方法) ```bash cmake [options] cmake [options] cmake [options] -S -B ``` - Specify a source directory to (re-)generate a build system for it in the current working directory. - Specify an existing build directory to re-generate its build system. - Options | 参数 | 含义 | | ------------------------------- | -------------------------------------------------------- | | -S \ | 指定源文件根目录,必须包含一个CMakeLists.txt文件 | | -B \ | 指定构建目录,构建生成的中间文件和目标文件的生成路径 | | -D \[:\]=\ | 指定变量, -D后面的空格可以省略 | | -G \ | 指定编译器,系统所有可用编译器在`cmake --help`的末尾显式 | | --build \ | 执行构建,Build a CMake-generated project binary tree. | ## 1.3 CMake使用流程 1. 生成构建系统(buildsystem,比如make工具对应的Makefile) ```bash cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DAUTHOR=RealCoolEngineer ``` - `-S .`:指明使用当前目录`.`作为源文件目录,其中包含`CMakeLists.txt`文件 - `-B build`:使用`build`目录作为构建目录,执行完成后,在项目的根目录下会创建build目录,其中生成了`Makefile`文件。这里创建了一个 build 目录存放编译产物,可以避免编译产物与代码文件混在一起,这种叫做外部构建;还有一种内部构建,即直接在项目根目录下进行构建系统与编译,会使得项目文件很混乱,一般直接用外部构建即可。 - 设定变量`CMAKE_BUILD_TYPE`的值为`Debug`,变量`AUTHOR`的值为`RealCoolEngineer` 2. 执行构建(比如make),生成目标文件 - 可以直接使用cmake命令: ```bash cmake --build build ``` - 也可以使用等价的make命令: ```bash cd build && make && cd .. ``` 3. 执行测试、安装或打包 ## 1.4 build目录介绍 - build 目录用来存放 cmake 构建和编译的产物,大致如下 ```txt build/ CMakeFiles/ lib/ 如果有库就会生成 cmake_install.cmake CMakeCache.txt demo 即CMakeLists.txt中设置的project名称 config.h 即CMakeLists.txt中设置的configure_file名称 Makefile ``` - 其中 - `lib/`文件夹存放库文件 - `CMakeCache.txt` 文件缓存变量 - `demo`是生成的执行文件,通过该文件运行程序 - `config.h` 是用于配置信息的头文件,是 cmake 根据 `config.h.in` 文件自动生成的。 - `Makefile` 是 cmake 根据顶级 CMakeLists.txt 生成的构建文件,通过该文件可以对整个项目进行编译。 - 由于CMake会缓存信息,因此重复运行`cmake -B build` 时就可以直接用缓存的值,就不需要重新检测编译器、检测编译特性是否支持C++17等信息。但有时候外部的情况有所更新(比如编译器卸载了,CMake却还是指向原来的地址),这时候 CMake 里缓存的却是旧的值,会导致一系列问题。 - 最简单的方法就是删除build文件夹然后重新`cmake -B build` - Linux:rm -rf build - Windows:rd /s /q build - 删 build 虽然彻底,也会导致编译的中间结果(`.o`文件)都没了,重新编译要花费很长时间。如果只想清除缓存,不想从头重新编译,可以只删除 `CMakeCache.txt` 这个文件,因为它里面装的就是缓存的变量,删了他就可以让 CMake 强制重新检测一遍所有库和编译器。 - p.s. 90%的CMake错误都是缓存未更新导致的! ## 1.5 编码1:构建最小项目 - 项目结构 ```txt |_ cmake-tutorial/ |_ 1/ CMakeLists.txt main.cpp ... ``` - main.cpp ```cpp #include int main() { std::cout << "Hello CMake!" << std::endl; return 0; } ``` - CmakeList.txt ```cmake cmake_minimum_required(VERSION 3.20) # set the project name project(demo) # add the executable add_executable(demo main.cpp) ``` - 构建与执行 ```bash cd 1 && cmake -B build && cmake --build build && build/demo && cd .. ``` # 2 CMake语法 > [CMake应用:核心语法篇 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/368701263) > > [CMake 良心教程,教你从入门到入魂 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/500002865) > > [CMake 入门实战 | HaHack](https://www.hahack.com/codes/cmake/) ## 2.1 CMake命令类型 CMake语言有3种命令类型: 1. 脚本命令([Scripting Commands](https://cmake.org/cmake/help/v3.21/manual/cmake-commands.7.html#id3)):always available. - 例如`if`、`else`等命令 2. 项目配置命令([Project Commands](https://cmake.org/cmake/help/v3.21/manual/cmake-commands.7.html#id4)):available only in CMake projects. - 例如`add_executable`、`include_directories `、`set_target_properties `等命令 3. 测试命令([CTest Commands](https://cmake.org/cmake/help/v3.21/manual/cmake-commands.7.html#id5)):available only in CTest scripts. - 都是`ctest_`开头的命令 ## 2.2 CMake文件类型 CMake语言在项目配置中组织为3种源文件类型: 1. 目录:`CMakeLists.txt`,针对的是一个目录,描述如何针对目录(Source tree)生成构建系统,会用到项目配置命令; 2. 脚本:`