cmake是現在主流的用於多平台C++構建系統,本文用來記錄cmake的一些常用命令的索引,加上一些自己理解,理解有誤的話,歡迎大家指出。
常用路徑
- CMAKE_SOURCE_DIR: 頂級cmakelists.txt的文件夾目錄。
- CMAKE_BINRAY_DIR: 對應cmake的build的目錄,主要是運行時生成的文件目錄。
- CMAKE_CURRENT_SOURCE_DIR: 一般來說,一個工程會有多個cmakelists.txt文件,對應當前文件目錄。
- CMAKE_CURRENT_BINARY_DIR: 對應build里的目錄。
- CMAKE_MODULE_PATH: api(include/find_package)包含別的cmake文件時的搜索目錄。
- CMAKE_PREFIX_PATH: api(find_libray/path)包含模塊時的搜索目錄。
- CMAKE_INSTALL_PREFIX: 調用install相關函數,要生成/保存的根目錄路徑。
常用內置變量
- 系統:WIN32/APPLE/ANDROID
- 方案配置:CMAKE_BUILD_TYPE(Release/Debug)
- 編譯器:MINGW/CMAKE_COMPILER_IS_GNUCXX/CMAKE_COMPILER_IS_CLANGXX/MSVC(MSVC_VERSION C++平台工具集)
- 編譯器64/32:CMAKE_SIZEOF_VOID_P EQUAL 8/4
常用API
系統API,每一個API應該說是一個庫,所以具體用法自行搜索。
- set 設置參數,包含一般/緩存/環境變量。
- list 針對列表操作,比如針對文件列表/參數列表/編譯列表的增加刪除這些。
- file 針對文件操作,如收集文件列表,讀寫文件等。
- string 針對字符串的操作,如大小寫,查找,正則表達式匹配等。
- message 打印消息,可以跟蹤測試修改。
C++編譯相關
- add_compile_options:不同平台一般來說有不同的編譯設置。
- add_definitions:添加預處理器定義。
- include_directories: 如visual studio里的,頭文件搜索目錄,在當前項目以及當前項目用add_subdirectory添加的項目都會應用。
- target_include_directories:針對指定目標的include_directories。
- link_libraries: 添加庫文件路徑,注意是全路徑,如果是本方案的項目,直接使用項目名就行。在當前項目以及當前項目用add_subdirectory添加的項目都會應用。
- target_link_libraries:指定目標的link_directories。
- add_library:添加庫,根據參數生成靜態或是動態庫。
- add_executable:添加執行文件。
- set_target_properties:指定項目一些具體編輯器里的屬性,如生成lib/dll的目錄。
install:方案包含的項目多,每次把需要發給用戶的 include/lib/dll按照指定目錄格式放好,這個可以用來做這些。cmake默認會生成一個insatll項目,這個項目會執行所有install命令,比如生成的 include/lib/dll放入以CMAKE_INSTALL_PREFIX為根路徑的目錄。
常用操作
A目錄 CMakeLists.txt包含B目錄 CMakeLists.txt
一般有二種方式,其一存放一些共同宏,函數或是變量,放入CMAKE_MODULE_PATH指定的目錄里,用include包含,其類似CMAKE_CURRENT_SOURCE_DIR指向的是執行這個函數的CMakeLists.txt,比如這里A執行B中函數,那指向A目錄。其二是使用add_subdirectory,這個文件內一般會包含add_library或是add_executable,CMAKE_CURRENT_SOURCE_DIR針對的是當前這個文件目錄,如上就是B所在目錄,B這種文件一般放在方案下的每個項目內。
引入第三方庫
find_package(LibaryName)根據對應CMAKE_MODULE_PATH找到對應的Find<LibaryName>.cmake,一般來說,有如下三下變量(你也可以定義成別的名字)。
- <LibaryName>_FOUND 是否找到庫
- <LibaryName>_INCLUDE_DIR <LibaryName>_INCLUDES 庫頭文件目錄
- <LibaryName>_LIBRARY <LibaryName>_LIBRARIES 庫鏈接文件路徑
如果我們引用的第三方庫沒有提供Find<LibaryName>.cmake,我們可以自己寫,只需要填充上面上面變量,就可以使用find_package,實際一般用如下幾個函數確定這三個變量,而這幾個函數默認都會去CMAKE_PREFIX_PATH查找:
- FIND_PACKAGE_HANDLE_STANDARD_ARGS:<LibaryName>_FOUND
- find_path:獲得<LibaryName>_INCLUDE_DIR目錄。
- find_library:獲得<LibaryName>_LIBRARY 目錄。
結合前面的include_directories/link_libraries引用對應的<LibaryName>_INCLUDE_DIR/<LibaryName>_INCLUDE_DIR就引入第三方庫了。
配置選項
option/cmake_dependent_option:給定用戶選項,如是否使用某個第三庫這些,是否使用某些組件等。
configure_file:把如上選項結合配置模板生成配置文件C++頭文件,使C++項目能拿到用戶的配置。
這樣CMake變量與配置C++的頭文件以及根據變量設置的預處理器定義對應上。
運行Python腳本
一般工程會在編譯前或后執行一些腳本或是下載,一般配合python腳本語言使用。
find_package(PythonInterp 3 REQUIRED)
add_custom_command 使用 ${PYTHON_EXECUTABLE} 執行對應腳本並傳入相應參數,完成如下載資源或是執行glsl/hlsl轉spv等邏輯。