Cmake 重要指令
指定 CMake 最小版本要求
语法
cmake_minimum_required(VERSION versionNumber[FATAL_ERROR])
例子
指定 CMake 最小版本要求 3.21.1
cmake_minimum_required(VERSION 3.21.1)
定义工程名称(可指定工程支持的语言)
语法
project(projectName[CXX][C][JAVA])
例子
定义工程名称为 helloWorld
project(helloWorld)
显示定义变量
语法
set(VAR [VALUE] [CACHE TYPE DECSTRING [FORCE]])
例子
定义变量 SRC ,其值为 hello.c main.c
set(SRC hello.c main.c)
向工程添加多个特定头文件搜索路径
相当于指定编译器的 -I 参数
语法
include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2)
例子
将 /inc 和 /include 添加到头文件搜索路径
include_directories(./inc ./include)
向工程添加多个特定库文件搜索路径
相当于指定编译器的 -L 选项
语法
link_directories(dir1 dir2 …)
例子
将 ./lib 文件添加到库文件搜索路径
link_directories(./lib)
生成库文件
语法
add_library(libName [SHARED | STATIC | MODULE | EXCLUDE_FROM_ALL] source1 source2 …)
例子
通过变量 SRC 生成 libhello.so 共享库
add_library(hello SHARED ${SRC})
添加编译参数
语法
add_compile_options( option …)
例子
添加编译参数 -Wall -std=c++11
add_compile_options(-Wall -std=c++11 -O2)
生成可执行文件
语法
add_executable(exename source1 source2 …)
例子
编译 main.c 生成 main 的可执行文件
add_executable(mian mian.c)
为 target 添加需要链接的共享库
语法
target_link_libraries(target library1<debug | optimized> library2 …)
例子
将 hello 动态文件链接到可执行文件 main
target_link_libraries(main hello)
向当前工程添加存放源文件的子目录
可以指定中间二进制和目标二进制存放的位置
语法
add_subdirectory(source_dir [binaryDir] [EXCLUDE_FROM_ALL])
例子
添加 src 子目录
注:src 中需要有一个 CMakeLists.txt 文件
add_subdirectory(src)
发现一个目录下所有的源代码文件并将列表存储在一个变量中
这个指令常被临时用来自动构建源文件列表
语法
aux_source_directory(dir VARIABLE)
例子
定义 SRC 变量,其值为当前目录下所有源代码文件
aux_source_directory(. SRC)
编译 SRC 变量所代表的团代码文件,生成 main 可执行文件
add_executable(main ${SRC})
cmake 常用变量
变量名 | 说明 |
---|---|
CMAKE_C_FLAGS | gcc 编译选项 |
CMAKE_CXX_FLAGS | g++ 编译选项 |
# 在CMAKE_CXX_FLAGS 编译选项后追加 -std=c++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
变量名 | 说明 |
---|---|
CMAKE_BUILD_TYPE | 编译类型(Debug、Release) |
# 设定编译器类型为 Debug
set(CMAKE_BUILD_TYPE Debug)
# 设定编译类型为 release
set(CMAKE_BUILD_TYPE Release)
变量名 | 说明 |
---|---|
CMAKE_BINARY_DIR | |
PROJECT_BINARY_DIR | |
_BINARY_DIR |
这三个变量指代的内容一致
如果是 in_source_build,指的就是工程目录顶层
如果是 out-of-source 编译,指的是工程编译发生的目录
PROJECT_BINARY_DIR 跟其他指令稍有区别
变量名 | 说明 |
---|---|
CMAKE_SOURCE_DIR | |
PROJECT_SOURCE_DIR | |
_SOURCE_DIR |
这三个变量指代的内容是一致的,不论采用何种编译方式,都是工程顶层目录
在 in_source_buind 时,跟 CMAKE_BINARY_DIR 等变量一致
PROJECT_SOURCE_DIR 跟其他指令稍有区别
变量名 | 说明 |
---|---|
CMAKE_C_COMPILER | 指定 C 编译器 |
CMAKE_CXX_COMPILE | 指定 C++ 编译器 |
EXECUTABLE_OUTPUT_PATH | 可执行文件输出的存放路径 |
LIBRARY_OUTPUT_PATH | 库文件输出存放路径 |
CMake 编译工程
CMake 目录结构
项目主目录存在一个CMakeLists.txt 文件
设置编译规则
1、 包含源文件的子文件夹包含 CMakeLists.txt 文件,主目录的 CMakeLists.txt 通过 add_subdirectory 添加子目录即可
2、 包含源文件的子文件夹未包含 CMakeLists.txt 文件,子目录编译规则体现在主目录的 CMakeLists.txt 中
编译流程
在 Linux 平台下使用 CMake 构建 C/C++ 工程的流程:
- 手动编写 CMakeLists.txt
- 执行 cmake PATH 生成 Makefile (PATH 是顶层 CMakeLists.txt 所在目录)
- 执行 make 进行编译
构建方式
内部构建
内部构件会在同级目录下产生一大堆中间文件,这些中间文件并不是我们最终所需要的,和工程源文件存放在一起
# 内部构建
# 在当前目录下,编译本目录的 CMakeLists.txt ,生成 Makefile 和其他文件
make .
外部构建
将编译输出的文件与源文件放置在不同目录中
# 在当前文件创建 build 文件
mkdir build
# 进入到 build 文件夹
cd build
# 编译上级目录的 CMakeLists.txt
cmake ..
CMake 实战
最小 CMake 工程
步骤:
- 指定 cmake 最低版本要求
- 定义工程名称
- 生成可执行文件
测试代码
#include <stdio.h>
int main(char argc, char **argv)
{
printf("hello world\r\n");
return 0;
}
cmake 代码
# 指定 CMake 最小版本要求
cmake_minimum_required(VERSION 3.0.0)
# 定义工程名称(可指定工程支持的语言)
project(HELLO)
# 生成可执行文件
add_executable(hello hello.c)
多文件 CMake 工程
文件结构:
swap.h
#ifndef __SWAP_H
#define __SWAP_H
void swapNum(int *a, int *b);
#endif
swap.c
void swapNum(int *a, int *b)
{
int temp = a;
a = b;
b = temp;
}
mian.c
#include "../inc/swap.h"
#include <stdio.h>
int main()
{
int a = 10, b = 20;
printf("Before swap a=%d, b=%d\r\n", a, b);
swapNum(&a, &b);
printf("After swap a=%d, b=%d\r\n", a, b);
return 0;
}
CMakeLists.txt
# 规定最小版本
cmake_minimum_required(VERSION 3.0.0)
# 工程名称
project(SWAP)
#添加头文件
include_directories(inc)
# 生成可执行文件
add_executable(swap main/main.c src/swap.c)
autobuild.sh
# 自动编译脚本
#!/bin/bash
# 创建文件
mkdir build
# 移动路径
cd build
# cmake 配置
cmake ../
# 编译
make
给脚本添加可执行权限
chmod +x autobuild.sh
运行脚本
./autobuild.sh
最后执行可执行文件
./build/swap
运行结果:
Before swap a=10, b=20
After swap a=10, b=20
ctories(inc)
生成可执行文件
add_executable(swap main/main.c src/swap.c)
autobuild.sh
自动编译脚本
#!/bin/bash
创建文件
mkdir build
移动路径
cd build
cmake 配置
cmake …/
编译
make
给脚本添加可执行权限
`chmod +x autobuild.sh`
运行脚本
`./autobuild.sh`
最后执行可执行文件
`./build/swap `
运行结果:
Before swap a=10, b=20
After swap a=10, b=20