CMake 構建系統概述

關鍵要點

  • 研究表明,CMake 是一種強大的跨平臺構建系統,廣泛用于 C++ 項目。
  • 證據傾向于認為,CMake 通過生成本地構建文件(如 Makefile、Visual Studio 項目)簡化軟件構建。
  • 它似乎可能支持多種平臺,包括 Windows、Linux 和 macOS,適合復雜項目。
  • 存在爭議,部分開發者認為其腳本語言學習曲線較陡,但社區支持廣泛。

CMake 構建系統概述

什么是 CMake?
CMake 是一種跨平臺構建系統生成工具,最初于 2000 年由 Kitware 公司開發,旨在解決傳統構建工具(如 Make 和 autoconf)在跨平臺上的局限性。它不直接編譯代碼,而是生成本地平臺的構建文件(如 Makefile、Visual Studio 項目文件、Ninja 腳本等),方便在不同操作系統(如 Windows、Linux、macOS)上構建軟件。CMake 的核心是 CMakeLists.txt 文件,用于描述項目的結構、源文件和構建設置。

如何工作?
CMake 的工作流程分為兩步:

  1. 配置階段:運行 cmake 命令,解析 CMakeLists.txt,生成適合目標平臺的構建文件。
  2. 構建階段:使用生成的構建文件(如 make 或 Visual Studio)編譯和鏈接代碼。
    它支持出源構建,將構建文件存儲在獨立目錄(如 build/),避免污染源代碼目錄。

使用方法
使用 CMake 需要:

  • 創建 CMakeLists.txt,定義項目信息和目標。例如:

    ?

    cmake_minimum_required(VERSION 3.0.0)
    project(myApp VERSION 1.0 DESCRIPTION "一個簡單的 CMake 示例" LANGUAGES CXX)
    add_executable(myApp src/main.cpp)
    target_compile_features(myApp PRIVATE cxx_std_20)

  • 在構建目錄運行 cmake .. 生成文件,然后用 cmake --build . 構建項目。

優勢
CMake 因其跨平臺能力、依賴管理能力和社區支持而受歡迎。相比其他工具:

  • 比 Make 更強大,自動處理依賴;
  • 比 Autotools 更簡單,Windows 支持更好;
  • 比 SCons 更快,比 Premake 錯誤報告更清晰。


詳細調研筆記:CMake 構建系統的來龍去脈

CMake 構建系統是現代軟件開發中不可或缺的工具,尤其在 C++ 項目中占據主導地位。以下是其定義、歷史、工作原理、關鍵特性、使用方法和優勢的詳細分析,旨在為讀者提供全面的理解。

1. 定義與背景

CMake 是一種跨平臺的構建系統生成工具(meta-build system),由 Kitware 公司于 2000 年開發,最初是為了支持 Insight Segmentation and Registration Toolkit (ITK) 的多平臺構建。它的核心目標是解決傳統構建工具(如 Make 和 autoconf)在跨平臺上的局限性,例如 Make 文件高度依賴平臺,Windows 上需要額外的工具(如 nmake),而 autoconf 生成的腳本復雜且難以維護。

CMake 的工作方式是通過解析 CMakeLists.txt 文件,生成本地平臺的構建文件(如 Unix 的 Makefile、Windows 的 Visual Studio 項目文件、Ninja 構建腳本等),然后由這些本地工具實際執行構建。它的設計理念是“一次編寫,處處構建”,適合從簡單項目到復雜大型項目的構建需求。

2. 歷史與發展

CMake 的開發始于 1999 年,受到美國國家醫學圖書館資助,旨在支持 Visible Human Project 下的 ITK 項目。2000 年,CMake 1.0 正式發布,初期功能包括依賴主機 C++ 編譯器、生成 Visual Studio 和 Unix makefiles、支持構建程序、靜態庫和共享庫等。

  • 早期發展(2000-2010)
    • CMake 1.0 發布,支持基本的項目定義和源文件管理。
    • 2006 年,CMake 2.0 發布,引入條件構建(if 語句)、變量管理和宏定義,增強靈活性。
    • 被更多項目采用,如 Visualization Toolkit (VTK) 和 ITK,功能擴展到更多平臺。
  • 中期發展(2010-2014)
    • 2010 年,CMake 2.8 發布,引入對外部庫的自動檢測(如 find_package),簡化依賴管理。
    • 2014 年,CMake 3.0 發布,標志著“現代 CMake”的開始,強調使用目標(targets)和屬性(properties)取代全局變量。這使得 CMakeLists.txt 的編寫更加模塊化和可維護。
  • 現代發展(2014-至今)
    • 2016 年,CMake 3.7 引入對 C++ 標準庫的自動鏈接,進一步簡化 C++ 項目構建。
    • 2020 年,CMake 3.18 引入對 C++ 模塊的支持,增強代碼依賴管理。
    • 截至 2025 年 6 月 14 日,CMake 4.0 發布,支持替代項目文件名,方便開發者過渡。

