CMake基礎:CMakeLists.txt 文件結構和語法

目錄

1.CMakeLists.txt基本結構

2.核心語法規則

3.關鍵命令詳解

4.常用預定義變量

5.變量和緩存

6.變量作用域與傳遞

7.注意事項


1.CMakeLists.txt基本結構

????????CMakeLists.txt 是 CMake 構建系統的核心配置文件,采用命令式語法組織項目結構和編譯流程。主要用于定義項目的構建規則、依賴關系、編譯選項等。每個 CMake 項目通常都有一個或多個 CMakeLists.txt 文件。

????????一個完整的 CMakeLists.txt 通常包含以下部分:

# 1. CMake 最低版本要求
cmake_minimum_required(VERSION 3.10)# 2. 項目信息
project(MyProject VERSION 1.0.0 LANGUAGES CXX)# 3. 全局配置(可選)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)  # 生成 compile_commands.json# 4. 查找依賴(可選)
find_package(Threads REQUIRED)
find_package(Boost 1.70 COMPONENTS system REQUIRED)# 5. 添加子目錄(可選)
add_subdirectory(src)
add_subdirectory(tests)# 6. 定義目標(可執行文件或庫)
add_executable(myapp main.cpp)
add_library(mylib STATIC src/lib.cpp src/utils.cpp)# 7. 配置目標屬性
target_include_directories(mylib PUBLIC include)
target_link_libraries(myapp PRIVATE mylib Threads::Threads)
target_compile_definitions(myapp PRIVATE DEBUG_MODE=1)# 8. 安裝規則(可選)
install(TARGETS myapp DESTINATION bin)
install(FILES include/mylib.h DESTINATION include)# 9. 測試配置(可選)
enable_testing()
add_test(NAME MyTest COMMAND myapp_test)

2.核心語法規則

1.命令格式

command(arg1 arg2 ...)  # 命令名不區分大小寫,但參數區分
  • 命令和參數用空格或括號分隔。
  • 參數可用雙引號括起(如包含空格時):set(NAME "My Project")

2.變量引用

set(SOURCE_FILES main.cpp src/foo.cpp)
add_executable(myapp ${SOURCE_FILES})  # 使用 ${} 引用變量
  • 變量作用域:當前目錄及子目錄,可用?PARENT_SCOPE?提升作用域。

3.注釋

# 單行注釋

4.條件語句

if(WIN32)set(PLATFORM_LIBS ws2_32)
else()set(PLATFORM_LIBS pthread)
endif()target_link_libraries(myapp PRIVATE ${PLATFORM_LIBS})
  • 條件表達式:WIN32APPLEUNIXDEFINED varNOTANDOR?等。

5.循環

foreach(file IN LISTS source_files)message("Processing file: ${file}")
endforeach()

6.函數和宏

# 函數(有獨立作用域)
function(print_info name)message("Project name: ${name}")
endfunction()# 宏(直接替換)
macro(add_example name)add_executable(${name} examples/${name}.cpp)
endmacro()print_info(${PROJECT_NAME})
add_example(example1)

3.關鍵命令詳解

1.項目設置

  • cmake_minimum_required(VERSION <version>):指定所需的最低 CMake 版本。
  • project(<name> [VERSION <ver>] [LANGUAGES <langs>]):定義項目名稱、版本和支持的語言。

示例如下:

#1
cmake_minimum_required(VERSION 3.10)
#2
project(MyProject CXX)

2.目標定義

  • add_executable(<name> <sources>):創建可執行文件。
  • add_library(<name> [STATIC|SHARED|MODULE] <sources>):創建庫(靜態 / 共享 / 模塊)。
  • add_custom_target(<name> [COMMAND <cmd>] [DEPENDS <deps>]):創建自定義目標(如構建腳本)。

示例代碼:

#1
add_executable(MyExecutable main.cpp other_file.cpp)
#2
add_library(MyLibrary STATIC library.cpp)
#3
add_library(MyLibrary SHARED library.cpp)

3.依賴管理

  • find_package(<package> [REQUIRED] [VERSION <ver>]):查找并導入外部包。
  • add_subdirectory(<dir>):添加子目錄中的 CMakeLists.txt。
  • target_link_libraries(<target> <PRIVATE|PUBLIC|INTERFACE> <libs>):鏈接庫到目標。
  • include_directories(<dirs>...)

示例代碼:

