ROS云课三分钟-cmake默认版本和升级-260120

如何查看云端系统内核版本

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 ![](https://i-blog.csdnimg.cn/direct/3af080a89eba4520a33e4269362763f3.png) *** ** * ** *** ## 查询更新效果cmake 失败了吧\^_\^ ![](https://i-blog.csdnimg.cn/direct/2d0e970a6d3d45818589591bc8837e02.png) *** ** * ** *** ## 合理的方式 ```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 ![](https://i-blog.csdnimg.cn/direct/a8abcd42020f48b59017ce1da8a65b90.png) * 避免使用 `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) 编译器编译源码 生成可执行文件/库 ![](https://i-blog.csdnimg.cn/direct/16506252e3814737bfebfba32445fbc6.png) * **配置阶段(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 用法(如集成第三方库、条件编译、安装规则)也会更轻松。

相关推荐
sycmancia2 小时前
C语言学习07——变量的作用域
c语言·学习
lkbhua莱克瓦243 小时前
JavaScript核心语法
开发语言·前端·javascript·笔记·html·ecmascript·javaweb
SmartBrain3 小时前
Agent 知识总结
服务器·数据库·笔记
杨浦老苏3 小时前
离线优先的自托管笔记应用Anchor
笔记·docker·群晖
虾说羊3 小时前
Langchain4j中AIService学习
学习
CryptoPP3 小时前
主流国际股票行情API接口横向对比:如何选择适合你的数据源?
大数据·笔记·金融·区块链
代码游侠3 小时前
嵌入式开发——ARM Cortex-A7内核和i.MX6处理器相关的底层头文件
arm开发·笔记·嵌入式硬件·学习·架构
hetao17338374 小时前
2026-01-19~20 hetao1733837 的刷题笔记
c++·笔记·算法
优雅的潮叭4 小时前
c++ 学习笔记之 volatile与atomic
c++·笔记·学习