亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

CMake自動(dòng)管理C/C++項(xiàng)目的實(shí)現(xiàn)

 更新時(shí)間:2025年02月08日 09:03:15   作者:Dolphin_Home  
CMake是一個(gè)強(qiáng)大的構(gòu)建系統(tǒng),用于跨平臺(tái)管理C/C++項(xiàng)目的編譯過程,本文主要介紹了CMake自動(dòng)管理C/C++項(xiàng)目的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下

1. 介紹

CMake 是一個(gè)強(qiáng)大的構(gòu)建系統(tǒng),可用于跨平臺(tái)管理 C/C++ 項(xiàng)目的編譯過程。本 CMakeLists.txt 文件提供了一種自動(dòng)化的方式來管理 C/C++ 項(xiàng)目,包括創(chuàng)建代碼目錄、自動(dòng)編譯所有源文件、管理輸出文件等。

2. CMake 最低版本要求 & 項(xiàng)目信息

cmake_minimum_required(VERSION 3.14)
project(TestDemo C CXX)

這段代碼確保 CMake 版本不低于 3.14,并定義項(xiàng)目名稱 TestDemo,支持 C 和 C++ 語言。

3. 主要功能

該 CMakeLists.txt 具備以下功能:

  • 自動(dòng)創(chuàng)建 src 目錄,存放源代碼文件;
  • 自動(dòng)遍歷 src 目錄,編譯其中的所有 .c 和 .cpp 文件;
  • 設(shè)定編譯輸出路徑,避免污染項(xiàng)目根目錄:
    • .runtime/ 目錄存放可執(zhí)行文件;
    • .library/ 目錄存放靜態(tài)/動(dòng)態(tài)庫;
    • .archive/ 目錄存放編譯中間文件;
  • 支持多個(gè) main() 函數(shù),可以直接運(yùn)行單個(gè)源文件。

4. C/C++ 語言標(biāo)準(zhǔn)設(shè)定

set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 17)

此處指定 C 語言標(biāo)準(zhǔn)為 C99,C++ 語言標(biāo)準(zhǔn)為 C++17。

5. 編譯輸出目錄設(shè)定

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/.archive)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/.library)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/.runtime)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/.runtime)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/.library)

這些配置確保編譯后的文件不會(huì)污染項(xiàng)目根目錄。

6. 自動(dòng)創(chuàng)建 src 目錄

set(SRC_DIR ${PROJECT_SOURCE_DIR}/src)
if (NOT EXISTS ${SRC_DIR})
    file(MAKE_DIRECTORY ${SRC_DIR})
endif ()
message(STATUS "src目錄: ${SRC_DIR}")

若 src 目錄不存在,則自動(dòng)創(chuàng)建,并在 CMake 輸出日志中打印 src 目錄路徑。

7. 頭文件搜索路徑

include_directories(${SRC_DIR})

這行代碼告訴編譯器在 src 目錄中查找頭文件。

8. 自動(dòng)遍歷 src 目錄下的 C/C++ 文件

file(GLOB_RECURSE SOURCE_FILES "${SRC_DIR}/*.c" "${SRC_DIR}/*.cpp")

使用 file(GLOB_RECURSE ...) 指令遞歸查找 src 目錄下的所有 .c 和 .cpp 文件。

9. 生成唯一目標(biāo)名并添加可執(zhí)行文件

foreach (SOURCE_FILE ${SOURCE_FILES})
    get_filename_component(FILE_NAME ${SOURCE_FILE} NAME)
    string(REGEX REPLACE "^${SRC_DIR}[\\/]" "" RELATIVE_PATH ${SOURCE_FILE})
    string(REGEX REPLACE "[\\/]" "." TARGET_NAME ${RELATIVE_PATH})
    add_executable(${TARGET_NAME} ${SOURCE_FILE})
    message(STATUS "[Compile] ${SOURCE_FILE} --> ${TARGET_NAME}")
endforeach ()
  • 獲取文件名
    get_filename_component(FILE_NAME ${SOURCE_FILE} NAME)
    
  • 計(jì)算相對(duì)路徑(去掉 src/ 部分),并將 / 替換為 .,仿照 Java 包命名格式。
  • 添加可執(zhí)行文件,確保每個(gè) C/C++ 文件都能獨(dú)立編譯。

10. 編譯警告設(shè)置

if (MSVC)
    add_compile_options(/W4)
else ()
    add_compile_options(-Wall -Wextra -Wpedantic)
endif ()
  • Windows(MSVC):開啟最高級(jí)別 /W4 警告。
  • Linux/macOS(GCC/Clang):啟用 -Wall -Wextra -Wpedantic,增強(qiáng)代碼質(zhì)量。

