【Cmake】Cmake概覽

目錄

一.環境準備

1.1.Cmake安裝

1.2. VSCodeCMake插件安裝

1.3 快速樣例-helloworld?程

二. cmake的基礎命令?使用示例

2.1.文件準備

2.2.?成構建系統

2.3.編譯連接

2.4.測試Ctest模塊

2.5.測試安裝模塊

2.6.測試打包模塊

2.7?查看幫助


CMake語法簡潔清晰,易于上手,同時功能強大而靈活,在現代C/C++開發中應用極為廣泛。其卓越的跨平臺能力和高度的IDE支持,使其已成為C/C++領域事實上的構建標準與工程管理的核心工具。

掌握CMake不僅能夠讓你的項目結構更加清晰、構建過程更加高效優雅,還能極大地簡化跨平臺開發的復雜度,提升項目的可維護性和協作效率。無論是管理個人項目還是參與大型企業級開發,精通CMake都是一項極具價值的關鍵技能,必將顯著提升你的工程實踐能力和職場競爭力。

一.環境準備

1.1.Cmake安裝

ubuntu安裝

sudo apt install cmake
cmake --version

在不同 Linux 發行版中,軟件倉庫內預裝的 CMake 版本通常會隨著系統版本的更新而逐步升級。新發布的系統版本往往提供更新的 CMake,以支持更多現代特性和改進。以下是常見發行版與 CMake 版本的對應情況概覽,可供環境準備時參考:

Linux 發行版發行版版本預裝/默認 CMake 版本是否滿足本專欄要求(≥3.18)備注
Ubuntu LTS22.04 (Jammy)3.22需通過?apt?安裝
24.04 (Noble)3.28+默認版本較高,功能更全面
Debian12 (Bookworm)3.22包管理器直接安裝
Fedora393.28+版本較新,支持新特性
CentOS Stream93.22+需從默認倉庫安裝
Arch Linux滾動更新最新穩定版(如3.28+)持續更新,支持最新功能

本專欄所使用的 CMake 功能需要最低版本為?3.18。若您當前系統中的版本低于此要求,建議通過包管理工具安裝官方軟件源中的新版本,或從CMake官網下載預編譯二進制包進行安裝,亦可從源碼編譯安裝,以保證課程實驗的順利進行。

1.2. VSCodeCMake插件安裝

VSCodeCMake插件有以下2點好處:

  1. 語法?亮和代碼補全:對 CMakeLists.txt ?件提供語法?亮顯?,使代碼結構更加清晰易 讀。同時,?持代碼補全功能,當你輸?CMake命令或變量時,插件會?動提?可能的選項,減 少?動輸?的錯誤和時間。
  2. 智能分析和錯誤檢查:能夠對 CMakeLists.txt ?件進?智能分析,檢查其中的語法錯誤和潛 在問題,并在編輯器中實時顯?錯誤提?和警告信息,幫助你及時發現和解決問題。

安裝步驟如下:

Step 0:打開VSCode,點擊左側活動欄中的擴展圖標(或按 Ctrl+Shift+X )。

Step 1:在搜索框中輸? CMake ,我們選擇安裝以下4個插件:

  1. CMake
  2. CMake Tools
  3. CMake LanguageSupport
  4. CMake IntelliSence

Step 2:挨個點擊Install按鈕,安裝完成并且成功之后如下圖

1.3 快速樣例-helloworld?程

本節我們將使??個例?來演?下使?CMake構建?個最簡單的C++程序,?致了解下CMake的 使??式。

我們創建?個新的 hello_world ?程。

下圖展?了使?CMake來管理helloworld程序?成的過程

main.cc

#include<iostream>
using namespace std;
int main()
{std::cout<<"Hello World"<<std::endl;
}

Cmakelists.txt

# 1 設置能運行此工程的CMake最低版本要求
# 此處指定構建本項目所需CMake的最小版本為3.18,若環境中的版本低于此值,配置階段將報錯
cmake_minimum_required(VERSION 3.18)# 2 設置項目名稱
# 定義工程名為“helloWorld”,CMake會自動生成一些與該名稱相關的變量,如 PROJECT_NAME、PROJECT_SOURCE_DIR 等
project(helloWorld)# 3 添加構建目標(可執行文件)
# 指定生成一個名為“main”的可執行文件,該文件由源文件 main.cc 編譯鏈接而成
add_executable(main main.cc)

為什么需要設置最低 CMake 版本?

