【CMake】学习笔记1

1. CMake概述

  1. CMake 是一个项目构建工具,并且是跨平台的。关于项目构建我们所熟知的还有 Makefile(通过 make 命令进行项目的构建),大多是 IDE软件都集成了 make,比如:VS的 nmake、linux下的 GNU make、Qt 的 qmake 等,如果自己动手写 makefile,会发现,makefile 通常依赖于当前的编译平台,而且编写 makefile 的工作量比较大,解决依赖关系时也容易出错。
  2. 而 CMake 恰好能解决上述问题, 其允许开发者指定整个工程的编译流程,在根据编译平台, 自动生成本地化的Makefile和工程文件,最后用户只需 make 编译即可,所以可以把 CMake 看成一款自动生成 Makefile 的工具,其编译流程如下图:
    在这里插入图片描述

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

系统环境:

ubuntu20.04

查看Cmake是否安装:

cmake --version

CMake优点:

  1. 跨平台
  2. 能够管理大型项目
  3. 简化编译构建和编译过程
  4. 可扩展:可以为cmake编写特定功能的模块,扩充cmake功能

2.1注释

2.1.1 注释行

CMake使用#进行行注释,可以放在任何位置

# 这是一个CMakeLists.txt文件
cmake_minimum_required(VERSION 3.0.0)

2.1.2 块注释

CMake使用#[[]]进行块注释

#[[这是一个CMakeLists.txt文件
这是一个CMakeLists.txt文件
这是一个CMakeLists.txt文件
]]
cmake_minimum_required(VERSION 3.0.0)

2.1 只有源文件

add.cpp:

#include <stdio.h>
#include "head.h"

const char* libVersion = "Library Version 1.0";

int add(int a, int b){
    return a+b;
}

div.cpp:

#include <stdio.h>
#include "head.h"

double divide(int a, int b){
    return a/b;
}

mult.cpp:

#include <stdio.h>
#include "head.h"

int multiply(int a, int b){
    return a*b;
}

sub.cpp:

#include <stdio.h>
#include "head.h"

int substract(int a, int b){
    return a-b;
}

head.h

#include <stdio.h>
#include "head.h"

int substract(int a, int b){
    return a-b;
}

main.cpp

#include <stdio.h>
#include "head.h"

int main(){
    int a = 20;
    int b = 12;
    printf("a = %d, b= %d \n",a,b);
    printf("a+b = %d \n", add(a,b));
    printf("a-b = %d \n", substract(a,b));
    printf("a*b = %d \n", multiply(a,b));
    printf("a/b = %f \n", divide(a,b));
}

添加CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.0.0)
project(CALC)
add_executable(app add.cpp div.cpp main.cpp mult.cpp sub.cpp)
  1. cmake_minimum_required: 指定cmake的最低版本,可选,非必须,如果不加可能会有警告
  2. project:定义工程名称,并可指定工程的版本、工程描述、web 主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可。