以下表格總結了 CMake 的主要發展里程碑:

年份版本主要變化
20001.0基本項目定義和源文件管理,支持跨平臺構建。
20062.0引入條件構建、變量管理和宏定義,增強靈活性。
20102.8支持外部庫自動檢測(如 find_package)。
20143.0強調目標和屬性管理,現代 CMake 開始。
20163.7支持 C++ 標準庫自動鏈接,簡化 C++ 項目構建。
20203.18引入 C++ 模塊支持,增強代碼依賴管理。
20224.0支持替代項目文件名,方便開發者過渡。
3. 工作原理

CMake 的工作流程分為兩個階段:

  • 配置階段
    • 用戶運行 cmake <source_dir> 命令,CMake 解析 CMakeLists.txt,根據指定的生成器(如 Unix Makefiles、Ninja)生成本地平臺的構建文件。
    • 支持出源構建,用戶可以在源目錄外創建構建目錄(如 build/),運行 cmake .. 生成文件。
  • 構建階段
    • 使用生成的構建文件調用本地構建工具。例如,生成 Makefile 后,可以運行 make 或 cmake --build . 編譯和鏈接代碼。
    • CMake 確保依賴關系正確,自動處理增量構建(只重新構建發生變化的部分)。
  • 關鍵文件:CMakeLists.txt
    • CMakeLists.txt 是 CMake 的核心配置文件,包含項目信息、源文件列表、構建目標和依賴管理。
    • 示例:

      ?

      cmake_minimum_required(VERSION 3.0.0)
      project(myApp VERSION 1.0 DESCRIPTION "一個簡單的 CMake 示例" LANGUAGES CXX)
      add_executable(myApp src/main.cpp)
      target_compile_features(myApp PRIVATE cxx_std_20)

    • 支持分層結構,根目錄的 CMakeLists.txt 可以包含子目錄的 CMakeLists.txt,反映項目目錄結構。
4. 關鍵特性

CMake 的功能強大,涵蓋以下方面:

  • 跨平臺支持
    • 支持生成多種平臺的構建文件,包括 Windows(Visual Studio、NMake)、Linux(Make、Ninja)、macOS(Xcode)、iOS、Android 等。
    • 通過單套 CMakeLists.txt 文件實現跨平臺構建。
  • 生成器(Generators)
    • 支持多種生成器,如 Unix Makefiles、Ninja、Visual Studio、Xcode、Eclipse CDT 等。
    • 用戶可以通過 -G 選項指定生成器,例如 cmake -G "Unix Makefiles" ..。
  • 構建目標(Targets)
    • 支持定義可執行文件(add_executable)、靜態庫(add_library STATIC)、共享庫(add_library SHARED)等。
    • 現代 CMake 強調使用目標屬性(如 target_compile_options、target_link_libraries)而非全局變量。
  • 依賴管理
    • 通過 find_package 查找系統庫或外部依賴,通過 FetchContent 下載和構建依賴。
    • 自動處理依賴關系,確保下游組件在源文件變化時重新構建。
  • 條件構建
    • 使用 if、elseif、else 等命令支持根據平臺、編譯器或用戶選項進行條件構建。
    • 示例:
      if(WIN32)target_compile_options(myApp PRIVATE /W4)
      else()target_compile_options(myApp PRIVATE -Wall -Wextra)
      endif()

  • 模塊化和可維護性
    • 現代 CMake(從 3.0 開始)建議使用目標和屬性,而不是全局變量(如 CMAKE_CXX_FLAGS),提高模塊化。
    • 示例:target_compile_features(myApp PRIVATE cxx_std_20) 設置 C++ 標準。
  • 包管理(Packaging)
    • 通過 CPack 工具支持生成安裝包(如 .deb、.rpm、.msi),便于分發。
  • IDE 支持
    • 可以生成 IDE 項目文件,如 Visual Studio 解決方案、Xcode 項目文件、Eclipse 項目文件等。
  • 其他特性
    • 支持預編譯頭(從 3.6 開始)、C++ 模塊(從 3.28 開始)、JSON 數據提取(從 3.19 開始)。