CMake 作為一個持續演進的構建工具,其版本迭代顯著(目前主流已進入 4.x 系列,歷史版本以 3.x 為主)。不同版本往往會引入新的語法、命令、模塊,甚至對現有命令的行為做出調整。如果項目中使用了某些高版本才支持的功能——例如新的內置函數、生成器表達式或特定目標屬性——而用戶本地安裝的 CMake 版本過低,則可能無法正確解析工程配置,導致難以診斷的錯誤或無法預料的行為。

為避免此類兼容性問題,CMake 提供了?cmake_minimum_required?命令。該命令在配置階段(即執行?cmake?命令時)首先檢查當前環境中 CMake 的版本:

  • 若當前版本低于指定的最低要求,CMake 會立即終止處理過程,并報錯提示用戶“需要至少某個版本”,從而防止因語法或功能不兼容導致的后續問題;

  • 只有在版本符合要求時,CMake 才會繼續執行后續的配置流程,確保工程按預期正確配置。

這樣的機制顯著提高了構建腳本的可移植性和可靠性,是實現跨版本兼容的重要保障。

什么是 CMake 中的“目標”?

在 CMake 中,“目標(Target)”是一個核心概念,代表構建過程中要生成的輸出實體,例如可執行文件、靜態庫或動態庫。每個目標都封裝了構建該實體所需的全部信息,包括源文件、編譯選項、鏈接依賴和安裝規則等。

“目標”可類比于傳統 Makefile 中的構建目標,但其功能更為強大和結構化。在現代 CMake 的實踐中,以目標為中心的工程管理方式被廣泛推薦。通過明確定義目標及其屬性,開發者可以更清晰、更模塊化地組織項目結構,精確控制構建過程,并有效管理依賴關系。正因如此,理解并熟練使用“目標”,是掌握現代 CMake 構建方法的關鍵一步,我們將在課程的后續章節中對其作深入探討。


運?cmake

# 運? CMake 命令 就在這?步?成Makefile 
cmake .

我們看到cmake直接生成了makefile

有了makefile,那后續的工作大家肯定知道了吧

二. cmake的基礎命令?使用示例

接下來我將舉一個比較全面的例子。

我們接下來將介紹cmake的基礎命令?,介紹了如何?成構建?件,編譯鏈接,安裝等。

2.1.文件準備

mkdir cmake_tools
cd cmake_tools
touch main.cpp test.cpp CMakelists.txt 

main.cpp

#include <iostream>
int main()
{std::cout << "hello world!" << std::endl;return 0;
}

test.cpp

#include<iostream>
#include<assert.h>
int main()
{assert(1+2==3);std::cout<<"test OK"<<std::endl;
}
CmakeLists.txt
# 1 設置能運行此cmake 工程的最低cmake版本要求
# 指定構建本項目所需的最低CMake版本為3.18,確保使用的CMake特性得到支持
cmake_minimum_required(VERSION 3.18)# 2 設置項目名稱
# 定義項目名稱為"helloWorld",CMake會自動創建相關變量如PROJECT_NAME
project(helloWorld)# 3 添加構建目標
# 創建一個名為"main"的可執行文件,由main.cpp源文件編譯而成
# 相當于執行: g++ main.cpp -o main
add_executable(main main.cpp)# 創建另一個名為"testAdd"的可執行文件,專門用于測試
# 由test.cpp源文件編譯而成,通常包含單元測試代碼
add_executable(testAdd test.cpp)# 4 開啟測試功能 & 集成測試邏輯
# 包含CTest模塊,為項目添加測試支持功能
include(CTest)
# 添加一個名為"Case_Add"的測試用例
# 該測試通過運行專門編譯的測試程序"testAdd"來執行
add_test(NAME Case_Add      # 測試用例的名稱,用于標識和報告COMMAND testAdd    # 測試命令:運行測試可執行文件testAdd
)# 5 安裝二進制可執行程序到本地
# 包含GNUInstallDirs模塊,提供標準安裝目錄的定義
include(GNUInstallDirs)
# 安裝主程序目標"main"到默認安裝目錄
# 默認情況下會安裝到CMAKE_INSTALL_BINDIR(通常為bin目錄)
install(TARGETS main)# 6 開啟打包功能 & 打包二進制可執行程序
# 包含CPack模塊,為項目添加打包功能
include(CPack)
# CPack會自動收集所有通過install命令指定的目標
# 并將它們打包到一個可分發的壓縮包中(如ZIP、TGZ等格式)
# 使用cpack命令即可執行打包操作

2.2.?成構建系統

通過 cmake 可以看到cmake命令?持的詳細參數,常?的參數如下:

在 CMake 中,-S?和?-B?是兩個常用的命令行參數,用于明確指定項目的源目錄和構建目錄。

