【CMake】学习条记1

[复制链接]
发表于 2026-2-6 07:42:10 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
1. CMake概述

   

  • CMake 是一个项目构建工具,而且是跨平台的。关于项目构建我们所熟知的尚有 Makefile(通过 make 下令举行项目标构建),大多是 IDE软件都集成了 make,好比:VS的 nmake、linux下的 GNU make、Qt 的 qmake 等,假如本身动手写 makefile,会发现,makefile 通常依赖于当前的编译平台,而且编写 makefile 的工作量比力大,办理依赖关系时也轻易堕落。
  • 而 CMake 恰恰能办理上述题目, 其答应开辟者指定整个工程的编译流程,在根据编译平台, 主动生本钱地化的Makefile和工程文件,末了用户只需 make 编译即可,以是可以把 CMake 当作一款主动天生 Makefile 的工具,其编译流程如下图:

  2. 编写一个简单的CMakeLists.txt

体系情况:
  1. ubuntu20.04
复制代码
检察Cmake是否安装:
  1. cmake --version
复制代码
CMake长处:
   

  • 跨平台
  • 可以大概管理大型项目
  • 简化编译构建和编译过程
  • 可扩展:可以为cmake编写特定功能的模块,扩充cmake功能
  2.1表明

2.1.1 表明行

CMake使用#举行行表明,可以放在任何位置
  1. # 这是一个CMakeLists.txt文件
  2. cmake_minimum_required(VERSION 3.0.0)
复制代码
2.1.2 块表明

CMake使用#[[]]举行块表明
  1. #[[这是一个CMakeLists.txt文件
  2. 这是一个CMakeLists.txt文件
  3. 这是一个CMakeLists.txt文件
  4. ]]
  5. cmake_minimum_required(VERSION 3.0.0)
复制代码
2.1 只有源文件

add.cpp:
  1. #include <stdio.h>
  2. #include "head.h"
  3. const char* libVersion = "Library Version 1.0";
  4. int add(int a, int b){
  5.     return a+b;
  6. }
复制代码
div.cpp:
  1. #include <stdio.h>
  2. #include "head.h"
  3. double divide(int a, int b){
  4.     return a/b;
  5. }
复制代码
mult.cpp:
  1. #include <stdio.h>
  2. #include "head.h"
  3. int multiply(int a, int b){
  4.     return a*b;
  5. }
复制代码
sub.cpp:
  1. #include <stdio.h>
  2. #include "head.h"
  3. int substract(int a, int b){
  4.     return a-b;
  5. }
复制代码
head.h
  1. #include <stdio.h>
  2. #include "head.h"
  3. int substract(int a, int b){
  4.     return a-b;
  5. }
复制代码
main.cpp
  1. #include <stdio.h>
  2. #include "head.h"
  3. int main(){
  4.     int a = 20;
  5.     int b = 12;
  6.     printf("a = %d, b= %d \n",a,b);
  7.     printf("a+b = %d \n", add(a,b));
  8.     printf("a-b = %d \n", substract(a,b));
  9.     printf("a*b = %d \n", multiply(a,b));
  10.     printf("a/b = %f \n", divide(a,b));
  11. }
复制代码
添加CMakeLists.txt文件:
  1. cmake_minimum_required(VERSION 3.0.0)
  2. project(CALC)
  3. add_executable(app add.cpp div.cpp main.cpp mult.cpp sub.cpp)