5. 使用方法

使用 CMake 構建項目通常涉及以下步驟:

  • 創建 CMakeLists.txt
    • 在項目根目錄創建 CMakeLists.txt,定義項目信息、源文件和構建目標。
    • 示例:

      ?

      cmake_minimum_required(VERSION 3.0.0)
      project(myApp VERSION 1.0 DESCRIPTION "一個簡單的 CMake 示例" LANGUAGES CXX)
      add_executable(myApp src/main.cpp)
      target_compile_features(myApp PRIVATE cxx_std_20)

  • 創建構建目錄
    • 創建獨立構建目錄(如 build/),支持出源構建。
  • 運行 CMake
    • 在構建目錄運行 cmake .. 生成構建文件。
    • 可通過 -G 指定生成器,例如 cmake -G "Unix Makefiles" ..。
  • 構建項目
    • 使用 cmake --build . 或調用本地工具(如 make)構建項目。
  • 安裝(可選)
    • 如果定義了安裝規則,可運行 cmake --install . 安裝項目。
  • 基本命令
    • cmake_minimum_required(VERSION <version>):指定所需 CMake 版本。
    • project(<name> VERSION <version> DESCRIPTION "<desc>" LANGUAGES <lang>):定義項目。
    • add_executable(<name> <source_files>):創建可執行文件。
    • add_library(<name> STATIC|SHARED <source_files>):創建庫。
    • target_compile_features(<target> PRIVATE <feature>):設置編譯特征。
    • target_compile_options(<target> PRIVATE <options>):設置編譯選項。
    • find_package(<package>):查找外部庫。
    • option(<var> "<desc>" [value]):定義可選變量。
6. 優勢與與其他構建系統的比較

CMake 的優勢使其在現代軟件開發中備受青睞:

  • 跨平臺能力
    • 支持從桌面到移動設備(iOS、Android)再到高性能計算系統的多平臺構建。
  • 高效和靈活
    • 自動處理依賴關系,確保只重新構建必要的部分。
    • 支持復雜的條件構建和模塊化配置。
  • 與其他構建系統的比較
    • 與 Make 比較:CMake 自動處理依賴關系,而 Make 需要手動維護,適合更復雜的項目。
    • 與 Autotools 比較:Autotools 在 Windows 上表現不佳,而 CMake 更易于跨平臺使用。
    • 與 SCons 比較:SCons 速度較慢,而 CMake 更高效。
    • 與 Premake 比較:Premake 的錯誤報告較差,而 CMake 提供更清晰的錯誤信息。
    • 與 Ninja 比較:Ninja 是快速構建工具,但需要 CMake 等高層工具生成輸入。
    • 與 Meson 比較:Meson 專注于速度,但 CMake 在平臺支持(如 iOS、Android)上更全面。
  • 社區和生態
    • CMake 是 C++ 項目的 de-facto 標準,擁有龐大的用戶社區和豐富的資源。
    • 被廣泛用于開源項目(如 Android NDK、Boost、KDE)和商業軟件(如 Netflix、MySQL)。
7. 總結

CMake 構建系統是現代軟件開發中不可或缺的工具,尤其在 C++ 項目中。它通過生成本地平臺的構建文件,實現了跨平臺的軟件構建,同時提供了強大的依賴管理、條件構建和模塊化配置能力。CMake 的發展歷程從 2000 年至今,經歷了從簡單項目支持到復雜大型項目的演變,尤其在 2014 年后的“現代 CMake”階段,強調了目標和屬性的使用,提高了構建腳本的可讀性和可維護性。

對于開發者來說,掌握 CMake 是高效管理跨平臺項目的關鍵。通過簡單的 CMakeLists.txt 文件,開發者可以輕松定義項目結構、構建目標和依賴關系,從而在不同平臺上高效地構建軟件。