-S?參數用于指定源代碼的根目錄該目錄下必須包含一個頂層的?CMakeLists.txt?文件。這個源文件目錄代表了項目的“源文件樹”(Source Tree),即整個項目源代碼的目錄結構,CMake 正是通過該目錄中的?CMakeLists.txt?文件來識別和配置項目。

-B?參數用于指定構建目錄,即構建過程中生成的中間文件(如目標文件、依賴信息等)和最終輸出文件(如可執行文件、庫文件)的存放路徑。這個構建目錄被稱為“構建樹”(Build Tree),與源文件樹分開,以保持源代碼的整潔。構建目錄中通常會生成一個?CMakeCache.txt?文件,用于緩存CMake的配置變量,從而避免每次配置時重復檢測系統環境。

使用?-S?和?-B?參數是一種推薦的做法,它能夠清晰地將源代碼與生成的文件分離,既便于管理,也支持為不同構建配置(如Debug、Release)創建多個獨立的構建目錄。


在 CMake 構建過程中,根據構建生成的中間文件存放位置的不同,可分為兩種構建方式:源內構建與源外構建。

1.源內構建(In-Source Build)

指在包含頂層?CMakeLists.txt?的源代碼目錄中直接進行構建。此時,生成的所有中間文件和最終目標文件都會與源代碼混雜在同一目錄中。使用方式如下:

cmake .

該命令表示在當前目錄(即源代碼根目錄)中進行配置和生成構建系統。由于構建文件與源代碼混合存放,容易造成結構混亂,因此通常不推薦使用該方式。

2.源外構建(Out-of-Source Build)

指在一個獨立于源代碼的專門目錄(通常命名為?build)中進行構建。這樣做可以確保所有構建過程中產生的文件(包括中間文件、緩存文件和目標文件)與源代碼完全分離,保持源代碼樹的整潔。使用方式如下:

mkdir build && cd build
cmake ../

該命令首先創建并進入一個名為?build?的子目錄,然后在該目錄中執行 CMake,并通過?../?指定上一級目錄(即源代碼根目錄)作為源文件路徑。此時,build?為構建目錄,../?為源文件目錄。

源外構建是 CMake 官方推薦的最佳實踐。它不僅可以保持源代碼的純凈,還支持同時維護多個不同配置(如 Debug 與 Release)的構建目錄,極大提高了項目管理的靈活性和可維護性。


接下來我們將詳細講解下面這3個命令的用法。

用法一: cmake [options] <path-to-source>

cmake [options] <path-to-source>
  • 此命令在當前工作目錄中運行 CMake,并將其作為構建目錄

  • 參數?<path-to-source>?用于指定包含頂級?CMakeLists.txt?文件的源代碼目錄

  • 執行后,CMake 會在當前目錄生成所有的構建系統文件(如 Makefile)。

我們來看看

用法二:cmake [options] <path-to-existing-build>

  • 含義:此命令用于重新配置一個已經生成過的構建目錄

  • 參數?<path-to-existing-build>?是一個已經執行過 CMake 的構建目錄的路徑。

  • 使用場景:當你修改了源代碼目錄中的?CMakeLists.txt?文件或其他配置,需要重新生成構建系統時,使用此命令非常方便。它會在原有配置的基礎上應用最新的變更。

假設你后來修改了/root/cmake/cmake_tools/CMakeLists.txt?文件,需要重新生成構建系統時使用。

事實上,下面這個命令大有來頭

cmake .

cmake .?中的點號?.?在Linux/Unix系統中代表當前目錄

所以,這個命令的意思是:告訴CMake,以當前所在的目錄(/root/cmake/build)作為構建目錄(Build Directory),并且以當前目錄(/root/cmake/build)也作為源代碼目錄(Source Directory)。

為什么這次運行?cmake .?沒有報錯?

因為你所在的?build?目錄里已經存在一個由第一次CMake運行生成的?CMakeCache.txt?文件。這個緩存文件記錄了你最初的配置(包括源代碼的實際路徑在哪里)。所以當CMake再次在當前目錄運行時,它讀取了這個緩存,知道了真正的源代碼目錄在哪里,從而能夠成功完成配置。

我們仔細尋找

在他里面我們找到了這個

這個CMAKE_HOME_DIRECTORY:INTERNAL=/root/cmake/cmake_tools,不就是我們源代碼的目錄嗎?

