CMake進階:Ninja環境搭建與加速項目構建

目錄

1.引入Ninja的原因

2.Ninja 環境搭建(跨平臺)

2.1.Linux系統安裝

2.2.macOS 系統

2.3.Windows 系統

2.4.源碼編譯安裝(通用方案)

3.Ninja 與構建系統配合:以 CMake 為例

4.加速構建的關鍵技巧

5.Ninja 與 Make 構建速度對比

6.項目構建過程中遇到的問題

7.總結

相關鏈接


1.引入Ninja的原因

????????Ninja 是一款由 Google 開發的輕量、高速的構建系統,專注于 “快速執行構建”,尤其擅長處理大型項目的頻繁增量構建。相比傳統的 Make,Ninja 啟動速度更快、并行編譯效率更高,是頻繁迭代開發場景(如 C++/Rust 項目)的理想選擇。

?????????Ninja 加速構建的核心原因:

1.極簡設計:Ninja 的構建文件(.ninja)語法簡單,僅包含必要的依賴和命令,解析速度遠快于 Makefile(避免 Make 的復雜語法和冗余處理)。

2.高效并行:默認充分利用多核 CPU,并行任務調度更智能(比 Make 更精準地控制并行數,減少資源競爭)。

3.增量構建優化:對文件修改的檢測和依賴跟蹤更高效,僅重新編譯受影響的文件,避免不必要的重建。

4.無冗余開銷:啟動時幾乎無額外計算(如 Make 會重新解析整個 Makefile),適合頻繁構建(如開發中 “改一行代碼就重建” 的場景)。

2.Ninja 環境搭建(跨平臺)

Ninja 支持 Windows、Linux、macOS,安裝方式簡單,優先推薦通過包管理器或官方二進制包安裝。

2.1.Linux系統安裝

通過包管理器安裝(推薦)

Ubuntu/Debian:

sudo apt update && sudo apt install ninja-build

Fedora/RHEL:

sudo dnf install ninja-build

Arch Linux:

sudo pacman -S ninja

驗證安裝

ninja --version  # 輸出版本號即成功(如 1.11.1)

2.2.macOS 系統

通過 Homebrew 安裝(推薦)

brew install ninja

驗證:

ninja --version

2.3.Windows 系統

Windows 需手動配置 PATH,推薦以下兩種方式:

方式 1:包管理器安裝(需先安裝 Chocolatey 或 Scoop):