#1
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Network)
find_package(Qt${QT_VERSION_MAJOR} CONFIG REQUIRED COMPONENTS Widgets Network)#2
add_subdirectory(tutorial)#3
target_link_libraries(QSimpleUpdater PUBLIC Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Widgets PRIVATE Qt${QT_VERSION_MAJOR}::Network)#4
include_directories(${PROJECT_SOURCE_DIR}/include)

4.編譯選項

  • target_include_directories(<target> <PRIVATE|PUBLIC|INTERFACE> <dirs>):添加頭文件搜索路徑。
  • target_compile_definitions(<target> <PRIVATE|PUBLIC|INTERFACE> <defs>):添加編譯定義(如?-DDEBUG)。
  • target_compile_options(<target> <PRIVATE|PUBLIC|INTERFACE> <options>):添加編譯選項(如?-Wall)。

示例代碼:

#1
target_include_directories(QSimpleUpdater PUBLIC include)

5.安裝規則

install(TARGETS target1 [target2 ...][RUNTIME DESTINATION dir][LIBRARY DESTINATION dir][ARCHIVE DESTINATION dir][INCLUDES DESTINATION [dir ...]][PRIVATE_HEADER DESTINATION dir][PUBLIC_HEADER DESTINATION dir])

示例代碼:

#1
install(TARGETS <targets>RUNTIME DESTINATION binLIBRARY DESTINATION libARCHIVE DESTINATION lib/static)install(FILES <files> DESTINATION include)
install(DIRECTORY <dir> DESTINATION share)#2
install(TARGETS MyExecutable RUNTIME DESTINATION bin)

6.自定義命令 (add_custom_command 命令)

add_custom_command(TARGET targetPRE_BUILD | PRE_LINK | POST_BUILDCOMMAND command1 [ARGS] [WORKING_DIRECTORY dir][COMMAND command2 [ARGS]][DEPENDS [depend1 [depend2 ...]]][COMMENT comment][VERBATIM]
)

示例代碼:

add_custom_command(TARGET MyExecutable POST_BUILDCOMMAND ${CMAKE_COMMAND} -E echo "Build completed."
)

7.測試配置

enable_testing()
add_test(NAME <test_name> COMMAND <executable> <args>)
add_test(NAME <test_name> WORKING_DIRECTORY <dir> COMMAND <cmd>)

4.常用預定義變量

1. 項目信息

變量名描述示例值
PROJECT_NAME當前項目名稱MyProject
PROJECT_VERSION項目版本(通過?project()?設置)1.2.3
PROJECT_SOURCE_DIR當前項目的源目錄/path/to/myproject
PROJECT_BINARY_DIR當前項目的構建目錄/path/to/myproject/build

2.路徑相關

變量名描述示例值
CMAKE_SOURCE_DIR頂級 CMakeLists.txt 所在目錄/path/to/myproject
CMAKE_BINARY_DIR頂級構建目錄/path/to/myproject/build
CMAKE_CURRENT_SOURCE_DIR當前 CMakeLists.txt 所在目錄/path/to/myproject/src
CMAKE_CURRENT_BINARY_DIR當前構建目錄/path/to/myproject/build/src
CMAKE_INSTALL_PREFIX安裝路徑前綴/usr/local(默認)
LIBRARY_OUTPUT_PATH庫文件輸出的默認路徑庫路徑不設置的話,默認放在BINARY_DIR下,即構建時執行cmake命令的目錄下

3.構建配置

變量名描述示例值
CMAKE_BUILD_TYPE構建類型Debug,?Release,?RelWithDebInfo
CMAKE_C_COMPILERC 編譯器路徑/usr/bin/gcc
CMAKE_CXX_COMPILERC++ 編譯器路徑/usr/bin/g++
CMAKE_CXX_STANDARDC++ 標準版本11,?14,?17,?20
CMAKE_GENERATOR當前使用的生成器Unix Makefiles,?Ninja
CMAKE_C_STANDARD_REQUIRED
  • ON:若編譯器不支持指定的 C 標準,CMake 會終止配置并報錯。
  • OFF(默認):若編譯器不支持,CMake 會嘗試降級到兼容版本(可能導致意外行為)。
set(CMAKE_C_STANDARD 11)             # 指定 C 語言標準為 C11
set(CMAKE_C_STANDARD_REQUIRED ON)    # 強制要求此標準
CMAKE_CXX_STANDARD_REQUIRED
  • ON:若編譯器不支持指定的 C++ 標準,CMake 會終止配置并報錯。
  • OFF(默認):若編譯器不支持,CMake 會嘗試降級到兼容版本(可能導致意外行為)。
