cmake使用說明

海_纳百川發表於2024-10-29

LINK_DIRECTORIES

LINK_DIRECTORIES 是 CMake 中用於指定連結器搜尋目錄的命令。它告訴 CMake 在構建過程中,連結器應當在哪些目錄中查詢庫檔案。這在你依賴於外部庫或目標時非常有用。

使用場景

  • 當你的專案依賴於某些外部庫,而這些庫不在系統的標準庫路徑下時,你可以使用 LINK_DIRECTORIES 來指定這些庫的所在路徑。
  • 這種方式使得編譯器和連結器在構建時能夠找到所需的庫檔案。

語法

LINK_DIRECTORIES(directory1 directory2 ...)

示例

假設你有一個專案依賴於一些庫,這些庫位於 lib 目錄下,你可以這樣使用:

cmake_minimum_required(VERSION 3.10)
project(MyProject)

# 新增連結目錄
LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/lib)

add_executable(MyExecutable main.cpp)

# 連結庫
target_link_libraries(MyExecutable mylib)

注意事項

  • 使用 LINK_DIRECTORIES 是一種全域性設定,影響到後續的所有目標。如果只需要對特定目標設定連結目錄,可以使用 target_link_directories(CMake 3.13 及更高版本)。
  • 建議儘量使用 target_link_librariesfind_package 來管理庫依賴,這樣可以提高可移植性和可維護性。

使用 LINK_DIRECTORIES 使得庫的管理更為靈活,能夠方便地指定不同的庫路徑。


ADD_EXECUTABLE

ADD_EXECUTABLE 是 CMake 中的一個命令,用於定義一個可執行檔案的構建目標。透過這個命令,CMake 可以生成一個可執行檔案,並將指定的原始檔編譯成該檔案。

主要作用

  • 定義可執行檔案: 指定要生成的可執行檔案的名稱和原始檔列表。
  • 生成構建規則: CMake 會為該可執行檔案生成相應的構建規則,以便在構建時編譯和連結原始檔。
  • 支援多個原始檔: 你可以指定一個或多個原始檔,CMake 會將它們編譯成一個單獨的可執行檔案。

語法

ADD_EXECUTABLE(target_name source1 source2 ...)

示例

以下是一個簡單的示例,展示如何使用 ADD_EXECUTABLE 建立一個名為 MyExecutable 的可執行檔案:

cmake_minimum_required(VERSION 3.10)
project(MyProject)

# 新增可執行檔案
ADD_EXECUTABLE(MyExecutable main.cpp utils.cpp)

引數說明

  • target_name:生成的可執行檔案的名稱。
  • source1, source2, ...:編譯該可執行檔案所需的原始檔列表。

其他功能

  • 連結庫: 一旦使用 ADD_EXECUTABLE 定義了可執行檔案,可以使用 TARGET_LINK_LIBRARIES 來連結其他庫。
  • 設定屬性: 你可以使用 SET_TARGET_PROPERTIES 來設定可執行檔案的屬性,如輸出路徑、版本資訊等。

總結

ADD_EXECUTABLE 是構建可執行檔案的基本命令,使用它可以方便地管理專案中的可執行目標,並確保原始檔被正確編譯和連結。


add_dependencies

add_dependencies 是 CMake 中的一個命令,用於指定目標之間的依賴關係。透過這個命令,你可以確保在構建時某個目標在另一個目標之前構建,從而滿足構建順序的需求。

主要作用

  • 指定依賴關係: 用於宣告一個目標依賴於另一個目標。CMake 會根據這些依賴關係自動安排構建順序。
  • 確保正確的構建順序: 例如,如果你的可執行檔案依賴於一個庫,那麼在構建可執行檔案之前,必須先構建該庫。

語法

add_dependencies(target depend_target1 depend_target2 ...)

示例

以下是一個簡單示例,展示如何使用 add_dependencies 來確保可執行檔案在庫構建之後進行構建:

cmake_minimum_required(VERSION 3.10)
project(MyProject)

# 新增庫
add_library(MyLibrary STATIC mylib.cpp)

# 新增可執行檔案
add_executable(MyExecutable main.cpp)

# 指定可執行檔案依賴於庫
add_dependencies(MyExecutable MyLibrary)

引數說明

  • target:需要依賴的目標(例如可執行檔案或另一個庫)。
  • depend_target1, depend_target2, ...:所依賴的目標。

使用場景

  • 複雜專案: 在大型專案中,尤其是多模組或多目標的專案,使用 add_dependencies 可以確保正確的構建順序。
  • 生成目標: 例如,如果某個目標是從外部工具生成的(如程式碼生成),你可以使用這個命令確保生成目標在使用前完成。

注意事項

  • add_dependencies 不影響檔案的實際編譯或連結,它隻影響 CMake 的構建順序。
  • 目標之間的依賴關係有助於提高構建效率,避免不必要的重複構建。

總結

add_dependencies 是管理目標之間依賴關係的重要工具,確保了構建過程中各個目標的正確順序,從而使得複雜專案的構建變得更加可控和高效。


add_libraryadd_dependencies區別

add_libraryadd_dependencies 是 CMake 中用於不同目的的兩個命令。它們的主要區別在於功能和使用場景。

1. add_library

  • 目的: 用於定義一個庫目標。透過這個命令,你可以建立一個靜態庫、動態庫或共享庫。

  • 用法:

    add_library(target_name [STATIC | SHARED | MODULE] source1 source2 ...)
    
  • 功能:

    • 建立一個可重用的庫,供其他可執行檔案或庫連結使用。
    • 指定庫的型別(靜態、共享或模組)。
  • 示例:

    add_library(MyLibrary STATIC mylib.cpp)
    

2. add_dependencies

  • 目的: 用於指定目標之間的依賴關係。透過這個命令,可以確保在構建時一個目標在另一個目標之前構建。

  • 用法:

    add_dependencies(target depend_target1 depend_target2 ...)
    
  • 功能:

    • 確保在構建過程中某個目標依賴於其他目標的構建。
    • 管理複雜專案中目標的構建順序。
  • 示例:

    add_dependencies(MyExecutable MyLibrary)
    

主要區別

  1. 功能:

    • add_library 用於建立庫目標。
    • add_dependencies 用於管理目標之間的構建依賴關係。
  2. 使用場景:

    • 使用 add_library 當你需要建立一個庫以供其他目標使用時。
    • 使用 add_dependencies 當你需要確保一個目標在另一個目標構建之前完成時。
  3. 影響:

    • add_library 影響的是專案的結構和可重用性。
    • add_dependencies 影響的是構建過程的順序和依賴管理。

總結

add_libraryadd_dependencies 是 CMake 中各自具有不同目的和功能的重要命令,理解它們的區別有助於更有效地管理和構建 CMake 專案。


target_link_libraries

target_link_libraries 是 CMake 中的一個命令,用於指定一個目標(如可執行檔案或庫)連結的其他庫。這使得 CMake 能夠在構建過程中為目標新增所需的庫依賴。

主要作用

  • 連結庫: 透過此命令,您可以將一個或多個庫連結到指定的目標,以便在編譯和連結過程中使用這些庫的功能。
  • 管理庫依賴: CMake 將根據指定的庫自動處理構建順序和連結過程。

語法

target_link_libraries(target_name library1 library2 ...)

示例

以下是一個簡單的示例,展示如何使用 target_link_libraries 將庫連結到可執行檔案:

cmake_minimum_required(VERSION 3.10)
project(MyProject)

# 新增庫
add_library(MyLibrary STATIC mylib.cpp)

# 新增可執行檔案
add_executable(MyExecutable main.cpp)

# 將庫連結到可執行檔案
target_link_libraries(MyExecutable MyLibrary)

