博客 / 詳情

返回

Y 分鐘速成 CMake

源代碼下載: CMake-cn

CMake 是一個跨平台且開源的自動化構建系統工具。通過該工具你可以對你的源代碼進行測試、編譯或創建安裝包。

CMake 試圖去解決Makefile 跨平台的自動配置問題(不同的make解釋器有不同的命令),以及鏈接第三方庫時的易用性問題。

CMake 是一個可擴展的開源系統,它以操作系統和與編譯器無關的方式管理構建過程。與其他許多跨平台系統不同的是,
CMake 被設計為與本機的構建環境結合使用。它通過被放置於每個源文件目錄下的簡單配置文件(名為 CMakeLists.txt 的文件)
來生成常規使用的標準構建文件(比如:Unix 下的 makefiles 文件或 Windows MSVC 中的 projects/workspaces)。

# 在 CMake 中, 這是一條命令

# 要運行我們的代碼,請執行以下命令:
#  - mkdir build && cd build
#  - cmake ..
#  - make
# 
# 通過上述命令,我們將遵循最佳實踐在子目錄中進行編譯
# 在第二行命令中我們請求Cmake 生成新的依賴於系統的Makefile文件。
# 最後,我們運行本地的make 命令。

#------------------------------------------------------------------------------
# 基礎部分
#------------------------------------------------------------------------------
#
# Cmake文件必須被命令為 “CMakeLists.txt” 。

# 設置生成Makefile的CMake所需最低版本要求
cmake_minimum_required (VERSION 2.8)

# 當版本小於2.8時,需要加入關鍵字 FATAL_ERROR。
cmake_minimum_required (VERSION 2.8 FATAL_ERROR)

# 在這裏定義了項目的名稱,同時會影響Cmake 生成的目錄命名約定。
# 我們可以將代碼的語言作為第二個參數傳入。
project (learncmake C)

# 設置項目的源目錄(僅僅是由於慣例)
set( LEARN_CMAKE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
set( LEARN_CMAKE_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} )

# 在構建系統中用“semver”風格為我們代碼設置當前版本是很有用的。
set (LEARN_CMAKE_VERSION_MAJOR 1)
set (LEARN_CMAKE_VERSION_MINOR 0)
set (LEARN_CMAKE_VERSION_PATCH 0)

# 將變量(版本號)發送到源代碼頭
configure_file (
  "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
  "${PROJECT_BINARY_DIR}/TutorialConfig.h"
)

# 包含目錄
# 在 GCC中, 該語句等同於 "-I" 命令
include_directories( include )

# 在哪裏安裝其他庫?注意:在此處提供includes路徑,後續檢查將解決所有其他問題
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMake/modules/" )

# 條件
if ( CONDITION )
  # 輸出!

  # 附帶信息
  message(STATUS "My message")

  # CMake 警告,繼續處理
  message(WARNING "My message")

  # CMake 警告 (dev),繼續處理
  message(AUTHOR_WARNING "My message")

  # CMake 錯誤,繼續處理但是會跳過生成
  message(SEND_ERROR "My message")

  # CMake 錯誤,停止處理和生成
  message(FATAL_ERROR "My message")
endif()

if( CONDITION )

elseif( CONDITION )

else( CONDITION )

endif( CONDITION )

# 循環
foreach(loop_var arg1 arg2 ...)
  COMMAND1(ARGS ...)
  COMMAND2(ARGS ...)
  ...
endforeach(loop_var)

foreach(loop_var RANGE total)
foreach(loop_var RANGE start stop [step])

foreach(loop_var IN [LISTS [list1 [...]]]
                    [ITEMS [item1 [...]]])

while(condition)
  COMMAND1(ARGS ...)
  COMMAND2(ARGS ...)
  ...
endwhile(condition)


# 邏輯運算
if(FALSE AND (FALSE OR TRUE))
  message("Don't display!")
endif()

# 將常規,緩存或環境變量設置為給定值。
# 如果指定了PARENT_SCOPE選項,則將在當前作用域上的作用域中設置變量
# `set(<variable> <value>... [PARENT_SCOPE])`

# 如何在帶引號和不帶引號的參數中引用變量?How to reference variables inside quoted and unquoted arguments?
# 如果未設置變量,變量引用由變量值或空字符串替換。
${variable_name}

# 清單
# 設置源文件列表
set( LEARN_CMAKE_SOURCES 
  src/main.c
  src/imagem.c
  src/pather.c
)

# 調用編譯器
#
# ${PROJECT_NAME} 即 Learn_CMake 
add_executable( ${PROJECT_NAME} ${LEARN_CMAKE_SOURCES} )

# 鏈接庫
target_link_libraries( ${PROJECT_NAME} ${LIBS} m )

# 在哪裏安裝其他庫?注意:在此處提供includes路徑,後續檢查將解決所有其他問題
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMake/modules/" )

# 編譯條件 (gcc ; g++)
if ( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" )
  message( STATUS "Setting the flags for ${CMAKE_C_COMPILER_ID} compiler" )
  add_definitions( --std=c99 )
endif()

# 檢查 OS
if( UNIX )
    set( LEARN_CMAKE_DEFINITIONS
        "${LEARN_CMAKE_DEFINITIONS} -Wall -Wextra -Werror -Wno-deprecated-declarations -Wno-unused-parameter -Wno-comment" )
endif()

資源

  • CMake tutorial
  • CMake documentation
  • Mastering CMake
  • An Introduction to Modern CMake

有建議?或者發現什麼錯誤?在Github上開一個 issue ,或者發起 pull request !


原著 Bruno Alano,並由 0 個好心人修改。
© 2022 Bruno Alano
Translated by: tx23
本作品採用 CC BY-SA 3.0 協議進行許可。

user avatar lilin_5e390e08b42e4 頭像 tongouba 頭像
2 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.