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 makesudo 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.5CMake 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目錄下會生成可執行程序