Chocolatey:

    choco install ninja -y

    Scoop:

    scoop install ninja

    方式 2:手動下載二進制

    1. 從?Ninja 官網?下載最新 Windows 二進制包(如?ninja-win.zip)。
    2. 解壓得到?ninja.exe,將其所在目錄(如?C:\tools\ninja)添加到系統環境變量?PATH
    3. 重啟終端,執行?ninja --version?驗證。

    2.4.源碼編譯安裝(通用方案)

    若上述方法不適用,可從源碼編譯(需 Python 3 環境):

    構造Ninja可使用CMake或python,需要先安裝re2c:

    1.安裝re2c。下載地址:http://re2c.org/index.html

    tar -xvzf re2c-1.0.3.tar.gz   # 解壓
    cd re2c-1.0.3/                # 進入目錄
    autoreconf -i -W all          # 生成configure(若無configure時用)
    ./configure                   # 配置編譯選項
    make                          # 編譯
    sudo make install             # 安裝(需管理員權限)

    2.re2c安裝成功之后開始Ninja安裝:

    # 克隆源碼
    git clone https://github.com/ninja-build/ninja.git
    cd ninja# 編譯(生成 ninja 二進制文件)
    python3 configure.py --bootstrap# 安裝(Linux/macOS 為例,Windows 直接使用生成的 ninja.exe)
    sudo cp ninja /usr/local/bin/

    3.Ninja 與構建系統配合:以 CMake 為例

    Ninja 本身不直接處理項目配置(如依賴、編譯選項),通常由 CMake、Meson 等工具生成?.ninja?構建文件,再通過 Ninja 執行構建。以下以最常用的 CMake 為例說明。

    1.生成 Ninja 構建文件

    在 CMake 項目中,通過?-G "Ninja"?指定生成 Ninja 格式的構建文件:

    # 創建構建目錄(推薦 out-of-source 構建,避免污染源碼)
    mkdir build && cd build# 生成 Ninja 構建文件(替代默認的 Makefile)
    cmake -G "Ninja" ..  # .. 指向源碼根目錄(含 CMakeLists.txt)

    執行后,build?目錄下會生成?build.ninja(主構建文件)、rules.ninja(編譯規則)等,后續通過 Ninja 構建。

    2.執行構建

    生成構建文件后,直接用?ninja?命令啟動構建:

    # 構建默認目標(如 all 目標)
    ninja# 構建指定目標(如生成可執行文件 myapp)
    ninja myapp# 清理構建產物
    ninja clean# 顯示詳細編譯命令(調試用)
    ninja -v

    4.加速構建的關鍵技巧

    Ninja 本身已足夠高效,但結合以下技巧可進一步提升構建速度,尤其適合大型項目。

    1.最大化并行編譯

    Ninja 默認根據 CPU 核心數自動并行執行任務(類似?make -j$(nproc)),但可手動指定更優的并行數(避免過多任務導致內存瓶頸):

    # 查看 CPU 核心數(Linux/macOS)
    nproc  # 輸出如 8(8 核)# 指定 8 個并行任務(根據核心數調整,通常等于或略大于核心數)
    ninja -j 8

    注意:并行數并非越大越好,若項目編譯需要大量內存(如鏈接大型二進制),過度并行可能導致內存不足,需根據實際硬件調整。

    2.配合編譯緩存(ccache/sccache)

    編譯緩存工具(如?ccache?或?sccache)可緩存編譯產物,重復編譯相同代碼時直接復用,大幅減少編譯時間。需在 CMake 中配置編譯器路徑為緩存工具:

    # 安裝 ccache(Linux 為例)
    sudo apt install ccache# 生成 Ninja 構建文件時,指定 C/C++ 編譯器為 ccache 包裝的 clang/gcc
    cmake -G "Ninja" \-DCMAKE_C_COMPILER=ccache \-DCMAKE_CXX_COMPILER=ccache \-DCMAKE_C_COMPILER_LAUNCHER=ccache \-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \..

    后續?ninja?構建時,ccache?會自動緩存?.o?目標文件,重復修改少量代碼時,編譯時間可減少 50% 以上。

    3.優化增量構建

    Ninja 對增量構建的優化是其核心優勢之一,但需注意:

    • 確保項目的?CMakeLists.txt?正確設置依賴(如?target_link_librariestarget_include_directories),避免不必要的文件被標記為 “需要重建”。
    • 避免在構建目錄中手動修改文件,防止 Ninja 的依賴跟蹤失效。

    4.使用?ninja -t?調試構建問題

    若構建異常(如重復編譯、依賴錯誤),可通過 Ninja 的調試命令分析:

    # 列出所有目標
    ninja -t targets# 查看目標依賴鏈(如 myapp 依賴哪些文件)
    ninja -t graph myapp | dot -Tpng -o myapp_deps.png  # 需要安裝 graphviz# 檢查哪些文件會觸發目標重建
    ninja -t dependents myapp.cpp

    5.結合 Clang 或 Mold 鏈接器

    鏈接階段(尤其大型項目)往往是構建瓶頸,可配合更快的鏈接器:

    • Clang 鏈接器(lld):比 GNU ld 更快,CMake 中指定?CMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld
    • Mold 鏈接器:速度遠超 lld,適合超大項目,配置?CMAKE_EXE_LINKER_FLAGS=-fuse-ld=mold

    配置方式:

    cmake -G "Ninja" \-DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" \-DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld" \..

    5.Ninja 與 Make 構建速度對比

    以之前的Fast-DDS為例,在麒麟V10桌面虛擬機化境下,對比相同配置下的構建時間:

    通信中間件 Fast DDS(一) :編譯、安裝和測試_fast dds 安裝-CSDN博客

    構建場景Make(命令make)Ninja(命令ninja)加速比例
    全量構建(首次)9分25秒3分44秒61.4%
    增量構建(改 1 文件)未測試未測試未知

    可見,Ninja 在構建中優勢很明顯,這對頻繁調試的開發場景至關重要。

    6.項目構建過程中遇到的問題

    1.在windows命令行構建報錯

    解決方法:

    在?Visual Studio 開發者命令提示符(而非普通 PowerShell)中運行 CMake,步驟:

    1) 開始菜單找到?“Developer Command Prompt for Visual Studio 2022”?并打開;

    2) 進入項目?build?目錄,執行:

    cmake -G "Ninja" ..

    (原理:普通終端未加載 MSVC 編譯器環境變量,開發提示符會自動配置?CL.exe?路徑。)

    2.檢查架構一致性(32 位 vs 64 位)

    你的編譯日志顯示當前使用的是?32 位編譯器Hostx86/x86/cl.exe),而?vcpkg?安裝的依賴(如?asio_x64-windows)是?64 位版本,可能存在架構不匹配:

    • 若?fastcdr?安裝的是 64 位版本,而編譯器是 32 位,會導致查找失敗。
    • 解決:使用?64 位 VS 開發者命令提示符(如 “x64 Native Tools Command Prompt for VS 2022”),并確保?fastcdr?是 64 位版本。

    7.總結

    Ninja 是提升項目構建效率的 “利器”,其核心價值在于快速啟動、高效并行和精準增量構建。通過以下步驟可充分發揮其優勢:

    1. 按系統需求安裝 Ninja(包管理器或二進制包最便捷);
    2. 用 CMake 生成 Ninja 構建文件(-G "Ninja");
    3. 結合?-j?調整并行數、ccache?緩存編譯產物、快速鏈接器(lld/mold)進一步加速;
    4. 用?ninja -t?命令調試構建依賴問題。

    對于需要頻繁迭代的大型項目,Ninja 可顯著減少構建等待時間,提升開發效率。

    相關鏈接

    • CMake 官網?CMake - Upgrade Your Software Build System
    • CMake 官方文檔:CMake Tutorial — CMake 4.1.0 Documentation
    • CMake 源碼:https://github.com/Kitware/CMake
    • CMake 源碼:https://gitlab.kitware.com/cmake/
    • 中文版基礎介紹:?CMake 入門實戰 | HaHack
    • wiki:?https://gitlab.kitware.com/cmake/community/-/wikis/Home
    • Modern CMake 簡體中文版:??Introduction · Modern CMake

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

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

    相關文章

    開發避坑指南(35):mybaits if標簽test條件判斷等號=解析異常解決方案

    異常信息 org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: The expression orderInfo.idList evaluated to a null value.報錯語句 <if test"orderInfo.queryFlag ! null and orderInfo.queryFlag sett…

    GitCode 疑難問題診療:全面指南與解決方案

    引言 在軟件開發的動態領域中&#xff0c;GitCode 作為一款強大的分布式版本控制系統&#xff0c;已然成為團隊協作與項目管理的基石。它賦予開發者高效管理代碼版本、輕松實現并行開發以及順暢協同合作的能力。然而&#xff0c;如同任何復雜的技術工具&#xff0c;在 GitCode…

    使用 JS 渲染頁面并導出為PDF 常見問題與修復

    本文直擊兩個最常見的導出痛點&#xff0c;并給出可直接落地的診斷 修復方案&#xff08;適用于 html2canvas jsPDF ECharts/自繪 canvas 場景&#xff09;。 問題清單 問題 A&#xff1a;導出后圖表模糊&#xff0c;線條與文字不清晰&#xff08;低分辨率&#xff09;。問題…

    【Java后端】【可直接落地的 Redis 分布式鎖實現】

    可直接落地的 Redis 分布式鎖實現&#xff1a;包含最小可用版、生產可用版&#xff08;帶 Lua 原子解鎖、續期“看門狗”、自旋等待、可重入&#xff09;、以及基于注解AOP 的無侵入用法&#xff0c;最后還給出 Redisson 方案對比與踩坑清單。一、設計目標與約束 獲取鎖&#x…

    數據結構 -- 鏈表--雙向鏈表的特點、操作函數

    雙向鏈表的操作函數DouLink.c#include "DouLink.h" #include <stdio.h> #include <stdlib.h> #include <string.h>/*** brief 創建一個空的雙向鏈表* * 動態分配雙向鏈表管理結構的內存&#xff0c;并初始化頭指針和節點計數* * return 成功返回指…

    Wireshark獲取數據傳輸的碼元速率

    一、Wireshark的物理層參數 Wireshark主界面可以看到數據發送時刻和長度&#xff1a; 這個時刻是Wireshark完整獲取數據包的時刻&#xff0c;實際上就是結束時刻。 需要知道的是&#xff1a; Wireshark工作在數據鏈路層及以上&#xff0c;它能解碼 以太網幀 / IP 包 / TCP…

    11.1.3 完善注冊登錄,實現文件上傳和展示

    1、完善注冊/登錄 1. 涉及的數據庫表單&#xff1a;user_info 2. 引用MySQL線程池&#xff0c;Redis線程池 3. 完善注冊功能 4. 完善登錄功能 2.1 涉及的數據庫表單&#xff1a;user_info 重新創建數據庫 #創建數據庫 DROP DATABASE IF EXISTS 0voice_tuchuang;CREATE D…

    【Linux文件系統】目錄結構

    有沒有剛進入Linux世界時&#xff0c;對著黑乎乎的終端&#xff0c;輸入一個 ls / 后&#xff0c;看著蹦出來的一堆名字 like bin, etc, usr&#xff0c;感覺一頭霧水&#xff0c;像是在看天書&#xff1f; 別擔心&#xff0c;你不是一個人。Linux的文件系統就像一個超級有條理…

    螺旋槽曲面方程的數學建模與偏導數求解

    螺旋槽曲面的數學描述 在鉆頭設計和機械加工領域,螺旋槽的幾何建模至關重要。螺旋槽通常由徑向截形繞軸做螺旋運動形成,其數學模型可通過參數方程和隱函數方程兩種方式描述。 設螺旋槽的徑向截形方程為: y=f(z)y = f(z)y=f(z) x=xcx = x_cx=xc? 其中 xcx_cxc? 為常數,…

    線性回歸:機器學習中的基石

    在機器學習的眾多算法中&#xff0c;線性回歸無疑是最基礎也是最常被提及的一種。它不僅在統計學中占有重要地位&#xff0c;而且在預測分析和數據建模中也發揮著關鍵作用。本文將深入探討線性回歸的基本概念、評估指標以及在實際問題中的應用&#xff0c;并通過一個模擬的氣象…

    編程刷題-資料分發1 圖論/DFS

    P2097 資料分發 1 題目描述 有一些電腦&#xff0c;一部分電腦有雙向數據線連接。 如果一個電腦得到數據&#xff0c;它可以傳送到的電腦都可以得到數據。 現在&#xff0c;你有這個數據&#xff0c;問你至少將其輸入幾臺電腦&#xff0c;才能使所有電腦得到數據。 輸入格式 第…

    RabbitMQ:延時消息(死信交換機、延遲消息插件)

    目錄一、死信交換機【不推薦】二、延遲消息插件【推薦】2.1 安裝插件【Linux】2.2 安裝插件【Windows】2.3 如何使用延時消息&#xff1a;生產者發送消息時指定一個時間&#xff0c;消費者不會立刻收到消息&#xff0c;而是在指定時間之后才收到消息。 延時任務&#xff1a;設置…

    動學學深度學習05-深度學習計算

    動學學深度學習pytorch 參考地址&#xff1a;https://zh.d2l.ai/ 文章目錄動學學深度學習pytorch1-第05章-深度學習計算1. 層&#xff08;Layer&#xff09;與塊&#xff08;Block&#xff09;1.1 什么是深度學習中的“層”&#xff1f;1.2 什么是“塊”&#xff08;Block&…

    智慧工廠煙霧檢測:全場景覆蓋與精準防控

    智慧工廠煙霧檢測&#xff1a;構建工業安全的智能防線&#xff08;所有圖片均為真實項目案例&#xff09;在工業4.0時代&#xff0c;智慧工廠通過物聯網、人工智能與大數據技術的深度融合&#xff0c;實現了生產流程的數字化與智能化。然而&#xff0c;工廠環境中的火災隱患始終…

    @JsonIgnoreProperties注解詳解

    JsonIgnoreProperties是 Jackson 庫中的一個重要注解&#xff0c;用于在 JSON 序列化&#xff08;對象轉 JSON&#xff09;和反序列化&#xff08;JSON 轉對象&#xff09;過程中??控制屬性的可見性??。它提供了更高級別的屬性忽略能力&#xff0c;特別適合處理復雜場景。一…

    紅酒數據集預處理實戰:缺失值處理的 5 種打開方式,從入門到進階一步到位

    在數據分析與建模流程中&#xff0c;缺失值處理是數據預處理階段的關鍵步驟&#xff0c;直接影響后續模型的準確性與穩定性。本文以紅酒數據集為研究對象&#xff0c;詳細介紹如何通過基礎統計方法&#xff08;均值、中位數、眾數&#xff09;、完整案例分析&#xff08;CCA&am…

    Node.js 開發 JavaScript SDK 包的完整指南(AI)

    一、核心概念SDK 包定義 專為特定服務/平臺封裝的工具庫&#xff0c;提供標準化 API 調用、錯誤處理、類型聲明等功能。示例&#xff1a;支付寶 SDK、AWS SDK、微信小程序 SDK。技術棧選擇 語言&#xff1a;JavaScript/TypeScript&#xff08;推薦 TS&#xff0c;便于類型提示&…

    Redis實戰-基于Session實現分布式登錄

    1.流程分析1.1發送短信驗證碼提交手機號的時候要進行校驗手機號&#xff0c;校驗成功才會去生成驗證碼&#xff0c;將驗證碼保存到session&#xff0c;發生他把這部分那。1.2短信驗證碼登錄/注冊如果提交手機號和驗證碼之后&#xff0c;校驗一致才進行根據手機號查詢用戶&#…

    瘋狂星期四文案網第47天運營日記

    網站運營第47天&#xff0c;點擊觀站&#xff1a; 瘋狂星期四 crazy-thursday.com 全網最全的瘋狂星期四文案網站 運營報告 今日訪問量 今日搜索引擎收錄情況 必應現在是邊收錄邊k頁面 百度快倒閉 網站優化點 完善工作流&#xff0c;全面實現文案自動化采集&#xff0c;se…

    Vue生命周期以及自定義鉤子和路由

    Vue生命周期常用的onMounted掛載后執行和onUnmounted卸載前以及onupdated更新后實際上用react對比就是useEffect&#xff0c;而且掛載順序也是子組件先于父組件然后往外的棧結構&#xff0c;先進后出。1.Vue的生命周期<template><h2>當前求和為{{ sum }}</h2>…