11. CMake 關(guān)鍵指令說明

11.1 獲取文件名組件

get_filename_component(變量名 文件路徑 組件類型)

示例:

get_filename_component(FILE_NAME "D:/test/hello.txt" NAME_WE)

11.2 遞歸掃描目錄下的 C/C++ 文件

file(GLOB_RECURSE 變量名 "路徑/*.c" "路徑/*.cpp")

示例:

file(GLOB_RECURSE SOURCE_FILES "src/*.c" "src/*.cpp")

11.3 正則替換字符串

string(REGEX REPLACE "正則表達(dá)式" "替換字符串" 變量 輸入變量)

示例:

string(REGEX REPLACE "\\/" "." TARGET_NAME "src/com/example/Main.cpp")

11.4 數(shù)學(xué)運(yùn)算

math(EXPR 變量 "數(shù)學(xué)表達(dá)式")

示例:

math(EXPR RESULT "5 * 5")

11.5 編譯可執(zhí)行文件

add_executable(可執(zhí)行文件 源文件)

示例:

add_executable(my_program main.cpp)

11.6 目標(biāo)鏈接庫

target_link_libraries(可執(zhí)行文件 PRIVATE 庫名1 庫名2)

示例:

target_link_libraries(my_program PRIVATE jsoncpp_lib jsoncpp_object)

11.7 日志輸出

message(STATUS "日志信息")

示例:

message(STATUS "編譯目錄: ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")

12. 結(jié)論

這個(gè) CMakeLists.txt 通過自動(dòng)化管理 C/C++ 源文件、輸出目錄和編譯過程,使項(xiàng)目更加結(jié)構(gòu)化。它可以讓開發(fā)者專注于編寫代碼,而無需手動(dòng)管理每個(gè)可執(zhí)行文件的構(gòu)建。

13. 我常用的CMakeLists.txt配置

# 設(shè)置 CMake 最小版本 & 項(xiàng)目名稱, 編程語言C、C++
cmake_minimum_required(VERSION 3.14)
project(TestDemo C CXX)

# >------------------------------- CMake 功能說明 -------------------------------
# 本 CMakeLists.txt 具備以下功能:
# 1. 重新加載 CMake 項(xiàng)目時(shí),自動(dòng)創(chuàng)建 src 目錄(存放代碼文件)。
# 2. 自動(dòng)遍歷 src 目錄下的所有 .c 和 .cpp 文件,并生成獨(dú)立的可執(zhí)行文件。
# 3. 設(shè)定編譯輸出路徑,避免污染項(xiàng)目根目錄:
#    - 可執(zhí)行文件存放于 `.runtime/` 目錄。(即編譯結(jié)果)
#    - 靜態(tài)/動(dòng)態(tài)庫存放于 `.library/` 目錄。
#    - 編譯時(shí)中間文件存放于 `.archive/` 目錄。
# 4. 允許多個(gè) main() 函數(shù)共存,可直接運(yùn)行單個(gè)文件。
# >------------------------------- 使用說明 -------------------------------
# 使用此CMakeList時(shí),若要新建C/C++語言文件,請(qǐng)按照以下步驟:
# 1. 右鍵src目錄(如果沒有src目錄,請(qǐng)先創(chuàng)建) ——> 新建 ——> C/C++源文件
# 2. 在彈出的對(duì)話框中,輸入文件名(僅允許英文小寫及下劃線,不要出現(xiàn)空格),
#    后綴為 ".c(C語言文件)"或".cpp(C++文件)",切記不要勾選“添加到目標(biāo)”,點(diǎn)擊確定。
# 3. 點(diǎn)擊 左上角橫線 ——> 文件 ——> 重新加載CMake項(xiàng)目。
# 注:未重載前,進(jìn)入文件可能會(huì)有“不屬于任何項(xiàng)目目標(biāo)”的警告,重載后即會(huì)消失。
#    若此警告未消失,請(qǐng)檢查文件是否在src目錄下,以及文件名是否符合規(guī)范。
# >------------------------------- 運(yùn)行說明 -------------------------------
# 使用此CMakeList時(shí),若運(yùn)行 main() 函數(shù)代碼,請(qǐng)直接點(diǎn)擊函數(shù)前的綠色三角形按鈕。
# 右上角的運(yùn)行按鈕會(huì)自動(dòng)運(yùn)行最近一次運(yùn)行的程序,因此可能不是你想要的結(jié)果。
# >------------------------------- 注意事項(xiàng) -------------------------------
# 可執(zhí)行文件名,模仿Java包名 + 文件名 格式
# 例如:
#      文件路徑 src/com/example/testdemo/Main.cpp
#      可執(zhí)行文件名 com.example.testdemo.Main.cpp
# ------------------------------------------------------------------------

