如何查看云端系统内核版本
lsb_release -a
shiyanlou:~/ $ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.6 LTS
Release: 20.04
Codename: focal
如何查看cmake版本
cmake --version
shiyanlou:~/ $ cmake --version
cmake version 3.16.3
CMake suite maintained and supported by Kitware (kitware.com/cmake ).
错误升级cmake
sudo pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple cmake
shiyanlou:~/ $ sudo pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple cmake
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Collecting cmake
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/28/19/b54ff2e03946beeef785e6407d965a9493d26c50dd1aa09ffc7b53fbf9a5/cmake-4.2.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (28.9 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 28.9/28.9 MB 10.6 MB/s eta 0:00:00
Installing collected packages: cmake
Successfully installed cmake-4.2.1
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
notice\] A new release of pip is available: 24.0 -\> 25.0.1
\[notice\] To update, run: pip3.8 install --upgrade pip

*** ** * ** ***
## 查询更新效果cmake
失败了吧\^_\^

*** ** * ** ***
## 合理的方式
```bash
# 1. 创建并激活 Python3.8 虚拟环境
python3.8 -m venv myenv
source myenv/bin/activate
# 2. 在虚拟环境中安装/升级 cmake(无需 sudo)
pip3.8 install -i https://pypi.tuna.tsinghua.edu.cn/simple cmake==3.25.0 --upgrade
# 3. 验证版本
cmake --version
# 4. 退出虚拟环境(如需)
deactivate
```
可以指定版本,不指定版本升级到最新版。
> pip3.8 install -i https://pypi.tuna.tsinghua.edu.cn/simple cmake --upgrade

