1 CMake介绍
- CMake是一个开源的、跨平台的构建系统,用于管理软件从源代码到可执行文件的整个构建过程。它最初由Kitware公司为ITK(Insight Segmentation and Registration Toolkit)和VTK(Visualization Toolkit)等开源项目开发,后来成为了一个独立的开源项目。
- CMake的设计目标是让开发者能够以一种简单、统一的方式编写构建规则,这些规则可以在多种操作系统和编译器环境下工作,从而实现代码的跨平台编译。
2 CMake安装
- CMake包下载地址
2.1 Linux平台安装
- 以ubuntu 20.04 版本为例
2.1.1 命令行安装
- apt install cmake
2.1.2 源码编译安装
- 安装编译工具和依赖库
-
sudo apt install g++ sudo apt install make sudo install libssl-dev
-
- 下载源码
- 以3.28.5版本为例,下载这个源码包 cmake-3.28.5.tar.gz
- 编译安装
- 解压后进入cmake源码目录,执行以下命令编译安装
-
./configuire # 编译 make -j4 # 默认会安装到/usr/local/share目录下 make install
- 查看版本
- 安装完成后重新打开终端,执行cmake -version就可以看到当前安装的版本。
-
cmake version 3.28.5 CMake suite maintained and supported by Kitware (kitware.com/cmake).
- 设置环境变量
- 如果安装后执行cmake -version看不到版本,可能是环境变量没有设置进去
- 打开 ~/.bash_profile 在文件末尾添加以下内容
-
export PATH=/usr/local/share/cmake-3.28
2.2 Windows平台安装
- 下载windows平台安装包 cmake-3.28.5-windows-x86_64.msi
- 下载后直接双击安装
- 安装过程中会让你选择是否设置环境变量,这里就选择设置系统环境变量。
- 默认会安装到 C:\Program Files\CMake目录下
- 安装完成后,打开cmd命令行工具,执行cmake -version就可以看到当前安装的CMake版本
3 CMake生成可执行程序
- 文件结构
-
├── build ├── CMakeLists.txt └── src └── main.cpp
-
- build目录: 编译目录
- src目录: 存放源文件的目录
- CMakeLists.txt文件内容
-
# 指定CMake最低版本 cmake_minimum_required(VERSION 3.20) # 构建项目的名称 project(cmake_first_demo) # 构建执行程序 # PROJECT_SOURCE_DIR 是CMake的一个系统变量,表示当前工程目录,即CMake所在目录 add_executable(cmake_first_demo ${PROJECT_SOURCE_DIR}/src/main.cpp)
-
3.1 Windows平台
-
构建项目
-
# 构建项目,在build目录下执行,此命令会使用默认编译器构建项目 # ..表示上一级目录 cmake .. # 或者通过-G参数,指定编译器构建项目 cmake -G "Visual Studio 14 2015" ..
-
-
构建项目时指定生成项目文件路径
- 上面是手动创建了一个build项目来创建工程,还可以构建项目时自动创建目录
- 在 CMakeLists.txt 所在目录下执行
-
# -S 指定CMakeLists.txt 文件所在目录 # -B 指定工程文件生成目录 cmake -S . -B build_x86
-
编译可执行程序
-
构建项目成功后,在build目录下会生成工程文件,可以用Visual Studio 编译器打开sln后缀的文件。选择工程,点击生成,在build/Release目录下就可以生成可执行程序。
-
也可以不用打开编译器,直接在build目录下执行以下命令
-
# 默认生成Debug程序,通过--config可指定生成Release程序 cmake --build ./ --config Release
-
在build/Release 目录下也会生成可执行程序
-
3.2 Linux平台
- CMake支持跨平台,因此在其Linux平台也可以直接编译,和Windows差别不大
- 构建项目
-
# 在build目录下执行 cmake ..
- 执行后会在build目录下生成以下工程文件,工程文件和Windows平台是不一样的。
-
- 编译可执行程序
- 直接执行make命令生成可执行程序
4 CMake生成静态库
- 文件结构
-
├── build ├── CMakeLists.txt └── src ├── mymath.cpp └── mymath.h
-
- CMakeLists.txt文件内容
-
# 指定CMake最低版本 cmake_minimum_required(VERSION 3.20) # 构建项目的名称 project(mymath_demo) # 指定头文件路径 include_directories(${PROJECT_SOURCE_DIR}/src) # 生成库文件(静态库) add_library(mymath_demo STATIC ${PROJECT_SOURCE_DIR}/src/mymath.cpp)
-
- mymath.h文件内容
-
#ifndef __MY_MATH_H__ #define __MY_MATH_H__ int mymath_add(int a, int b); #endif
-
- mymath.cpp文件内容
-
#include "mymath.h" int mymath_add(int a, int b){ return a + b; }
-
Windows平台
- 在build目录下执行
-
cmake .. cmake --build . --config Release
-
- 在build/Release目录下就会生成静态库文件
Linux平台
- 在build目录下分别执行以下命令
-
cmake .. make
-
- 就会生成对应的静态库文件 libmymath_demo.a
5 CMake链接静态库
- 文件结构
-
├── build ├── CMakeLists.txt ├── mymath │ ├── gcc_x64 │ │ └── libmymath_demo.a │ ├── include │ │ └── mymath.h │ └── vc_x86 │ └── mymath_demo.lib └── src └── main.cpp
-
- mymath目录下的头文件和库文件,是在步骤4中编写和生成的,拷贝过来。
- CMakeLists.txt文件内容
-
# 指定CMake最低版本 cmake_minimum_required(VERSION 3.20) # 构建项目的名称 project(myproject) # 指定头文件路径 include_directories(${PROJECT_SOURCE_DIR}/mymath/include) # 指定库文件路径 IF(WIN32) link_directories(${PROJECT_SOURCE_DIR}/mymath/vc_x86) ELSEIF(UNIX) link_directories(${PROJECT_SOURCE_DIR}/mymath/gcc_x64) ENDIF() # 生成可执行程序 add_executable(myproject ${PROJECT_SOURCE_DIR}/src/main.cpp) # 链接库 target_link_libraries(myproject mymath_demo)
-
- main.cpp文件内容
-
#include <stdio.h> #include "mymath.h" int main(){ int sum = mymath_add(10, 20); printf("sum = %d\n", sum); return 0; }
-
Windows平台
- build目录下执行
-
cmake .. cmake --build . --config Release
-
- 在build/Release目录下会生成可执行程序
Linux平台
- build目录下执行
-
cmake .. make
-
- 在build目录下会生成可执行程序
6 CMake生成动态库
- 生成动态库时,使用步骤4中的代码工程。
- 将CMakeLists.txt文件最后一行做修改,指定生成动态库
-
# 指定CMake最低版本 cmake_minimum_required(VERSION 3.20) # 构建项目的名称 project(mymath_demo) # 指定头文件路径 include_directories(${PROJECT_SOURCE_DIR}/src) # 生成库文件(动态库) add_library(mymath_demo SHARED ${PROJECT_SOURCE_DIR}/src/mymath.cpp)
-
Windows平台
- 需要注意的是,Windows平台链接动态库时,需要先找到lib文件
- 因此对 mymath.h 文件做修改,生成动态库的同时需要生成lib文件
-
#ifndef __MY_MATH_H__ #define __MY_MATH_H__ // 导出接口到lib文件中 int __declspec(dllexport) mymath_add(int a, int b); #endif
-
- build目录下执行以下命令编译
-
cmake .. cmake --build . --config Release
-
- 会生成lib和dll文件
Linux平台
- 直接在build目录下执行命令编译就可以生成动态库
-
cmake .. make
-
- 生成了动态库文件
7 CMake链接动态库
- 使用步骤5中的代码工程
- 链接动态库时,不用做任何修改,只需要将静态库文件替换为动态库文件即可。
- 目录结构如下
-
├── build ├── CMakeLists.txt ├── mymath │ ├── gcc_x64 │ │ └── libmymath_demo.so │ ├── include │ │ └── mymath.h │ └── vc_x86 │ ├── mymath_demo.dll │ └── mymath_demo.lib └── src └── main.cpp
-
Windows平台
- build目录下执行
-
cmake .. cmake --build . --config Release
-
- 在build/Release目录下会生成可执行程序
- 运行时需要将 mymath_demo.dll 和可执行程序放到同一个目录下。
Linux平台
- build目录下执行
-
cmake .. make
-
- 在build目录下会生成可执行程序