用法三:cmake [options] -S <path-to-source> -B <path-to-build>

  • 含義:這是現代 CMake?推薦使用的命令格式。通過?-S?選項顯式指定源代碼目錄的路徑,通過?-B?選項顯式指定構建目錄的路徑。

  • 優勢

    • 清晰分離:明確將源代碼(只讀)和構建產物(可隨時清理)放在不同的目錄中,結構清晰。

    • 自動創建:如果?-B?指定的構建目錄不存在,CMake?會自動創建它,無需手動建立。

    • 通用性好:命令格式統一,易于記憶和腳本化。

接下來我們演示第3種方式

2.3.編譯連接

?成構建?件以后,就可以使?cmake來編譯鏈接,也可以使?第三?構建系統進?。

因為?成的makefile就在構建樹的根?錄下,所以可以直接在此?錄運?make。

cmake --build ./
或者
make 

2.4.測試Ctest模塊

正常我們在編寫功能代碼之后,也會編寫對應的單元測試代碼,然后使?ctest來調?我們的單元測 試。

如果cmake的配置?件CMakeLists.txt?包含CTest功能,則?成的makefile?也會包含test偽?標, 可以使?make來執?。

我們的CMakeLists.txt?就剛好包含了CTest功能。

第1行:include(CTest)

  • 這是什么?:這是一個指令,用于包含(啟用)CMake 的?CTest 模塊

  • 它做了什么?

    1. 啟用測試功能:它告訴 CMake:“本項目需要進行測試”。CMake 會因此生成必要的構建目標(如?make test)和文件(如?CTestTestfile.cmake)。

    2. 提供管理能力:它解鎖了一系列與測試相關的高級功能,比如:批量運行所有測試生成詳細的測試報告處理測試之間的依賴關系與持續集成(CI)系統(如 Jenkins, GitLab CI)無縫集成

簡單來說:include(CTest)?就是打開你項目的“測試總開關”。

第2-7行:add_test(...)

  • 這是什么?:這是一個指令,用于注冊一個具體的測試用例到 CTest 框架中。

  • 它做了什么?:它創建了一個名為?Case_Add?的測試項,并規定這個測試的運行方式就是執行?testAdd?這個命令。

讓我們分解它的參數:

  • NAME Case_Add

    • 這是測試用例的唯一標識符。CTest 在輸出報告時會使用這個名字。

    • 例如,你會看到?Passed: Case_Add?或?Failed: Case_Add,這比看到“第1個測試”清晰得多。

    • 你可以(也應該)添加多個?add_test?指令,每個都有描述性的名字(如?Case_Subtract,?FunctionA_InvalidInput_Test)。

  • COMMAND testAdd

    • 這是測試的核心——規定運行什么命令來執行測試

    • 這里的?testAdd?就是你之前通過?add_executable(testAdd test.cpp)?編譯出來的測試可執行文件的名稱

    • CTest 會運行這個命令,并根據它的退出狀態碼(Exit Code)來判斷測試是否通過

      • 返回 0:CTest 認為測試通過?(PASS)。

      • 返回非 0:CTest 認為測試失敗?(FAIL)。


我們來看看怎么使用

ctest
或者
make test

上面是測試成功的情況。

測試失敗的情況

我們回去把test.cpp修改成下面這樣子

#include<iostream>
#include<assert.h>
int main()
{assert(1+2==4);std::cout<<"test OK"<<std::endl;
}

我們發現它報錯了

我們運行Ctest模塊看看

錯誤信息解讀

  1. 測試結果摘要

    0% tests passed, 1 tests failed out of 1

    這很清楚:總共運行了1個測試,全部失敗了,成功率為0%。

  2. 失敗詳情

    1 - Case_Add (Subprocess aborted)

    具體是名為?Case_Add?的測試失敗了,失敗原因是:子進程異常中止 (Subprocess aborted)

  3. 關鍵線索

    Output from these tests are in: /root/cmake/build/Testing/Temporary/LastTest.log

    這告訴你:詳細的錯誤信息已經寫入了一個日志文件中

我們可以去這個日志里面看看

這個和我們手動運行的結果基本上是一樣的啊!!

?CTestTestfile.cmake文件

我們這里需要知道Ctest與CTestTestfile.cmake文件有關

簡單來說,CTestTestfile.cmake?是 CTest(CMake 的測試工具)的“測試清單”或“測試劇本”。它由 CMake 自動生成,其唯一目的是告訴?ctest?命令在這個特定的目錄下有哪些測試需要運行以及如何運行。

2.5.測試安裝模塊

在單元測試通過之后,我們可以使?cmake的安裝命令把庫和?進制發布到本機的標準路徑,供 ?家?起開發使?。

如果cmake的配置?件CMakeLists.txt?包含install函數,則?成的makefile?也 會包含install偽?標,可以使?make來執?。