* 避免使用 `sudo pip`,优先通过**虚拟环境** 或**系统包管理器(apt)** 安装软件包;
* 若需指定 cmake 版本,可在虚拟环境中用 `pip install cmake==xxx` 精准安装。
*** ** * ** ***
## 基础入门-AI
你已经成功在虚拟环境中确认了 cmake 4.2.1 版本,接下来我会给你一个**极简且完整的 CMake 入门实例**,包含基础的 C/C++ 源码、CMakeLists.txt 编写、编译和运行全流程,让你快速掌握 CMake 的核心用法。
#### 一、实例场景
我们用 CMake 编译一个简单的 C 语言程序(计算两数之和),涵盖 CMake 最基础的指令:指定版本、项目名称、添加可执行文件。
#### 二、完整操作步骤
##### 1. 创建项目目录和源码文件
先创建一个专属目录,避免文件混乱:
bash
运行
# 创建项目目录并进入
mkdir cmake_demo && cd cmake_demo
# 创建 C 语言源码文件 main.c
touch main.c
编辑 `main.c`(可以用 vim 或 nano,新手推荐 nano):
bash
运行
nano main.c
粘贴以下代码(实现两数相加功能):
c
运行
#include
int main() {
int a = 10, b = 20;
printf("Hello CMake!\n");
printf("a + b = %d\n", a + b);
return 0;
}
按 `Ctrl+O` 保存,`Ctrl+X` 退出 nano。
##### 2. 编写核心文件 CMakeLists.txt
CMake 的核心是 `CMakeLists.txt`(文件名大小写敏感,必须这么写),创建并编辑:
bash
运行
touch CMakeLists.txt
nano CMakeLists.txt
粘贴以下内容(每行都有注释,新手易理解):
cmake
# 1. 指定 CMake 最低版本要求(匹配你的 4.2.1,也可写 3.0 以上)
cmake_minimum_required(VERSION 3.0)
# 2. 定义项目名称(自定义,比如 cmake_demo)
project(cmake_demo)
# 3. 添加可执行文件:格式为 可执行文件名 源码文件
# 这里生成的可执行文件叫 demo,源码是 main.c
add_executable(demo main.c)
同样按 `Ctrl+O` 保存,`Ctrl+X` 退出。
##### 3. 用 CMake 构建编译文件并编译
CMake 推荐**Out-of-Source Build**(外部构建,源码和编译产物分离),步骤如下:
bash
运行
# 1. 创建编译目录并进入(存放临时文件和可执行文件)
mkdir build && cd build
# 2. 运行 cmake 生成 Makefile(指定上级目录的 CMakeLists.txt)
cmake ..
# 3. 编译(等同于 make,-j 后加数字表示多核编译,更快)
cmake --build . -j2
##### 4. 运行生成的可执行文件
编译完成后,build 目录下会生成 `demo` 可执行文件,运行即可:
bash
运行
./demo
#### 三、预期输出
运行后会看到:
plaintext
Hello CMake!
a + b = 30
#### 四、核心指令解释
| 指令 | 作用 |
|---------------------------------------|---------------------------------------------|
| `cmake_minimum_required(VERSION 3.0)` | 指定 CMake 最低版本,避免兼容性问题 |
| `project(cmake_demo)` | 定义项目名称,会影响生成的文件命名、编译环境等 |
| `add_executable(demo main.c)` | 告诉 CMake:要生成一个名为 `demo` 的可执行文件,源码是 `main.c` |
| `cmake ..` | 从 build 目录向上找 CMakeLists.txt,生成 Makefile |
| `cmake --build .` | 执行编译,等价于在 build 目录运行 `make` |
#### 五、进阶小扩展(可选)
如果你的源码有多个文件(比如 `main.c` + `calc.c`),只需修改 `CMakeLists.txt`:
cmake
cmake_minimum_required(VERSION 3.0)
project(cmake_demo)
# 多个源码文件用空格分隔
add_executable(demo main.c calc.c)
#### 总结
1. CMake 核心是编写 `CMakeLists.txt`,最基础的三行指令:指定版本、项目名、添加可执行文件;
2. 推荐使用「外部构建」(创建 build 目录),避免编译产物污染源码;
3. 核心流程:`编写源码 → 编写 CMakeLists.txt → 创建 build 目录 → cmake .. → cmake --build . → 运行可执行文件`。
这个实例覆盖了 CMake 入门的核心用法,你可以基于此修改源码(比如写 C++ 程序,只需把 `.c` 改成 `.cpp`),快速熟悉 CMake 的使用逻辑。
*** ** * ** ***
## 更进一步-AI
你已经掌握了 CMake 的基础用法,接下来我为你提供一个**进阶版 CMake 实战案例** ,这个案例模拟真实项目场景:包含**多源文件、多目录结构、静态库编译、头文件路径配置、编译选项控制、版本号定义**等核心进阶特性,能帮你理解 CMake 在实际项目中的应用方式。
#### 一、进阶案例场景
我们构建一个「简易计算器」项目,结构如下(分目录管理源码和头文件,将核心计算逻辑编译为静态库,主程序链接库文件运行):
plaintext
calc_project/ # 项目根目录
├── CMakeLists.txt # 根目录CMake配置
├── include/ # 头文件目录
│ └── calc.h # 计算器函数声明
├── src/ # 源码目录
│ ├── CMakeLists.txt # 子目录CMake配置
│ ├── calc.c # 计算器函数实现
│ └── main.c # 主程序(调用库函数)
└── build/ # 编译目录(外部构建)
#### 二、完整实现步骤
##### 1. 创建项目目录结构
先按上述结构创建所有目录和文件:
bash
运行
# 创建根目录并进入
mkdir -p calc_project/{include,src,build} && cd calc_project
# 创建头文件
touch include/calc.h
# 创建子目录源码和CMake文件
touch src/calc.c src/main.c src/CMakeLists.txt
# 创建根目录CMake文件
touch CMakeLists.txt
##### 2. 编写头文件(include/calc.h)
声明计算器核心函数,同时定义版本宏(后续由 CMake 注入):
c
运行
#ifndef CALC_H
#define CALC_H
// 版本号(由CMake定义)
#define CALC_VERSION_MAJOR @CALC_VERSION_MAJOR@
#define CALC_VERSION_MINOR @CALC_VERSION_MINOR@
// 计算器核心函数声明
int add(int a, int b); // 加法
int subtract(int a, int b); // 减法
int multiply(int a, int b); // 乘法
double divide(int a, int b); // 除法(处理除零)
#endif // CALC_H
##### 3. 编写核心实现文件(src/calc.c)
实现计算器函数,包含异常处理(除零判断):
c
运行
#include "calc.h"
#include
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
int multiply(int a, int b) {
return a * b;
}
double divide(int a, int b) {
if (b == 0) {
printf("Error: 除数不能为0!\n");
return 0.0;
}
return (double)a / b;
}
##### 4. 编写主程序(src/main.c)
调用静态库函数,打印版本号和计算结果:
c
运行
#include "calc.h"
#include
int main() {
// 打印版本号
printf("=== 简易计算器 v%d.%d ===\n", CALC_VERSION_MAJOR, CALC_VERSION_MINOR);
// 测试计算
int a = 20, b = 5;
printf("%d + %d = %d\n", a, b, add(a, b));
printf("%d - %d = %d\n", a, b, subtract(a, b));
printf("%d × %d = %d\n", a, b, multiply(a, b));
printf("%d ÷ %d = %.2f\n", a, b, divide(a, b));
// 测试除零
printf("%d ÷ %d = %.2f\n", a, 0, divide(a, 0));
return 0;
}
##### 5. 编写子目录 CMake 配置(src/CMakeLists.txt)
将 `calc.c` 编译为**静态库**,并指定头文件路径:
cmake
# 1. 收集源码文件(也可直接写 calc.c,file 指令更灵活)
file(GLOB CALC_SOURCES "calc.c")
# 2. 编译静态库:库名 calc_lib,源码为 CALC_SOURCES
add_library(calc_lib STATIC ${CALC_SOURCES})
# 3. 指定头文件搜索路径(让编译器找到 include 目录的 calc.h)
# INTERFACE 表示:链接该库的目标(如 main)会继承这个头文件路径
target_include_directories(calc_lib
INTERFACE ${CMAKE_SOURCE_DIR}/include
PRIVATE ${CMAKE_SOURCE_DIR}/include
)
# 4. 添加可执行文件:主程序 main.c,生成可执行文件 calc_app
add_executable(calc_app main.c)
# 5. 链接静态库:让 calc_app 链接 calc_lib
target_link_libraries(calc_app PRIVATE calc_lib)
# 6. 设置编译选项(开启警告、C99标准)
target_compile_options(calc_app PRIVATE -Wall -std=c99)
target_compile_options(calc_lib PRIVATE -Wall -std=c99)
##### 6. 编写根目录 CMake 配置(CMakeLists.txt)
配置项目版本、全局编译选项、包含子目录:
cmake
# 1. 指定CMake最低版本
cmake_minimum_required(VERSION 3.0)
# 2. 项目名称、版本号、语言(C语言)
project(CalcProject
VERSION 1.0 # 版本号 1.0(MAJOR=1,MINOR=0)
LANGUAGES C # 指定编译语言为C(默认C/C++)
)
# 3. 配置头文件:将 @CALC_VERSION_MAJOR@ 替换为实际版本号
# 生成 calc_config.h 文件到 include 目录
configure_file(
${CMAKE_SOURCE_DIR}/include/calc.h
${CMAKE_SOURCE_DIR}/include/calc.h
@ONLY
)
# 4. 包含子目录(执行 src/CMakeLists.txt)
add_subdirectory(src)
# 5. 设置全局编译选项(可选,也可在子目录单独设置)
if(CMAKE_COMPILER_IS_GNUCC)
add_compile_options(-Wall -Wextra -O2) # 开启警告、优化
endif()
#### 三、编译并运行项目
进入 build 目录执行外部构建:
bash
运行
# 进入编译目录
cd build
# 1. 生成Makefile(基于根目录CMakeLists.txt)
cmake ..
# 2. 编译(-j2 多核编译,更快)
cmake --build . -j2
# 3. 运行可执行文件(在 build/src 目录下)
./src/calc_app
#### 四、预期输出
plaintext
=== 简易计算器 v1.0 ===
20 + 5 = 25
20 - 5 = 15
20 × 5 = 100
20 ÷ 5 = 4.00
Error: 除数不能为0!
20 ÷ 0 = 0.00
#### 五、核心进阶特性解释
| 特性 / 指令 | 作用 |
|------------------------------------------------|---------------------------------------------------|
| `add_library(calc_lib STATIC ${CALC_SOURCES})` | 编译静态库(STATIC),区别于基础案例的直接编译可执行文件,适合代码复用 |
| `target_include_directories` | 精准指定头文件路径,`INTERFACE`/`PRIVATE` 控制作用域,避免头文件找不到的问题 |
| `target_link_libraries` | 将可执行文件链接到静态库,是多文件 / 多目录项目的核心 |
| `project(VERSION 1.0)` + `configure_file` | 动态注入版本号到代码中,无需手动修改头文件,适合版本管理 |
| `target_compile_options` | 为特定目标(可执行文件 / 库)设置编译选项(如警告、C 标准),更灵活 |
| `add_subdirectory(src)` | 包含子目录的 CMakeLists.txt,实现分目录管理配置,适合大型项目 |
#### 总结
1. 进阶 CMake 核心是**分目录管理** +**库编译**:将核心逻辑封装为静态库,主程序链接库文件,提高代码复用性;
2. `target_*` 系列指令(`target_include_directories`/`target_link_libraries`)是现代 CMake 的核心,精准控制目标的依赖和编译属性;
3. `configure_file` 实现「代码与配置解耦」,比如版本号、编译开关等可由 CMake 统一管理,无需修改源码。
这个案例覆盖了实际项目中 80% 的 CMake 常用进阶用法,你可以在此基础上扩展(比如添加动态库、条件编译、安装规则等),进一步加深理解。
*** ** * ** ***
旧版:
[https://blog.csdn.net/ZhangRelay/article/details/148171780](https://blog.csdn.net/ZhangRelay/article/details/148171780 "https://blog.csdn.net/ZhangRelay/article/details/148171780")
*** ** * ** ***
#### 一、CMake 是什么?
CMake 不是**编译器** ,也不是**构建工具** (如 make/ninja),而是一个**跨平台的构建系统生成器(Build System Generator)**。
* 通俗理解:你用 CMake 写一份「平台无关」的配置文件(`CMakeLists.txt`),CMake 会根据你的系统(Linux/macOS/Windows)和编译器(GCC/Clang/MSVC),自动生成对应的构建文件(比如 Linux 下的 `Makefile`、Windows 下的 Visual Studio 工程文件、跨平台的 Ninja 配置)。
* 核心定位:**桥梁**------ 连接开发者的「通用配置」和不同平台的「底层构建工具」。
#### 二、CMake 解决的核心问题
在 CMake 出现前,跨平台 C/C++ 开发有两大痛点:
1. **构建文件不通用** :Linux 写 `Makefile`,Windows 写 VS 工程,macOS 写 Xcode 工程,维护多套配置成本极高;
2. **Makefile 编写复杂**:手动写复杂的 Makefile 容易出错,尤其是多目录、多库的大型项目;
3. **依赖管理繁琐**:手动处理头文件路径、库链接、编译选项,容易出现「在 A 机器能编译,B 机器编译失败」的问题。
CMake 正是为解决这些问题而生:**一份 `CMakeLists.txt`,适配所有主流平台和构建工具**。
#### 三、CMake 的核心优势
1. **跨平台性**:支持 Linux/macOS/Windows/Android/iOS 等几乎所有主流平台,无需为不同平台写不同配置;
2. **易用性** :相比手写 Makefile,CMake 指令更简洁、语义更清晰(比如 `target_link_libraries` 直接链接库,无需手动写链接参数);
3. **扩展性**:支持静态库 / 动态库编译、条件编译、版本管理、自定义编译规则、第三方库集成(如 FindBoost.cmake);
4. **生态完善**:几乎所有主流 C/C++ 项目(如 OpenCV、Qt、TensorFlow)都用 CMake 作为构建系统,学习成本有高回报;
5. **现代特性** :「目标(Target)」为核心的设计(`target_*` 系列指令),精准控制编译属性,避免全局污染。
#### 四、CMake 的工作流程
CMake 执行分为两个核心阶段,这也是你之前实操中「`cmake ..` + `cmake --build .`」的底层逻辑:
预览
查看代码
编写 CMakeLists.txt
运行 cmake 命令
生成平台专属构建文件
(如 Makefile/Ninja/VS工程)
运行构建命令
(cmake --build . 或 make/ninja)
编译器编译源码
生成可执行文件/库
graph TD
A[编写 CMakeLists.txt] --> B[运行 cmake 命令]
B --> C[生成平台专属构建文件 (如 Makefile/Ninja/VS工程)]
C --> D[运行构建命令 (cmake --build . 或 make/ninja)]
D --> E[编译器编译源码 生成可执行文件/库]
编写 CMakeLists.txt
运行 cmake 命令
生成平台专属构建文件
(如 Makefile/Ninja/VS工程)
运行构建命令
(cmake --build . 或 make/ninja)
编译器编译源码
生成可执行文件/库

* **配置阶段(Configure)** :执行 `cmake ..`,CMake 解析 `CMakeLists.txt`,检查系统环境(编译器、库依赖),生成构建文件;
* **构建阶段(Build)** :执行 `cmake --build .`,调用底层构建工具(如 make),根据构建文件编译源码。
#### 五、CMake 的核心思想
1. **基于「目标(Target)」** 现代 CMake(3.0+)的核心是「目标」------ 可执行文件(`add_executable`)、库(`add_library`)都是「目标」。所有编译属性(头文件路径、编译选项、库链接)都绑定到具体目标(如 `target_include_directories`),而非全局设置,避免冲突。
2. **Out-of-Source Build(外部构建)** 推荐将编译产物(临时文件、可执行文件)放在单独的 `build` 目录,与源码分离:
* 优点:源码目录干净,删除 `build` 即可清空所有编译产物,支持多套编译配置(如 debug/release)。
3. **声明式配置** 你只需要告诉 CMake「要做什么」(比如「编译一个叫 calc_app 的可执行文件,链接 calc_lib 库」),无需关心「怎么做」(比如链接库需要加 `-l` 参数、头文件路径需要加 `-I` 参数),CMake 会自动处理底层细节。
#### 六、CMake 的适用场景
* 小项目:替代手写 Makefile,简化编译流程;
* 中大型项目:分目录管理、库编译、依赖管理、跨平台发布;
* 开源项目:适配不同用户的系统和编译环境,降低使用者的接入成本;
* 工程化开发:集成测试、安装规则(`make install`)、打包(CPack)等。
#### 总结
1. CMake 是「构建系统生成器」,核心价值是**跨平台、简化构建配置**,而非直接编译代码;
2. 现代 CMake 以「目标(Target)」为核心,通过 `target_*` 系列指令精准控制编译属性;
3. 核心工作流程是「配置阶段(生成构建文件)+ 构建阶段(编译源码)」,外部构建(build 目录)是最佳实践。
理解这些核心概念后,你之前写的基础案例、进阶案例就不再是「记指令」,而是能明白每个指令背后的设计逻辑,后续学习更复杂的 CMake 用法(如集成第三方库、条件编译、安装规则)也会更轻松。