引數說明

  • target_name:需要連結庫的目標(如可執行檔案或另一個庫)。
  • library1, library2, ...:要連結的庫名稱,可以是目標名稱、系統庫名稱或路徑。

使用場景

  • 連結外部庫: 當您的專案依賴於外部庫(如 OpenCV、Boost 等)時,使用此命令可以將這些庫連結到您的目標。
  • 模組化設計: 在大型專案中,將庫分開,可以透過 target_link_libraries 來定義各個模組之間的依賴關係。

注意事項

  • 順序: 在某些情況下,庫的連結順序可能會影響連結過程,特別是當庫之間有依賴關係時。
  • 作用域: CMake 3.0 及以上版本支援不同的連結選項(如 PRIVATEPUBLICINTERFACE),可以控制庫的可見性和依賴傳播。

總結

target_link_libraries 是 CMake 中用於管理庫依賴的關鍵命令,確保可執行檔案和庫能夠正確連結到所需的庫,從而實現預期的功能。


add_subdirectory

add_subdirectory 是 CMake 中的一個命令,用於將一個子目錄新增到當前構建中。這允許你在一個較大的專案中組織多個子模組或子專案,並使得 CMake 能夠處理這些子目錄中的 CMakeLists.txt 檔案。

主要作用

  1. 模組化專案: 使用 add_subdirectory 可以將專案分成多個模組或元件,每個模組有自己的 CMake 配置檔案。這有助於提高專案的可維護性和可讀性。

  2. 構建目標: CMake 會自動處理子目錄中定義的所有目標、庫和可執行檔案,將它們納入到整體構建過程。

  3. 共享變數和目標: 子目錄可以訪問父目錄中定義的變數和目標,這使得在不同模組之間共享資訊變得簡單。

語法

add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
  • source_dir: 需要新增的子目錄的路徑,其中包含 CMakeLists.txt 檔案。
  • binary_dir: 可選引數,指定用於構建的二進位制目錄。如果未提供,CMake 將使用 source_dir
  • EXCLUDE_FROM_ALL: 可選引數,表示在預設構建目標中排除該子目錄的目標。

示例

假設有一個專案結構如下:

/MyProject
  ├── CMakeLists.txt
  ├── src
  │    └── CMakeLists.txt
  └── include
       └── CMakeLists.txt

在根目錄的 CMakeLists.txt 檔案中,你可以使用 add_subdirectory 來新增子目錄:

cmake_minimum_required(VERSION 3.10)
project(MyProject)

# 新增 src 子目錄
add_subdirectory(src)

# 新增 include 子目錄
add_subdirectory(include)

使用場景

  • 大型專案: 在大型專案中,通常會將不同的模組或元件放在各自的子目錄中,以便於管理和構建。
  • 庫和可執行檔案分離: 可以在一個目錄中定義庫,在另一個目錄中定義可執行檔案,從而將程式碼和依賴分開。

總結

add_subdirectory 是 CMake 中用於組織和管理大型專案的重要命令,能夠將子模組或子專案的構建配置整合到主構建中,提供靈活的專案結構和可維護性。


if(PRODUCT STREQUAL "default")含義

在 CMake 中,if(PRODUCT STREQUAL "default") 是一個條件判斷語句,用於檢查變數 PRODUCT 的值是否等於字串 "default"。如果條件為真,接下來的程式碼塊將會被執行。

語法解析

  • if(...): CMake 的條件判斷語句,用於執行特定程式碼塊。
  • PRODUCT: 這是一個變數,可能在之前的 CMake 配置中被定義和賦值。
  • STREQUAL: 這是 CMake 中用於比較字串的運算子,表示“字串相等”。與 == 相比,STREQUAL 更為明確,適用於字串比較。
  • "default": 這是要與變數 PRODUCT 的值進行比較的字串。

示例

假設你的 CMakeLists.txt 檔案中定義了變數 PRODUCT,並想根據其值來執行不同的配置:

set(PRODUCT "default")

if(PRODUCT STREQUAL "default")
    message("Product is default")
else()
    message("Product is not default")
endif()

在這個例子中,如果 PRODUCT 的值為 "default",則會輸出 Product is default,否則輸出 Product is not default

總結

if(PRODUCT STREQUAL "default") 用於條件判斷,以便根據 PRODUCT 的值來決定執行哪一部分程式碼。這在根據不同的配置或選項設定專案時非常有用。


在 CMake 中,SET 命令用於定義一個變數並賦值。在你的例子中,SET(SRC ./src/middleware_alg_service.c ./src/middleware_app_mgr.c) 的含義和作用如下:

含義

  • SET: CMake 命令,用於建立或修改變數的值。
  • SRC: 這是變數的名稱。你可以在 CMake 中使用這個名稱引用該變數的值。
  • ./src/middleware_alg_service.c./src/middleware_app_mgr.c: 這些是要賦值給變數 SRC 的檔案路徑,表示原始碼檔案的相對路徑。

作用

  1. 儲存原始檔路徑: 將指定的原始檔路徑儲存在 SRC 變數中,以便在後續的 CMake 命令中使用。例如,可以在 add_executableadd_library 命令中引用這個變數。

  2. 提高可維護性: 透過將原始檔路徑儲存在變數中,你可以更容易地管理和修改原始檔列表。如果需要新增或移除原始檔,只需更新 SRC 變數,而不是在多個地方進行修改。

示例

在實際使用中,你可能會這樣使用 SRC 變數:

# 定義原始檔
SET(SRC ./src/middleware_alg_service.c
        ./src/middleware_app_mgr.c)

# 建立可執行檔案或庫
add_executable(MyExecutable ${SRC})

在這個示例中,MyExecutable 可執行檔案將會由 SRC 變數中列出的原始檔構建。

總結

SET(SRC ./src/middleware_alg_service.c ./src/middleware_app_mgr.c) 用於定義一個名為 SRC 的變數,並將指定的原始檔路徑賦值給它,以便在後續的構建配置中使用。這樣可以提高程式碼的可讀性和可維護性。


在 CMake 中,message(STATUS "CONFIG_HUMAN_DETECT is ${CONFIG_HUMAN_DETECT}") 是一個輸出資訊的命令,具體含義和作用如下:

含義

  • message: CMake 中用於輸出訊息到控制檯的命令。
  • STATUS: 這是訊息的型別,表示這條訊息是一個狀態訊息,通常用於提供資訊而不表示錯誤或警告。
  • "CONFIG_HUMAN_DETECT is ${CONFIG_HUMAN_DETECT}": 這是要輸出的字串,包含一個變數的值。${CONFIG_HUMAN_DETECT} 表示將變數 CONFIG_HUMAN_DETECT 的當前值插入到字串中。

作用

  1. 除錯和資訊輸出: 使用 message 命令可以幫助開發者瞭解當前變數的值,尤其在構建配置過程中。這對於除錯 CMake 指令碼或檢查變數是否被正確設定非常有用。

  2. 可讀性: 在構建過程的控制檯輸出中,能夠清晰地看到某些關鍵變數的值,有助於理解配置狀態。

示例

假設你在 CMakeLists.txt 中定義了一個變數 CONFIG_HUMAN_DETECT,並想輸出它的值:

set(CONFIG_HUMAN_DETECT "enabled")
message(STATUS "CONFIG_HUMAN_DETECT is ${CONFIG_HUMAN_DETECT}")

在構建時,控制檯將輸出:

-- CONFIG_HUMAN_DETECT is enabled

總結

message(STATUS "CONFIG_HUMAN_DETECT is ${CONFIG_HUMAN_DETECT}") 用於輸出變數 CONFIG_HUMAN_DETECT 的值,提供資訊給使用者,通常用於除錯和狀態報告。

相關文章