這兩行代碼的目的是:定義一個規則,告訴 CMake 如何將編譯好的可執行文件?main?“正式安裝”到您系統的標準目錄中,使其成為一個可以被系統識別和全局使用的程序。

您可以把它理解為軟件開發的“發布”或“裝機”步驟。它完成了從“編譯成功”(程序在構建目錄里能用)到“安裝就緒”(程序在系統目錄里,任何地方都能用)的轉變。

第1行:include(GNUInstallDirs)

  • 這是什么?:這是一個包含(include)指令,它告訴 CMake 去加載一個名為?GNUInstallDirs?的內置模塊。

  • 為什么需要它?:不同的操作系統(甚至不同的 Linux 發行版)對于“應該把可執行文件裝在哪”、“庫文件裝在哪”、“頭文件裝在哪”都有自己的慣例和標準。GNUInstallDirs?模塊定義了一組跨平臺的 CMake 變量,這些變量自動指向當前系統遵循這些慣例的正確路徑。

  • 它提供了哪些重要變量?

    • CMAKE_INSTALL_BINDIR:通常指向?bin?目錄,用于安裝用戶可執行程序(如?main)。

    • CMAKE_INSTALL_SBINDIR:通常指向?sbin?目錄,用于安裝系統管理員的可執行程序

    • CMAKE_INSTALL_LIBDIR:通常指向?lib?或?lib64,用于安裝庫文件(.so, .a)。

    • CMAKE_INSTALL_INCLUDEDIR:通常指向?include,用于安裝頭文件(.h)。

    • 默認的安裝前綴(CMAKE_INSTALL_PREFIX)通常是?/usr/local。所以,CMAKE_INSTALL_BINDIR?的完整路徑通常是?/usr/local/bin

簡單來說:include(GNUInstallDirs)?就是讓 CMake 幫你搞清楚各個類型的文件在該系統上應該裝在哪,你不用自己去硬編碼路徑,保證了移植性。

第2行:install(TARGETS main)

  • 這是什么?:這是一個安裝(install)指令,它指定了要安裝的目標(Target)。這里的?main?就是你之前通過?add_executable(main main.cpp)?定義的那個可執行文件目標。

  • 它會做什么?

    1. 生成安裝規則:CMake 會在生成的構建系統(如 Makefile)中創建一條?install?規則。

    2. 指定安裝位置:因為你沒有明確指定安裝到哪里,CMake 會使用默認的安裝位置。對于可執行文件目標(add_executable?添加的),默認位置就是?GNUInstallDirs?模塊提供的?CMAKE_INSTALL_BINDIR(即?<prefix>/bin)。


我們現在來看看怎么來進行安裝

sudo cmake --install .
或者
sudo make install

現在這個main程序就被安裝到這個/usr/local/bin目錄里面了,我們也可以看看是什么情況

甚至,我們可以像下面這樣子執行這個文件

現在我們這個main程序就沒有那么容易被刪除了。

cmake_install.cmake文件

這個安裝模塊可是和cmake_install.cmake息息相關

這個文件里面就存儲了我們到底要怎么進行安裝

install_manifest.txt文件

執行了安裝之后,就會另外生成下面這個文件

這個就是我們已經安裝的資源清單

2.6.測試打包模塊

在 CMake 項目中,除了可以通過?install?命令將生成的目標文件(如可執行程序或動態庫)安裝到本地系統目錄之外,還可以借助 CPack 工具將相關文件打包成壓縮包的形式進行分發和共享,這種方式便于軟件在不同環境之間的傳遞和部署。

若項目的 CMake 配置文件?CMakeLists.txt?中引入了 CPack 功能(通常通過?include(CPack)?實現),則在生成的構建系統文件(例如 Makefile)中也會自動包含一個名為?package?的偽目標。用戶可通過執行諸如?make package?這樣的命令觸發打包流程,CPack 會自動根據安裝規則收集所有應安裝的文件,并生成指定格式的發布包。

這種機制不僅支持生成跨平臺的標準壓縮包格式(如 ZIP、TGZ 等),還可配置生成系統特定的安裝包格式,如 Linux 下的 RPM 或 DEB 包,以及 Windows 上的 NSIS 安裝包,極大提升了項目發布和部署的靈活性與便利性。

我們看看怎么使用啊

cpack
或者
make package

打包之前,我們先看看目錄里面有什么

我們現在執行打包

打包之后,我們再看看當前目錄有什么

我們重點關注helloWorld-0.1.1-Linux.tar.gz這么一個文件。

我們可以解壓一下