# 按照書本要求設(shè)定C語言和C++版本
set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 17)

# 定義輸出目錄,避免污染根目錄
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/.archive)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/.library)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/.runtime)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/.runtime)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/.library)

# 自動(dòng)創(chuàng)建存放代碼文件夾 src (重新加載CMake項(xiàng)目后,會(huì)自動(dòng)創(chuàng)建)
set(SRC_DIR ${PROJECT_SOURCE_DIR}/src)
if (NOT EXISTS ${SRC_DIR})
    file(MAKE_DIRECTORY ${SRC_DIR})
endif ()
message(STATUS "src目錄: ${SRC_DIR}")

# 設(shè)定頭文件搜索路徑
include_directories(${SRC_DIR})

# 遍歷 src 目錄下所有 C/C++ 文件并自動(dòng)添加
file(GLOB_RECURSE SOURCE_FILES "${SRC_DIR}/*.c" "${SRC_DIR}/*.cpp")

foreach (SOURCE_FILE ${SOURCE_FILES}) # 遍歷所有發(fā)現(xiàn)的文件
    # 生成唯一的目標(biāo)名(避免重名問題)
    # get_filename_component(FILE_NAME ${SOURCE_FILE} NAME_WE) # 獲取文件名(去掉擴(kuò)展名)【注意: 這樣子 C、C++ 文件在同一個(gè)目錄, 并且文件名相同時(shí),會(huì)導(dǎo)致沖突】
    get_filename_component(FILE_NAME ${SOURCE_FILE} NAME) # 獲取文件名
    # 計(jì)算相對(duì)路徑(去掉 src/ 部分),并且將`/`替換成`.` 模仿成Java的包名,方便后續(xù)添加到編譯命令中
    string(REGEX REPLACE "^${SRC_DIR}[\\/]" "" RELATIVE_PATH ${SOURCE_FILE})
    string(REGEX REPLACE "[\\/]" "." TARGET_NAME ${RELATIVE_PATH})  # 將`/`替換成`.` 模仿成Java的包名,避免重名問題

    # 添加可執(zhí)行文件
    add_executable(${TARGET_NAME} ${SOURCE_FILE})
    message(STATUS "[Compile] ${SOURCE_FILE} --> ${TARGET_NAME}")
endforeach () # 遍歷結(jié)束

# -------------------------- CMake 關(guān)鍵指令說明 --------------------------
# 1. 獲取文件名組件:
#    get_filename_component(變量名 文件路徑 組件類型)
#    例如: 獲取文件名(無擴(kuò)展名)
#    get_filename_component(FILE_NAME "D:/test/hello.txt" NAME_WE)
#
# 2. 遞歸掃描指定目錄下的所有 C/C++ 文件:
#    file(GLOB_RECURSE 保存結(jié)果的變量名 "路徑/*.c" "路徑/*.cpp")
#    例如: 掃描 src 目錄下的所有 C 和 C++ 文件
#    file(GLOB_RECURSE SOURCE_FILES "D:/test1/*.c" "D:/test2/*.cpp")
#
# 3. 字符串處理:
#    - 正則表達(dá)式替換:
#      string(REGEX REPLACE "正則表達(dá)式" "替換字符串" 存儲(chǔ)結(jié)果變量 輸入變量)
#      例如: 將路徑中的 "/" 替換為 "."
#      string(REGEX REPLACE "/" "." TARGET_NAME "D:/test/hello.txt")
#
#    - 計(jì)算字符串長度:
#      string(LENGTH 字符串變量 存儲(chǔ)結(jié)果變量)
#
#    - 字符串截取:
#      string(SUBSTRING 字符串變量 起始下標(biāo) 截取元素個(gè)數(shù) 存儲(chǔ)結(jié)果變量)
#      例如: 截取字符串的前 5 個(gè)字符
#      string(SUBSTRING "hello world" 0 5 SUB_STR)
#
# 4. 數(shù)學(xué)運(yùn)算:
#    math(EXPR 存儲(chǔ)結(jié)果變量 "數(shù)學(xué)表達(dá)式")
#    例如: 計(jì)算一個(gè)數(shù)值的平方
#    math(EXPR RESULT "5 * 5")
#
# 5. 編譯可執(zhí)行文件:
#    add_executable(可執(zhí)行文件名稱 源碼文件)
#    例如: 生成一個(gè)名為 my_program 的可執(zhí)行文件
#    add_executable(my_program main.cpp)
#
# 6. 目標(biāo)鏈接庫:
#    target_link_libraries(可執(zhí)行文件名稱 PRIVATE 庫名1 庫名2)
#    例如: 連接 jsoncpp 庫
#    target_link_libraries(my_program PRIVATE jsoncpp_lib jsoncpp_object)
#
# 7. 日志輸出:
#    message(STATUS "日志信息")
#    例如: 輸出 CMake 變量值
#    message(STATUS "編譯目錄: ${OUTPUT_DIR_RUNTIME}")
# ----------------------------------------------------------------------