set(CMAKE_CXX_STANDARD 20) # 指定 C++ 標準為 C++20 set(CMAKE_CXX_STANDARD_REQUIRED ON) # 強制要求此標準
CMAKE_DEBUG_POSTFIX 
設置調試版本后綴
set(CMAKE_DEBUG_POSTFIX d)

4.系統信息

變量名描述示例值
CMAKE_SYSTEM_NAME操作系統名稱Linux,?Windows,?Darwin
CMAKE_SYSTEM_VERSION系統版本10.0(Windows)
CMAKE_HOST_SYSTEM_PROCESSOR處理器架構x86_64,?arm64

5.目標屬性(Target Properties)

通過?set_target_properties?或?get_target_property?操作,影響特定目標的行為。

常用屬性

屬性名描述設置命令
OUTPUT_NAME輸出文件名set_target_properties(myapp PROPERTIES OUTPUT_NAME "custom_name")
VERSION庫版本號set_target_properties(mylib PROPERTIES VERSION "1.2.3")
SOVERSION共享庫 API 版本set_target_properties(mylib PROPERTIES SOVERSION "1")
COMPILE_DEFINITIONS編譯定義(如?-DDEBUGtarget_compile_definitions(myapp PRIVATE DEBUG)
INCLUDE_DIRECTORIES頭文件搜索路徑target_include_directories(myapp PUBLIC include)
LINK_LIBRARIES鏈接庫target_link_libraries(myapp PRIVATE pthread)
POSITION_INDEPENDENT_CODE是否生成位置無關代碼(共享庫必需)set_target_properties(mylib PROPERTIES POSITION_INDEPENDENT_CODE ON)

5.變量和緩存

CMake 使用變量來存儲和傳遞信息,這些變量可以在 CMakeLists.txt 文件中定義和使用。

變量可以分為普通變量和緩存變量。

1.變量定義與使用

定義變量:

set(MY_VAR "Hello World")

使用變量:

message(STATUS "Variable MY_VAR is ${MY_VAR}")

2.緩存變量

緩存變量存儲在 CMake 的緩存文件中,用戶可以在 CMake 配置時修改這些值。緩存變量通常用于用戶輸入的設置,用戶可通過命令行(-D)或 CMake GUI 修改,例如編譯選項和路徑。

定義緩存變量:

set(MY_CACHE_VAR "DefaultValue" CACHE STRING "A cache variable")set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries")
set(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "Installation directory")

使用緩存變量:

message(STATUS "Cache variable MY_CACHE_VAR is ${MY_CACHE_VAR}")

3.環境變量

  • 訪問方式$ENV{VARIABLE_NAME}
  • 修改方式set(ENV{VARIABLE_NAME} value)
message("PATH: $ENV{PATH}")  # 讀取環境變量
set(ENV{MY_LIB_PATH} "${CMAKE_SOURCE_DIR}/libs")  # 設置環境變量

6.變量作用域與傳遞

  1. 默認作用域:當前目錄及子目錄。
  2. 提升作用域PARENT_SCOPE?參數。
# 在子目錄 CMakeLists.txt 中
set(CHILD_VAR "value" PARENT_SCOPE)  # 將變量傳遞到父目錄

7.注意事項

1.模塊化結構

project/
├── CMakeLists.txt       # 頂級配置
├── src/                 # 源代碼
│   └── CMakeLists.txt
├── include/             # 公共頭文件
├── tests/               # 測試代碼
│   └── CMakeLists.txt
├── examples/            # 示例
└── CMakeModules/        # 自定義 CMake 模塊

2.使用現代 CMake 模式

  • 優先使用?target_*?命令(如?target_include_directories)而非全局設置。
  • 通過?PUBLIC/PRIVATE/INTERFACE?明確依賴范圍。

3.避免硬編碼路徑

# 不好的做法
include_directories("/usr/local/include/mylib")# 好的做法
find_package(MyLib REQUIRED)
target_link_libraries(myapp PRIVATE MyLib::MyLib)

4.添加版本控制

project(MyProject VERSION 1.2.3)
configure_file(version.h.in version.h)
target_include_directories(myapp PRIVATE ${CMAKE_BINARY_DIR})

掌握 CMakeLists.txt 的結構和語法是高效管理 C/C++ 項目的關鍵,合理組織文件可大幅提升項目的可維護性和跨平臺兼容性。

相關鏈接

  • CMake 官網?CMake - Upgrade Your Software Build System
  • CMake 官方文檔:CMake Tutorial — CMake 4.0.2 Documentation
  • CMake 源碼:https://github.com/Kitware/CMake
  • CMake 源碼:Sign in · GitLab

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

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

相關文章

戰略-2.1 -戰略分析(PEST/五力模型/成功關鍵因素)

戰略分析路徑&#xff0c;先宏觀&#xff08;PEST&#xff09;、再產業&#xff08;產品生命周期、五力模型、成功關鍵因素&#xff09;、再競爭對手分析、最后企業內部分析。 本文介紹&#xff1a;PEST、產品生命周期、五力模型、成功關鍵因素、產業內的戰略群組 一、宏觀環境…

深入理解設計模式:工廠模式、單例模式

深入理解設計模式&#xff1a;工廠模式、單例模式 設計模式是軟件開發中解決常見問題的可復用方案。本文將詳細介紹兩種種重要的創建型設計模式&#xff1a;工廠模式、單例模式&#xff0c;并提供Java實現示例。 一、工廠模式 工廠模式是一種創建對象的設計模式&#xff0c;…

Jenkins 2.426.2配置“構建歷史的顯示名稱,加上包名等信息“

Jenkins 2.426.2配置“構建歷史的顯示名稱,加上包名等信息" 需求:想要在構建歷史中展示,本次運行的是哪個版本或哪個包 操作步驟: 1、先安裝插件Build Name and Description Setter 2、Set Build Name 3、構建歷史處查看展示 插件特性說明 安裝依賴:需手動安裝 Build …

為何在VMware中清理CentOS虛擬機后,本地磁盤空間未減少的問題解決

文章目錄 前言原因:虛擬機磁盤&#xff0c;到底是咋回事&#xff1f;為啥空間沒變小&#xff1f; 解決方案 前言 在使用VMware運行CentOS虛擬機時&#xff0c;你是否曾遇到過這樣的情況&#xff1a;明明在虛擬機內刪除了大量文件&#xff0c;rm -rf 后發現并沒什么用&#xff…

Development靶機通關筆記

一、主機發現 arp-scan -l靶機ip為192.168.55.152 二、端口掃描、目錄枚舉、漏洞掃描、指紋識別 2.1端口掃描 nmap --min-rate 10000 -p- 192.168.55.152發現靶機沒有開放80端口&#xff0c;開放的是8080端口 UDP端口掃描 nmap -sU --min-rate 10000 -p- 192.168.55.152靶…

自然語言處理核心技術:詞向量(Word Embedding)解析

自然語言處理核心技術&#xff1a;詞向量&#xff08;Word Embedding&#xff09;全面解析 在自然語言處理&#xff08;NLP&#xff09;領域&#xff0c;如何讓計算機理解人類語言的語義一直是核心挑戰。詞向量&#xff08;Word Vector&#xff09;&#xff0c;又稱詞嵌入&…

【Matlab】雷達圖/蛛網圖

文章目錄 一、簡介二、安裝三、示例四、所有參數說明 一、簡介 雷達圖&#xff08;Radar Chart&#xff09;又稱蛛網圖&#xff08;Spider Chart&#xff09;是一種常見的多維數據可視化手段&#xff0c;能夠直觀地對比多個指標并揭示其整體分布特征。 雷達圖以中心點為原點&…

Vue3實現輪播表(表格滾動)

在這之前,寫過一篇Vue2實現該效果的博文:vue-seamless-scroll(一個簡單的基于vue.js的無縫滾動) 有興趣也可以去看下,這篇是用vue3實現,其實很簡單,目的是方便后面用到直接復制既可以了。 安裝: <

安卓開發用到的設計模式(1)創建型模式

安卓開發用到的設計模式&#xff08;1&#xff09;創建型模式 文章目錄 安卓開發用到的設計模式&#xff08;1&#xff09;創建型模式1. 單例模式&#xff08;Singleton Pattern&#xff09;2. 工廠模式&#xff08;Factory Pattern&#xff09;3. 抽象工廠模式&#xff08;Abs…

后端開發概念

1. 后端開發概念解析 1.1. 什么是服務器&#xff0c;后端服務 1.1.1. 服務器 服務器是一種提供服務的計算機系統&#xff0c;它可以接收、處理和響應來自其他計算機系統&#xff08;客戶端&#xff09;的請求。服務器主要用于存儲、處理和傳輸數據&#xff0c;以便客戶端可以…

Spring AI 源碼解析:Tool Calling鏈路調用流程及示例

Tool工具允許模型與一組API或工具進行交互&#xff0c;增強模型功能&#xff0c;主要用于&#xff1a; 信息檢索&#xff1a;從外部數據源檢索信息&#xff0c;如數據庫、Web服務、文件系統或Web搜索引擎等 采取行動&#xff1a;可用于在軟件系統中執行特定操作&#xff0c;如…

Spyglass:跨時鐘域同步(長延遲信號)

相關閱讀 Spyglasshttps://blog.csdn.net/weixin_45791458/category_12828934.html?spm1001.2014.3001.5482 簡介 長延遲信號方案用于控制或數據信號跨時鐘域同步&#xff0c;該方案將使用quasi_static約束的跨時鐘域信號視為已同步&#xff0c;如圖1所示。 // test.sgdc q…

Linux云計算訓練營筆記day13【CentOS 7 find、vim、vimdiff、ping、wget、curl、RPM、YUM】

Linux云計算訓練營筆記day13[CentOS 7 find、vim、vimdiff、ping、wget、curl、RPM、YUM]] 目錄 Linux云計算訓練營筆記day13[CentOS 7 find、vim、vimdiff、ping、wget、curl、RPM、YUM]]1.find練習2.vim高級使用2.1 命令模式:2.2 插入模式:2.3 末行模式: 3. vimdiff4. ping5.…