可以看看它的結構

我們知道執行make install會生成一個文件install_manifest.txt,而cpace就是會讀取和寫入這個文件。

CPack 的執行過程

CPack 的執行過程是一個結構化的多步驟流程,旨在將構建產物可靠地打包為可分發的格式。其核心步驟可概括如下:

  1. 首先,CPack 會在構建目錄中創建一個專用的臨時目錄,通常命名為?_CPack_Packages。該目錄作為模擬安裝環境的沙盒,確保后續操作不會影響實際系統路徑中的文件。
  2. 隨后,CPack 會主動執行由 CMake 自動生成的安裝腳本?cmake_install.cmake。該腳本中包含了項目中通過?install()?命令定義的所有安裝規則。此步驟的作用是將需要分發的目標文件(如可執行文件、庫文件及資源文件)按照預設的安裝邏輯部署到上述臨時目錄中,完全模擬一次本地安裝的過程。
  3. 接下來,CPack 會系統性地掃描并收集臨時目錄中所有已部署的文件,生成最終要打包的文件列表。這一機制確保了最終軟件包的內容與項目配置的安裝規則完全一致。
  4. 最后,CPack 根據用戶指定的或默認的包類型(如 ZIP、TGZ、RPM 或 DEB 等),對收集到的文件執行打包操作,生成壓縮包或系統安裝包。生成的軟件包文件會被輸出到項目的構建目錄中,便于用戶直接獲取或進一步分發。

整個過程充分體現了 CPack 與 CMake 安裝系統的緊密集成,確保軟件包內容的管理既自動化又高度可靠。

臨時目錄的作用

我們可以看看這個臨時目錄的結構

我們仔細一看,嗯?跟我們解壓出來的目錄結構好像是一樣的


我們用一個最簡單的比喻來解釋,保證你馬上明白。

想象一下你要搬家

  • 你的所有物品?= 你編譯好的程序文件(比如?main?和?testAdd?這兩個文件)

  • 新家的房間布局?= 電腦的目錄結構(比如?/usr/local/bin?放程序,/usr/local/lib?放庫)

  • 打包好的紙箱?= CPack 最終生成的?.zip?或?.deb?壓縮包

現在問題來了:你怎么確保打包時,東西都放對了箱子,并且到了新家能立刻找到?

最笨的方法:直接從舊房子的各個角落(你的項目文件夾)里亂抓一通,胡亂塞進紙箱。結果到了新家,你發現勺子可能在衣柜里,襪子可能在廚房里——全亂套了。

聰明的方法(也就是 CPack 的方法)

  1. 你先在客廳的空地上?(_CPack_Packages),嚴格按照新家的布局,模擬擺放一次。

    • 比如,在地上畫個圈,標上“廚房”,然后把所有廚房用品暫時放在這個圈里。

    • 再畫個圈,標上“臥室”,把所有衣服暫時放在這里。

  2. 檢查一遍:看看“廚房”圈里是不是只有廚房用品,“臥室”圈里是不是只有衣服。確保每樣東西都放在了正確的位置,沒有漏掉任何東西。

  3. 開始打包:現在你看一眼“廚房”圈,把里面的所有東西打包到一個箱子上,并在箱子上貼好標簽“廚房”。再看一眼“臥室”圈,把所有東西打包到另一個箱子上,貼上“臥室”。

  4. 最后,把這些打包好的紙箱(壓縮包)運走。同時,把客廳地上畫的圈(臨時目錄)擦掉,恢復原狀。

所以,_CPack_Packages?就是這個“客廳的空地”!

它的作用就是:

  1. 提供一個臨時空間,讓 CPack 能把你程序的所有文件,按照最終要安裝的目錄結構(如?bin,?lib)先好好地、正確地擺放一次

  2. 檢查一下有沒有錯誤。

  3. 從這個擺放好的、絕對正確的臨時布局中,生成最終的壓縮包。

這樣做的巨大好處是:保證了壓縮包里的結構,和安裝到你電腦里的結構是一模一樣的,絕對不會出錯。

總結一句話:_CPack_Packages?就是 CPack 用來“預演”安裝過程、確保打包結果萬無一失的“臨時排練場”。?打包一結束,這個排練場就被拆掉了。

make install和make package對于install_mainfest.txt的作用

執行?make install?時,系統會讀取?install_manifest.txt?中列出的文件列表,并將其安裝到指定的系統目標路徑,默認情況下通常是?/usr/local