# *********************************************************************************


# 設(shè)置編譯選項(xiàng)(開啟警告)
if (MSVC)
    add_compile_options(/W4)
else ()
    add_compile_options(-Wall -Wextra -Wpedantic)
endif ()

效果圖

在這里插入圖片描述

到此這篇關(guān)于CMake自動(dòng)管理C/C++項(xiàng)目的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)CMake自動(dòng)管理C/C++內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • C++數(shù)據(jù)封裝以及定義結(jié)構(gòu)的詳細(xì)講解

    C++數(shù)據(jù)封裝以及定義結(jié)構(gòu)的詳細(xì)講解

    這篇文章主要詳細(xì)講解了C++數(shù)據(jù)封裝以及定義結(jié)構(gòu),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • C++實(shí)現(xiàn)管理系統(tǒng)的示例代碼

    C++實(shí)現(xiàn)管理系統(tǒng)的示例代碼

    這篇文章主要介紹了C++實(shí)現(xiàn)管理系統(tǒng)的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • 詳細(xì)了解C語言二叉樹的建立與遍歷

    詳細(xì)了解C語言二叉樹的建立與遍歷

    這篇文章主要介紹了C中二叉樹的建立和各種遍歷實(shí)例代碼,涉及樹節(jié)點(diǎn)的定義,后序遍歷,層序遍歷,深度優(yōu)先和廣度優(yōu)先等相關(guān)內(nèi)容,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07
  • C語言與C++項(xiàng)目實(shí)現(xiàn)相互調(diào)用

    C語言與C++項(xiàng)目實(shí)現(xiàn)相互調(diào)用

    extern?“c”的作用可以實(shí)現(xiàn)c語言和c++相互調(diào)用,本文就詳細(xì)的介紹一下C語言與C++項(xiàng)目實(shí)現(xiàn)相互調(diào)用,感興趣的可以了解一下
    2022-01-01
  • C語言數(shù)據(jù)結(jié)構(gòu)之線索二叉樹及其遍歷

    C語言數(shù)據(jù)結(jié)構(gòu)之線索二叉樹及其遍歷

    這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)之線索二叉樹及其遍歷的相關(guān)資料,為了加快查找節(jié)點(diǎn)的前驅(qū)和后繼。對(duì)二叉樹的線索化就是對(duì)二叉樹進(jìn)行一次遍歷,在遍歷的過程中檢測(cè)節(jié)點(diǎn)的左右指針是否為空,如果是空,則將他們改為指向前驅(qū)和后繼節(jié)點(diǎn)的線索,需要的朋友可以參考下
    2017-08-08
  • C++實(shí)現(xiàn)LeetCode(24.成對(duì)交換節(jié)點(diǎn))

    C++實(shí)現(xiàn)LeetCode(24.成對(duì)交換節(jié)點(diǎn))

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(24.成對(duì)交換節(jié)點(diǎn)),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++指針與引用的異同

    C++指針與引用的異同

    這篇文章主要介紹了C++指針與引用的異同,文章以C++指針與引用的相關(guān)資料結(jié)合指針和引用的相同點(diǎn)和區(qū)別展開詳細(xì)內(nèi)容,需要的朋友可以參考一下
    2021-11-11
  • C語言安全之?dāng)?shù)組長度與指針實(shí)例解析

    C語言安全之?dāng)?shù)組長度與指針實(shí)例解析

    這篇文章主要介紹了C語言安全之?dāng)?shù)組長度與指針,需要的朋友可以參考下
    2014-07-07
  • 淺析C++中的函數(shù)與指針

    淺析C++中的函數(shù)與指針

    這篇文章主要介紹了淺析C++中的函數(shù)與指針,是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • C語言實(shí)現(xiàn)linux網(wǎng)卡檢測(cè)精簡版

    C語言實(shí)現(xiàn)linux網(wǎng)卡檢測(cè)精簡版

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)linux網(wǎng)卡檢測(cè)的精簡版,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06

最新評(píng)論