复制代码

  • cmake_minimum_required: 指定cmake的最低版本,可选,非必须,假如不加大概会有告诫
  • project:界说工程名称,并可指定工程的版本、工程形貌、web 主页地点、支持的语言(默认情况支持全部语言),假如不必要这些都是可以忽略的,只必要指定出工程名字即可。
  1. #PROJECT 指令的语法是:
  2. project(<PROJECT-NAME>[<language-name>...])
  3. project(<PROJECT-NAME>
  4.                 [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
  5.                 [DESCRIPTI0N <project-description-string>]
  6.                 [HOMEPAGE URL <url-string>]
  7.                 [LANGUAGES <language-name>...])  # 指定语言,即cmake支持的语言
复制代码

  • add_executable : 界说工程会天生一个可实行步调
  1. add_executable(可执行程序名 源文件名称)
复制代码
这里的可实行步调名和project中的项目名称没有任何关系
源文件名可以是一个也可以是多个,假如有多个可以用空格大概;隔断
  1. # 样式1
  2. add_executable(app add.c div.c main.c mult.c sub.c)
  3. # 样式2
  4. add_executable(app add.c;div.c;main.c;mult.c;sub.c)
复制代码
4. 实行CMake下令
将CMakeLists.txt文件编译好之后,就可以实行cmake下令了
  1. # cmake 命令原型
  2. cmake CMakeLists.txt文件所在路径
复制代码
实行CMakeLists.txt会天生一些文件,可以在CMakeLists.txt目次下新建build文件,进入build文件,然后实行下令cmake ..这时间天生的文件就会在build目次下了,之后使用make对天生的Makefile文件举行编译,得到可实行文件app
3. CMake中set使用

set 根本使用

   在上面的例子中一共提供了5个源文件,假设这五个源文件必要反复被使用,每次都直接将它们的名字写出来确实是很贫苦,此时我们就必要界说一个变量,将文件名对应的字符串存储起来,在cmake 里界说变量必要使用 set。
  1. # SET 指令的语法是:
  2. #[]中的参数为可选项,如不需要可以不写
  3. SET(VAR [VALUE][CACHE TYPE DOCSTRING [FORCE]])
复制代码
此中:
VAR:变量名称
VALUE:变量值
  1. # 方式1:各个源文件之间使用空格间隔
  2. # set(SRC_LIST add.c div.cmain.c mult.csub.c)
  3. # 方式2:各个源文件之间使用分号;间隔
  4. set(SRC_LIST add.c;div.c;main.c;mult.c;sub.c)
  5. add_executable(app${SRC_LIST})
复制代码
set中变量的值都是字符串范例
set指定使用C++标准

在编写 C++步调的时间,大概会用到C++11、C++14、C++17、C++20 等新特性,那么就必要在编译的时间在编译下令中指定出要使用哪个标准:
假如不指定则默认使用C++98标准
  1. g++ *.cpp -std=c+=11 -o app
复制代码
上面的例子中通过参数 -std=c++11 指定出要使用 C++11 标准编译步调,C++标准对应有一宏叫做DCMAKE_CXX_STANDARD。在CMake 中想要指定C++标准有种方式:
1. 在CMakeLists.txt中通过set下令指定
  1. # 增加 -std=c++11
  2. set(CMAKE_CXX_STANDARD 11)
  3. # 增加 -std=c++14
  4. set(CMAKE_CXX_STANDARD 14)
  5. # 增加 -std=c++17
  6. set(CMAKE_CXX_STANDARD 17)
复制代码
2.在实行cmake下令的时间指定出这个宏的值
  1. # 增加-std=c++11
  2. cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=11
  3. # 增加-std=c++14
  4. cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=14
  5. # 增加-std=c++17
  6. cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=17
复制代码
set指定输出路径

   在 CMake 中指定可实行步调输出的路径,也对应一个宏,叫做EXECUTABLE_OUTPUT_PATH,它的值照旧通过 set
  1. set(HOME /home/robin/Linux/Sort)
  2. set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)
复制代码

  • 第一行:界说一个变量用于存储一个绝对路径
  • 第二行:将拼接好的路径值设置给EXECUTABLE_OUTPUT_PATH 宏,假如这个路径中的子目次不存在会主动天生,无需本身手动创建,路径发起用绝对路径
修改之前的CMakeLists.txt文件:
  1. cmake_minimum_required(VERSION 3.0.0)
  2. project(test)
  3. # 指定使用C++标准
  4. set(CMAKE_CXX_STANDARD 11)
  5. set(SRC add.cpp div.cpp main.cpp mult.cpp sub.cpp)
  6. # 指定可执行文件生成路径
  7. set(EXECUTABLE_OUTPUT_PATH /home/dabing/aa/bb/cc)
  8. add_executable(app ${SRC})
复制代码
4. 搜刮文件

   假如一个项目里边的源文件许多,在编写 CMakeLists.txt 文件的时间不大概将项目目次的各个文件逐一摆列出来,如许太贫苦也不实际。以是,在CMake 中为我们提供了搜刮文件的下令,可以使用aux_source_directory下令大概 file下令。
  方式1:aux_source_directory
  1. aux_source_directory(<dir> <variable>)
复制代码

  • dir: 要搜刮的目次
  • variable:将dir目次下搜刮到的源文件列表存储到该变量中
  1. cmake_minimum_required(VERSION 3.0.0)
  2. project(test)
  3. # 指定使用C++标准
  4. set(CMAKE_CXX_STANDARD 11)
  5. # aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRC_LIST)
  6. aux_source_directory(${PROJECT_SOURCE_DIR} SRC_LIST)
  7. add_executable(app ${SRC_LIST})
复制代码
方式2:file
  1. fiLe(GLOB/GLOB_RECURSE 变量名 要搜索的文件路径和文件类型)
复制代码
GLOB:将指定目次下搜刮到的满足条件的全部文件名天生一个列表,并将其存储到变量中。
GLOB_RECURSE:递归搜刮指定目次,将搜刮到的满足条件的文件名天生一个列表,并将其存储到变量中。
搜刮当前目次的src目次下全部源文件,并存储到变量中:
  1. file(GLOB MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
复制代码
  1. file(GLOB MAIN_HEAD ${CMAKE_CURRENT_SOURCE _DIR}/include/*.h)
复制代码
CMAKE_CURRENT_SOURCE_DIR:表现当前访问的CMakeLists.txt文件地点的路径
关于要搜刮的文件路径和范例可以加双引号雨可以不加:
PROJECT_SOURCE_DIR: 是在实行cmake下令时背面跟着的路径
  1. file(GLOB MAIN_HEAD "${CMAKE_CURRENT_SOURCE _DIR}/include/*.h")
复制代码
使用示例:
  1. cmake_minimum_required(VERSION 3.0.0)
  2. project(test)
  3. # 指定使用C++标准
  4. set(CMAKE_CXX_STANDARD 11)
  5. file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
  6. add_executable(app ${SRC_LIST})
复制代码
留意:在实际使用中aux_source_directory使用更方便,由于file不光要指定路径,还要指定文件后缀
本文参考:https://www.bilibili.com/video/BV14s4y1g7Zj/?spm_id_from=333.999.0.0
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表