網絡流量分析工具ntopng的安裝與基本使用

網絡流量分析工具ntopng的安裝與基本使用 一、ntopng基本介紹1.1 ntopng簡介1.2 主要特點1.3 使用場景 二、本地環境介紹2.1 本地環境規劃2.2 本次實踐介紹 三、安裝ntopng工具3.1 官網地址3.2 配置軟件源3.3 添加軟件源3.4 安裝ntopng 四、ntopng的基本配置4.1 修改配置文件4.…

數據的獲取與讀取篇---常見的數據格式JSON

文件格式 假如你有一份想分析的數據文件,獲得文件后下一步就是用代碼讀取它。不同的文件格式有不同的讀取方法。所以讀取前了解文件格式也很重要。你可能見過非常多的文件格式,例如TXT、MP3、PDF、JPEG等等。 一般可以通過文件的后綴來分辨文件的格式,例如TXT格式,一般保存…

人工智能發展

探秘人工智能領域的熱門編程語言與關鍵知識 在當今科技飛速發展的時代&#xff0c;人工智能已滲透到生活的各個角落&#xff0c;從智能語音助手到精準的推薦系統&#xff0c;從自動駕駛汽車到醫療影像診斷&#xff0c;人工智能正以前所未有的速度改變著世界。而在這背后&#x…