關鍵引文

  • CMake 官方網站詳細介紹
  • CMake Wikipedia 歷史與特性
  • 現代 CMake 初學者指南
  • 構建系統概述與比較

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

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

相關文章

如何順利將電話號碼轉移到新iPhone?

當您升級到新 iPhone 時&#xff0c;您需要做的第一件事就是轉移您的電話號碼。幸運的是&#xff0c;以目前的技術&#xff0c;很容易解決如何將電話號碼轉移到新iPhone上。此外&#xff0c;傳輸過程也得到了簡化。您可以輕松地將舊手機更換為新 iPhone&#xff0c;而不會丟失任…

java面試總結-20250609

DDD領域設計模型怎么理解&#xff1f; mysql和mongoDB分別適用于哪些業務場景&#xff1f; 查詢的場景&#xff0c;數量級的差異&#xff1f; mongodb為什么用B樹&#xff1f;用的什么數據引擎&#xff0c;部署方式使用什么模式&#xff0c;分片分了多少片&#xff0c;路由方…

使用GpuGeek訓練圖像分類器:從入門到精通

引言 在當今人工智能蓬勃發展的時代&#xff0c;圖像分類作為計算機視覺的基礎任務之一&#xff0c;已經廣泛應用于醫療診斷、自動駕駛、安防監控等諸多領域。然而&#xff0c;對于許多初學者和中小型企業來說&#xff0c;構建一個高效的圖像分類系統仍然面臨諸多挑戰&#xf…

Qt Widget類解析與代碼注釋

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解釋這串代碼&#xff0c;寫上注釋 當然可以&#xff01;這段代碼是 Qt …

2025年滲透測試面試題總結-字節跳動[實習]安全研發員(題目+回答)

安全領域各種資源&#xff0c;學習文檔&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各種好玩的項目及好用的工具&#xff0c;歡迎關注。 目錄 字節跳動[實習]安全研發員 1. 攻防演練中得意經歷 2. 安全領域擅長方向 3. 代碼審計語言偏向 4. CSRF修復…

Springboot短視頻推薦系統b9wc1(程序+源碼+數據庫+調試部署+開發環境)帶論文文檔1萬字以上,文末可獲取,系統界面在最后面。

系統程序文件列表 項目功能&#xff1a;用戶,視頻分類,視頻信息 開題報告內容&#xff1a; 基于Spring Boot的短視頻推薦系統開題報告 一、研究背景與意義 隨著移動互聯網的普及和短視頻行業的爆發式增長&#xff0c;用戶日均觀看短視頻時長已突破2小時&#xff0c;但海量內…

使用聯邦學習進行CIFAR-10分類任務

在深度學習領域,圖像分類任務是一個經典的應用,而CIFAR-10數據集則是圖像分類研究中的重要基準數據集之一。該數據集包含10類不同的圖像,每類有6,000個32x32像素的彩色圖像,共計60,000個圖像。在傳統的集中式學習中,所有數據都被集中到一個服務器上進行訓練。然而,隨著數…

【Linux網絡編程】基于udp套接字實現的網絡通信

目錄 一、實現目標&#xff1a; 二、實驗步驟&#xff1a; 1、服務端代碼解析&#xff1a; Init()&#xff1a; Run()&#xff1a; 2、客戶端代碼&#xff1a; 主函數邏輯&#xff1a; send_message發送數據&#xff1a; recv_message接收數據&#xff1a; 三、實驗結…

2025年想沖網安方向,該考華為安全HCIE還是CISSP?

打算2025年往網絡安全方向轉&#xff0c;現在考證是不是來得及&#xff1f;考啥證&#xff1f; 說實話&#xff0c;網絡安全這幾年熱得發燙&#xff0c;但熱歸熱&#xff0c;入門門檻也不低&#xff0c;想進這個賽道&#xff0c;技術、項目經驗、證書&#xff0c;缺一不可。 …

【系統架構設計師-2025上半年真題】綜合知識-參考答案及部分詳解(回憶版)

更多內容請見: 備考系統架構設計師-專欄介紹和目錄 文章目錄 【第1題】【第2題】【第3題】【第4題】【第5題】【第6題】【第7題】【第8題】【第9題】【第10題】【第11題】【第12題】【第13題】【第14題】【第15題】【第16題】【第17題】【第18題】【第19題】【第20~21題】【第…