執行?make package?或?cpack?時,系統同樣會依據?install_manifest.txt?中的清單收集需要分發的文件,但并不會將其安裝到系統路徑中。相反,這些文件會被放置在一個專為打包創建的臨時目錄(通常命名為?_CPack_Packages)中,該目錄模擬了目標系統的目錄結構。

Cpack配置文件——CPackConfig.cmake

我給大家列舉了一下CPackConfig.cmake的部分內容

還是有很多配置的,我們先不詳細講解。

同樣我們的最簡hello_world?程沒實現cpack規則,其中就包括沒有指定cpack?成器。在第三章 ?我們會詳細介紹CPack的使?。

2.7?查看幫助

cmake --help

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/94047.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/94047.shtml
英文地址,請注明出處:http://en.pswp.cn/web/94047.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

概率核心概念學習筆記:隨機事件與樣本空間、古典概率與條件概率、全概率公式與貝葉斯公式

目錄 一、 隨機事件與樣本空間 1. 原理講解 2. 類型與關系 3. 案例計算 4. 應用場景 二、 古典概率與條件概率 1. 古典概率 (Classical Probability) 2. 條件概率 (Conditional Probability) 三、 全概率公式與貝葉斯公式 1. 全概率公式 (Law of Total Probability) …

優考試局域網系統V6.0.0版

優考試局域網系統迎來V6.0.0版本更新&#xff0c;核心在于提升功能性能與優化操作體驗。重點對學情分析、移動端考試支持、考試監控和答題體驗等方面進行了實用性更新&#xff0c;進一步提升了局域網環境下考試系統的靈活性與管理效率。 一、增加學情分析功能&#xff0c;教學…

Autosar之Com模塊

Com模塊主要實現了Signal在I-PDU中的封裝及解析功能,為RTE層提供了基于Signal的發送與接收接口,實現了基于Signal的網關功能,實現了PDU的不同發送模式,以及Signal濾波,Update bit,Pdu Counter等功能 圖 Com模塊層次圖 Com模塊處于AUTOSAR架構中的通信服務層,其下層模塊…

【iOS】NSRunLoop

目錄 概念 RunLoop與線程的關系 Runloop對外的接口 CFRunLoopSourceRef Source0 Source1 CFRunLoopTimer CFRunLoopObserver RunLoop的Mode 應用場景 Runloop的內部邏輯 Runloop應用 tableView延遲加載圖片&#xff0c;保證流暢 Timer不被ScrollView的滑動影響 A…

HTTP接口鑒權方式

幾種主流且可行的HTTP接口鑒權方式&#xff0c;從簡單到復雜&#xff0c;各有其適用場景。我將它們分為兩大類&#xff1a;傳統方式和現代方式。一、傳統方式這類方式簡單易用&#xff0c;但通常安全性較低或擴展性較差&#xff0c;適用于內部系統或簡單API。1. HTTP Basic Aut…

DIC技術極端環境案例分享:系泊鏈在海水環境下氫脆化性能測試

實驗結果的具體視頻可詳見以下鏈接&#xff1a;研索儀器DIC技術在極端條件下的應用 01 海水環境&#xff1a; DIC技術在海水環境下的應用核心挑戰在于惡劣的光學條件&#xff08;如散射、衰減、畸變&#xff09;、嚴酷的化學/生物環境&#xff08;腐蝕、生物污損&#xff09;…

DL00291-聯邦學習以去中心化鋰離子電池健康預測模型完整實現

聯邦學習在鋰離子電池健康預測中的應用&#xff1a;去中心化訓練與客戶選擇策略在鋰離子電池健康預測領域&#xff0c;隨著電池使用環境的多樣化以及電池狀態監測需求的不斷增長&#xff0c;傳統的集中式數據訓練方法逐漸顯現出局限性。為了解決數據隱私保護和大規模數據集中處…

TCP協議大全

什么是TCP&#xff1f;基本定義與屬性TCP&#xff08;傳輸控制協議&#xff09;是傳輸層的重要協議&#xff0c;具有面向連接&#xff08;傳輸前需先建立連接&#xff0c;是發送方和接收方的點對點一對一連接&#xff09;、基于字節流&#xff08;以字節流形式傳輸數據&#xf…

當硅基生命遇見碳基萌寵:Deepoc具身智能如何重新定義“寵物監護者”

在東京某高級公寓里&#xff0c;一只布偶貓正優雅地踱步到智能喂食器前。令人驚訝的是&#xff0c;這個通體雪白的喂食器突然"活"了過來——它微微傾斜身體&#xff0c;用柔和的機械音發出問候&#xff0c;同時伸出仿生機械臂輕輕撫過貓咪的背部。這不是科幻電影場景…

線上日志排查問題