超全GPT-4o 風格提示詞案例,持續更新中,附使用方式

本文匯集了各類4o風格提示詞的精選案例&#xff0c;從基礎指令到復雜任務&#xff0c;從創意寫作到專業領域&#xff0c;為您提供全方位的參考和靈感。我們將持續更新這份案例集&#xff0c;確保您始終能夠獲取最新、最有效的提示詞技巧。 讓我們一起探索如何通過精心設計的提…

Vue3響應式數據: 深入分析Ref與Reactive

Vue3響應式數據: 深入分析Ref與Reactive 介紹 作為一個流行的前端框架&#xff0c;其響應式數據系統是其核心特性之一。在Vue3中&#xff0c;我們可以使用Ref和Reactive兩種方式來創建響應式數據。本文將深入分析Ref與Reactive&#xff0c;幫助讀者更好地理解Vue3的響應式數據系…

云計算,大數據,人工智能

1. 云計算&#xff1a;彈性資源與分布式計算 案例&#xff1a;基于AWS EC2的動態資源擴展 場景&#xff1a;電商網站在“雙十一”期間流量激增&#xff0c;需要臨時擴容服務器資源。 代碼&#xff1a;使用AWS Boto3庫動態啟動EC2實例 import boto3# 創建EC2客戶端 ec2 boto…

Linux(7)——進程(概念篇)

一、基本概念 書本上的概念&#xff1a;程序的一個執行實例&#xff0c;正在執行的程序等 基于內核的觀點&#xff1a;擔當分配系統資源(CPU時間&#xff0c;內存)的實體。 我們知道&#xff0c;我們在寫代碼的時候&#xff0c;你的代碼進行編譯鏈接后生成可執行文件&#xff…