「Java EE開發指南」如何用MyEclipse創建一個WEB項目?(一)

在本文中&#xff0c;您可以找到有關WEB項目的信息。將了解&#xff1a; Web項目結構和參數Web開發生產力工具JSP代碼完成和驗證 這些特性在MyEclipse中可用。 MyEclipse v2025.1離線版下載 一、Web項目結構 用最簡單的術語來說&#xff0c;MyEclipse Web項目是一個Eclips…

Elasticsearch:使用 ES|QL 進行地理空間距離搜索

作者&#xff1a;來自 Elastic Craig Taverner 在 Elasticsearch 查詢語言&#xff08;ES|QL&#xff09;中探索地理空間距離搜索&#xff0c;這是 Elasticsearch 地理空間搜索中最受歡迎和最有用的功能之一&#xff0c;也是 ES|QL 中的重要特性。 想獲得 Elastic 認證嗎&#…

列舉開源的模型和推理框架

當然可以&#xff01;下面是一個系統性的列表&#xff0c;按 開源大模型&#xff08;LLM&#xff09; 和 推理框架 兩大類列出&#xff0c;并配上簡要說明。 &#x1f9e0; 一、開源大語言模型&#xff08;LLMs&#xff09; 名稱發布者語言能力模型大小特點LLaMA 2 / 3Meta英文…

深入講解一下 Nomic AI 的 GPT4All 這個項目

我們來深入講解一下 Nomic AI 的 GPT4All 這個項目。 這是一個非常優秀和流行的開源項目&#xff0c;我會從**“它是什么”、“為什么它很重要”、“項目架構和源碼結構”以及“如何使用”**這幾個方面為你全面剖析。 一、項目概述 (Project Overview) 簡單來說&#xff0c;…

力扣HOT100之技巧:287. 尋找重復數

這道題真的是中等題嗎&#xff1f;我請問呢&#xff1f;&#xff1f;我怎么覺得是困難題呢&#xff1f; 這道題的思路太難想了&#xff0c;想不出來&#xff0c;直接去看的這位大佬的題解&#xff0c;寫得很清楚。 這道題可以將其轉化為環形鏈表問題&#xff0c;可是為什么只要…

QT log4qt 無法生成日志到中文的路徑中的解決方案

一.使用log4qt時,應用程序安裝在帶有中文路徑下,導致無法生成日志到安裝目錄中? 問題描述:如下的配置文件,log4j.appender.File.File 后面跟隨的路徑是當前路徑,你可能覺得自己的日志能夠生成在當前路徑中,如果你試著用自己的程序雙擊啟動一個文件時,你會發現日志生成在…

讓 Deepseek 寫電器電費計算器小程序

微信小程序版電費計算器 以下是一個去掉"電器名稱"后的微信小程序電費計算器代碼&#xff0c;包含所有必要文件&#xff1a; 1. app.json (全局配置) {"pages": ["pages/index/index"],"window": {"backgroundColor": &q…

第二部分-靜態路由實驗

目錄 一、什么是路由&#xff1f; 1.1.定義 1.2.路由作用 1.3.路由類型 1.3.1.直連路由 1.3.2.靜態路由 1.3.3.動態路由 1.3.4.路由表 1.5.路由器的匹配原則 1.6.路由配置 1.6.1.靜態路由配置 1.6.2.動態路由配置 二、實驗 2.1.靜態路由 2.1.1.實驗拓撲 2.1.2.實驗過程 2.2.缺省…

Could not initialize Logback logging from classpath:logback-spring.xml

jdk21、springboot 3.2.12啟動報錯找不到logback.xml Logging system failed to initialize using configuration from classpath:logback-spring.xml java.lang.IllegalStateException: Could not initialize Logback logging from classpath:logback-spring.xmlat org.sprin…

NORA:一個用于具身任務的小型開源通才視覺-語言-動作模型

25年4月來自新加坡技術和設計大學的論文“NORA: a Small Open-Sourced Generalist Vision Language Action Model for Embodied Tasks”。 現有的視覺-語言-動作 (VLA) 模型在零樣本場景中展現出優異的性能&#xff0c;展現出令人印象深刻的任務執行和推理能力。然而&#xff…