1、查異常堆棧 顯示該行及其后面的50行內容&#xff0c;然后通過 less 命令進行分頁查看 grep -A 50 "NullPointerException" a.log | less參數解釋&#xff1a; grep: 文本搜索命令-A 50: After 的意思&#xff0c;顯示匹配行后面的50行“NullPointerException”: 要…

LabVIEW與CAN開發燃料電池監控

?基于 LabVIEW 與 CAN 總線技術&#xff0c;構建了一套多組質子交換膜燃料電池&#xff08;PEMFC&#xff09;堆監控系統。系統采用優質硬件設備&#xff0c;通過 LabVIEW 的圖形化編程能力實現數據采集、實時監控與多堆切換控制&#xff0c;穩定可靠&#xff0c;為燃料電池性…

CVPR焦點 | 神經網絡新范式:輕量化與精度并行,重塑視覺任務性能天花板

關注gongzhonghao【CVPR頂會精選】神經網絡卷積想找新亮點&#xff1f;不妨考慮&#xff1a;動態結構設計。作為深度學習架構搜索與高效建模兩大熱點的結合&#xff0c;動態神經網絡憑借自適應推理與高效特征利用的優勢&#xff0c;在視覺識別、視頻理解等任務中脫穎而出&#…

機器學習之集成算法學習

一、集成學習概述集成學習&#xff08;ensemble learning&#xff09;通過構建并結合多個個體學習器來完成學習任務&#xff0c;核心思想是 “集眾家之長”—— 就像多個專家共同判斷往往比單個專家更可靠。其關鍵在于如何生成多樣化的個體學習器并設計有效的結合策略。結合策略…

Unreal Engine UE_LOG

Unreal&#x1f3ae; Unreal Engine - UE_LOG&#x1f4dd; 定義&#x1f3db; 類/宏關聯? 關鍵特性&#x1f6e0;? 常見配置&#x1f4da; 使用方法&#x1f527; 基礎語法&#x1f50d; 示例&#x1fa82; 典型應用場景&#x1f517; 與其他組件對比?? 常見問題與注意事項…

Halcon那些事:什么是動態閾值,如何用dyn_threshold分割圖片

Halcon那些事:什么是動態閾值,如何用dyn_threshold分割圖片 一、什么是動態閾值?為什么需要它? 1. 傳統全局閾值的局限性 2. 動態閾值的核心思想 二、Halcon 中的核心算子:`dyn_threshold` 1. 算子原型 2. 參數詳解 三、工作原理(數學模型) 四、詳細使用步驟與實例 五、關…

Go初級二

Go初級入門&#xff08;二&#xff09;&#xff1a;變量、常量與數據類型 大家好&#xff0c;歡迎來到《Go初級入門》系列的第二篇&#xff01;在上一篇文章中&#xff0c;我們介紹了如何安裝Go環境并運行第一個“Hello, World”程序。今天&#xff0c;我們將深入Go語言的基礎語…

《戰神:諸神黃昏》v1.0.668中文版,索尼大作,PC平臺體驗諸神黃昏

[游戲名稱]: 《戰神&#xff1a;諸神黃昏》v1.0.668中文版 [軟件大小]: 175 GB [軟件大小]: 夸克網盤 游戲介紹 《戰神&#xff1a;諸神黃昏》是由索尼制作并發行的動作冒險游戲&#xff0c;作為《戰神4》的正統續作&#xff0c;它繼續了奎托斯與阿特柔斯的神話之旅。在諸神…

AI賦能環保精準治理:AI水質監測溯源快、空氣質量預測施策準,守護生態新效能

傳統環境保護工作長期受限于 “污染監測滯后”“溯源難度大”“治理方案針對性弱” 的問題&#xff0c;而 AI 技術的深度應用&#xff0c;正讓環保工作從 “被動應對” 轉向 “主動預判”&#xff0c;既能實時捕捉污染蹤跡&#xff0c;還能精準制定治理方案&#xff0c;讓生態保…

yolo訓練實例(一)

yolo官網 https://github.com/ultralytics/ultralytics?tabreadme-ov-file 下載python和解除限制 https://www.python.org/downloads/windows/ Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled"…

STM32-BKP備份寄存器與RTC實時時鐘

引言本文主要從BKP備份寄存器和RTC實時時鐘的原理&#xff0c;特性及應用三個方面展開討論&#xff0c;解析它們在STM32中的獨特價值&#xff0c;助力開發者更好的掌握和運用它們。BKP備份寄存器的定義STM32的BKP備份寄存器是一種特殊的存儲單元&#xff0c;它位于備份區域&…