文章目录
一、前言
CMake是一个跨平台的开源工具,用于管理软件项目的构建过程。它不直接构建软件,而是生成用于特定平台或编译器的构建文件(如Makefile或Visual Studio项目文件),然后利用这些文件来实际构建软件。
简单的说:我用CMake可以把c++、python、java、等等语言,打包成.exe或者.app执行文件。
二、初次尝试
CMake通常用于构建C++项目,但它也可以与其他语言一起使用,包括Python。
1、安装
下载地址:https://cmake.org/files/
安装是注意添加环境变量如下图:
查看是否安装成功cmake --version
2、初次构建案例
先创建C++执行代码如下:代码地址 github
CMakeLists.txt 是用于配置 CMake 构建系统的文件,它描述了项目的组织结构、依赖关系和构建规则,简单的理解就是配置文件。
1、进入build目录,编译c++代码
mkdir build
cd build
# cmake 后面跟的是CMakeLists.txt文件所在的目录
cmake ..
2、构建可执行文件,--config Release
不写默认构建debug
模式
cmake --build . --config Release
3、构建好的目录效果
4、执行效果
三、更多用法
1、定义变量
这里通过set
命令,创建新的SRC变量并给它赋值。
# cmake版本
cmake_minimum_required(VERSION 3.2)
# 项目名称
project(test)
# 设置变量SRC
set(SRC add.cpp div.cpp mult.cpp main.cpp sub.cpp)
# 设置构建输出目录
set(EXECUTABLE_OUTPUT_PATH E:/code/js_reverse/CMake构建/v1/bulid/aa/bb/cc)
# 设置C++ 标准版本
set(CMAKE_CXX_STANDARD 11)
# 得到变量 ${SRC}并构建exe文件
add_executable(app ${SRC})
2、搜索文件
如何通过搜索文件实现变量SRC的赋值
PROJECT_SOURCE_DIR 实现
# cmake版本
cmake_minimum_required(VERSION 3.2)
# 项目名称
project(test)
# 设置变量SRC PROJECT_SOURCE_DIR 表示命令行执行cmake .. 后面的..
aux_source_directory(${PROJECT_SOURCE_DIR} SRC)
# C++ 标准版本
set(CMAKE_CXX_STANDARD 11)
# 得到变量 ${SRC}并构建exe文件
add_executable(app ${SRC})
CMAKE_CURRENT_BINARY_DIR实现(不推荐使用)
# cmake版本
cmake_minimum_required(VERSION 3.2)
# 项目名称
project(test)
# 设置变量SRC CMAKE_CURRENT_BINARY_DIR 表示命令 CMakeLists.txt 所在的目录
file(GLOB SRC ${CMAKE_CURRENT_BINARY_DIR}/*.cpp)
# C++ 标准版本
set(CMAKE_CXX_STANDARD 11)
# 得到变量 ${SRC}并构建exe文件
add_executable(app ${SRC})
3、指定头文件目录
修改项目目录,让项目更加方便管理
CMakeLists.txt 编写内容
# cmake版本
cmake_minimum_required(VERSION 3.2)
# 项目名称
project(test)
# 设置变量SRC CMAKE_CURRENT_BINARY_DIR 表示命令 CMakeLists.txt 所在的目录
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC)
# 指定头文件目录
include_directories(${PROJECT_SOURCE_DIR}/include)
# C++ 标准版本
set(CMAKE_CXX_STANDARD 11)
# 得到变量 ${SRC}并构建exe文件
add_executable(app ${SRC})
4、通过CMake制作库文件
动态库和静态库文件区别
window下
动态库:library.dll
静态库:library.lib
liunx下
动态库:library.so
静态库:library.a
动态库适合于多个程序共享、节省系统资源和方便更新维护的场景,而静态库适合于需要独立运行、性能要求高或者依赖库版本稳定的场景。
CMakeLists.txt 编写内容
# cmake版本
cmake_minimum_required(VERSION 3.2)
# 项目名称
project(test)
# 设置变量SRC CMAKE_CURRENT_BINARY_DIR 表示命令 CMakeLists.txt 所在的目录
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC)
# 指定头文件目录
include_directories(${PROJECT_SOURCE_DIR}/include)
# C++ 标准版本
set(CMAKE_CXX_STANDARD 11)
# 指定库路径
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/libr)
# 生成动态库
#add_library(library SHARED ${SRC})
# 生成静态库
add_library(library STATIC ${SRC})
执行命令
cmake --build . --config Release
执行效果
5、链接静态库
语法:
link_libraries(library_name1 library_name2 ...)
CMakeLists.txt 案例编写
# cmake版本
cmake_minimum_required(VERSION 3.2)
# 项目名称
project(test)
# 设置变量SRC CMAKE_CURRENT_BINARY_DIR 表示命令 CMakeLists.txt 所在的目录
file(GLOB SRC ${PROJECT_SOURCE_DIR}/main.cpp)
# 指定头文件目录
include_directories(${PROJECT_SOURCE_DIR}/include)
# C++ 标准版本
set(CMAKE_CXX_STANDARD 11)
# 链接 library 是库名称
link_libraries(library)
# 如果是自定义库就需要 定义路径
link_directories(${PROJECT_SOURCE_DIR}/lib1/Debug)
# 得到变量 ${SRC}并构建exe文件
add_executable(app ${SRC})
6、链接动态库
语法:
target_link_libraries(target_name PRIVATE|PUBLIC|INTERFACE library_name1 library_name2 ...)
CMakeLists.txt 案例编写
# cmake版本
cmake_minimum_required(VERSION 3.2)
# 项目名称
project(test)
# 设置变量SRC CMAKE_CURRENT_BINARY_DIR 表示命令 CMakeLists.txt 所在的目录
file(GLOB SRC ${PROJECT_SOURCE_DIR}/main.cpp)
# 指定头文件目录
include_directories(${PROJECT_SOURCE_DIR}/include)
# C++ 标准版本
set(CMAKE_CXX_STANDARD 11)
# 如果是自定义库就需要 定义路径
link_directories(${PROJECT_SOURCE_DIR}/lib1/Debug)
# 得到变量 ${SRC}并构建exe文件
add_executable(app ${SRC})
# 链接动态库
target_link_libraries(app PUBLIC library)
7、打印日志
FATAL_ERROR 错误抛出程序停止
message(FATAL_ERROR "2222222222222222")
STATUS 正常日志输出
message(STATUS "2222222222222222")
CMakeLists.txt 案例编写
# cmake版本
cmake_minimum_required(VERSION 3.2)
# 项目名称
project(test)
# 设置变量SRC CMAKE_CURRENT_BINARY_DIR 表示命令 CMakeLists.txt 所在的目录
file(GLOB SRC ${PROJECT_SOURCE_DIR}/main.cpp)
# 指定头文件目录
include_directories(${PROJECT_SOURCE_DIR}/include)
# C++ 标准版本
set(CMAKE_CXX_STANDARD 11)
# 如果是自定义库就需要 定义路径
link_directories(${PROJECT_SOURCE_DIR}/lib1/Debug)
message(STATUS "111111111111111")
add_executable(app ${SRC})
# FATAL_ERROR 错误抛出 程序停止
#message(FATAL_ERROR "2222222222222222")
# 链接动态库
target_link_libraries(app PUBLIC library)
# STATUS 正常日志输出
message(STATUS "55555555555555")
8、字符串操作
多个变量拼接后底层是由;
区分
cmake_minimum_required(VERSION 3.2)
# 项目名称
project(test)
file(GLOB SRC ${PROJECT_SOURCE_DIR}/main.cpp)
include_directories(${PROJECT_SOURCE_DIR}/include)
set(CMAKE_CXX_STANDARD 11)
set(aaa 1)
message(${aaa})
# 拼接字符串
set(bbb ${aaa} 2)
message(${bbb})
# 追加字符串
list(APPEND bbb 3)
message(${bbb})
# 删除字符串
list(REMOVE_ITEM bbb 1)
message(${bbb})
效果:
1
12
123
23
除了 list(APPEND)
和 list(REMOVE_ITEM)
,CMake 还提供了其他用于操作列表的命令和函数。以下是其中一些常用的:
创建列表:
通过 set 命令直接创建列表变量
set(<list_variable> value1 value2 ...)
获取列表的长度,并将结果存储在输出变量中。
list(LENGTH <list_variable> <output_variable>)
获取列表中指定索引位置的元素,并将结果存储在输出变量中。
list(GET <list_variable> <index> <output_variable>)
向列表变量添加一个或多个元素。
list(APPEND <list_variable> value1 value2 ...):
从列表中移除一个或多个特定的元素。
list(REMOVE_ITEM <list_variable> value1 value2 ...)
将列表中的元素连接成一个字符串,并将结果存储在输出变量中。
list(JOIN <list_variable> <glue> <output_variable>)
反转列表中的元素顺序。
list(REVERSE <list_variable>):
查找列表中指定值的索引,并将结果存储在输出变量中。
list(FIND <list_variable> value <output_variable>):
9、自定义宏
c++ 案例代码
#include <stdio.h>
#define NUMBER 3
int main()
{
int a = 10;
#ifdef DEBUG
printf("111111111111\n");
#endif
for(int i=0; i<NUMBER; ++i)
{
printf("hello, GCC|||\n");
}
return 0;
}
宏的定义
cmake_minimum_required(VERSION 3.2)
project(test)
file(GLOB SRC ${PROJECT_SOURCE_DIR}/h.cpp)
# 定义宏DEBUG 类似定义变量
add_definitions(-DDEBUG)
add_executable(app ${SRC})
打印效果:
应用场景:可以用做的log信息打印开关
10、嵌套操作
在编程中,CMake 是一个流行的跨平台构建系统生成工具,它用于自动生成针对不同操作系统和编译器的构建文件。嵌套的 CMake 项目通常指的是一个 CMake 项目包含了另一个或多个 CMake 项目的情况。
以下是一个简单的嵌套 CMake 项目的示例结构:
project_root/
│
├── CMakeLists.txt # 主项目的 CMake 配置文件
│
├── submodule_1/ # 第一个子模块
│ ├── CMakeLists.txt # 子模块 1 的 CMake 配置文件
│ ├── source_files.cpp # 子模块 1 的源文件
│ └── header_files.h # 子模块 1 的头文件
│
├── submodule_2/ # 第二个子模块
│ ├── CMakeLists.txt # 子模块 2 的 CMake 配置文件
│ ├── source_files.cpp # 子模块 2 的源文件
│ └── header_files.h # 子模块 2 的头文件
│
└── ...
以下是一个简单的示例主项目的 CMakeLists.txt 文件:
cmake_minimum_required(VERSION 3.0)
project(MyProject)
# 包含第一个子模块
add_subdirectory(submodule_1)
# 包含第二个子模块
add_subdirectory(submodule_2)
# 添加主项目的源文件
add_executable(MyExecutable main.cpp)
# 链接子模块的库到主项目
target_link_libraries(MyExecutable Submodule1Library Submodule2Library)
四、参考文档
https://subingwen.cn/cmake/CMake-advanced/
https://subingwen.cn/cmake/CMake-primer/