#PROJECT 指令的语法是:
project(<PROJECT-NAME>[<language-name>...])
project(<PROJECT-NAME>
		[VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
		[DESCRIPTI0N <project-description-string>]
		[HOMEPAGE URL <url-string>]
		[LANGUAGES <language-name>...])  # 指定语言,即cmake支持的语言
  1. add_executable : 定义工程会生成一个可执行程序
add_executable(可执行程序名 源文件名称)

这里的可执行程序名和project中的项目名称没有任何关系
源文件名可以是一个也可以是多个,如果有多个可以用空格或者;间隔

# 样式1
add_executable(app add.c div.c main.c mult.c sub.c)
# 样式2
add_executable(app add.c;div.c;main.c;mult.c;sub.c)

4. 执行CMake命令
将CMakeLists.txt文件编译好之后,就可以执行cmake命令了

# cmake 命令原型
cmake CMakeLists.txt文件所在路径 

执行CMakeLists.txt会生成一些文件,可以在CMakeLists.txt目录下新建build文件,进入build文件,然后执行命令cmake ..这时候生成的文件就会在build目录下了,之后使用make对生成的Makefile文件进行编译,得到可执行文件app

3. CMake中set使用

set 基本使用

在上面的例子中一共提供了5个源文件,假设这五个源文件需要反复被使用,每次都直接将它们的名字写出来确实是很麻烦,此时我们就需要定义一个变量,将文件名对应的字符串存储起来,在cmake 里定义变量需要使用 set

# SET 指令的语法是:
#[]中的参数为可选项,如不需要可以不写
SET(VAR [VALUE][CACHE TYPE DOCSTRING [FORCE]])

其中:
VAR:变量名称
VALUE:变量值

# 方式1:各个源文件之间使用空格间隔
# set(SRC_LIST add.c div.cmain.c mult.csub.c)
# 方式2:各个源文件之间使用分号;间隔
set(SRC_LIST add.c;div.c;main.c;mult.c;sub.c)
add_executable(app${SRC_LIST})

set中变量的值都是字符串类型

set指定使用C++标准

在编写 C++程序的时候,可能会用到C++11、C++14、C++17、C++20 等新特性,那么就需要在编译的时候在编译命令中指定出要使用哪个标准:
如果不指定则默认使用C++98标准

g++ *.cpp -std=c+=11 -o app

上面的例子中通过参数 -std=c++11 指定出要使用 C++11 标准编译程序,C++标准对应有一宏叫做DCMAKE_CXX_STANDARD。在CMake 中想要指定C++标准有种方式:

1. 在CMakeLists.txt中通过set命令指定

# 增加 -std=c++11
set(CMAKE_CXX_STANDARD 11)

# 增加 -std=c++14
set(CMAKE_CXX_STANDARD 14)

# 增加 -std=c++17
set(CMAKE_CXX_STANDARD 17)

2.在执行cmake命令的时候指定出这个宏的值

# 增加-std=c++11
cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=11
# 增加-std=c++14
cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=14
# 增加-std=c++17
cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=17

set指定输出路径

在 CMake 中指定可执行程序输出的路径,也对应一个宏,叫做EXECUTABLE_OUTPUT_PATH,它的值还是通过 set

set(HOME /home/robin/Linux/Sort)
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)
  1. 第一行:定义一个变量用于存储一个绝对路径
  2. 第二行:将拼接好的路径值设置给EXECUTABLE_OUTPUT_PATH 宏,如果这个路径中的子目录不存在会自动生成,无需自己手动创建,路径建议用绝对路径

修改之前的CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.0.0)
project(test)

# 指定使用C++标准
set(CMAKE_CXX_STANDARD 11)
set(SRC add.cpp div.cpp main.cpp mult.cpp sub.cpp)

# 指定可执行文件生成路径
set(EXECUTABLE_OUTPUT_PATH /home/dabing/aa/bb/cc)
add_executable(app ${SRC})

4. 搜索文件

如果一个项目里边的源文件很多,在编写 CMakeLists.txt 文件的时候不可能将项目目录的各个文件一一罗列出来,这样太麻烦也不现实。所以,在CMake 中为我们提供了搜索文件的命令,可以使用aux_source_directory命令或者 file命令。

方式1:aux_source_directory

aux_source_directory(<dir> <variable>)
  1. dir: 要搜索的目录
  2. variable:将dir目录下搜索到的源文件列表存储到该变量中
cmake_minimum_required(VERSION 3.0.0)
project(test)

# 指定使用C++标准
set(CMAKE_CXX_STANDARD 11)

# aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRC_LIST)
aux_source_directory(${PROJECT_SOURCE_DIR} SRC_LIST)
add_executable(app ${SRC_LIST})

方式2:file

fiLe(GLOB/GLOB_RECURSE 变量名 要搜索的文件路径和文件类型)

GLOB:将指定目录下搜索到的满足条件的所有文件名生成一个列表,并将其存储到变量中。
GLOB_RECURSE:递归搜索指定目录,将搜索到的满足条件的文件名生成一个列表,并将其存储到变量中。

搜索当前目录的src目录下所有源文件,并存储到变量中:

file(GLOB MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
file(GLOB MAIN_HEAD ${CMAKE_CURRENT_SOURCE _DIR}/include/*.h)

CMAKE_CURRENT_SOURCE_DIR:表示当前访问的CMakeLists.txt文件所在的路径
关于要搜索的文件路径和类型可以加双引号雨可以不加:
PROJECT_SOURCE_DIR: 是在执行cmake命令时后面跟着的路径

file(GLOB MAIN_HEAD "${CMAKE_CURRENT_SOURCE _DIR}/include/*.h")

使用示例:

cmake_minimum_required(VERSION 3.0.0)
project(test)

# 指定使用C++标准
set(CMAKE_CXX_STANDARD 11)
file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
add_executable(app ${SRC_LIST})

注意:在实际使用中aux_source_directory使用更方便,因为file不仅要指定路径,还要指定文件后缀

本文参考:https://www.bilibili.com/video/BV14s4y1g7Zj/?spm_id_from=333.999.0.0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值