CMake教程版本號:3.16.3
英文原文鏈接: https://cmake.org/cmake/help/latest/guide/tutorial/index.html#id2
github示例代碼 https://github.com/sxpsxp12/cmake-learning-exampes
自定義庫
第二課內容是講解爲我們的項目添加庫。首先需要創建我們自己的庫。
cmake_minimum_required(VERSION 3.0.0)
project(sayhello VERSION 0.1.0)
add_library(sayhello helloworld.cpp)
庫目錄樹爲:
.
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── cmake_install.cmake
│ ├── compile_commands.json
│ ├── CPackConfig.cmake
│ ├── CPackSourceConfig.cmake
│ ├── CTestTestfile.cmake
│ ├── DartConfiguration.tcl
│ ├── libhelloworld.a
│ ├── Makefile
│ └── Testing
├── CMakeLists.txt
└── helloworld.cpp
3 directories, 11 files
- 構建項目,即可看到build目錄下生成的庫
cd build
cmake ..
make
使用自定義庫
示例項目目錄樹爲:
.
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── cmake_install.cmake
│ ├── compile_commands.json
│ ├── config.h
│ ├── helloworld
│ └── Makefile
├── CMakeLists.txt
├── config.h.in
├── main.cpp
└── sayhellolibrary
├── CMakeLists.txt
├── helloworld.cpp
└── helloworld.h
3 directories, 12 files
- 首先創建項目目錄,然後將自定義庫目錄放置到根目錄下
- 在根目錄創建CMakefile.txt文件,添加命令,以便庫能夠得到編譯
add_subdirectory(sayhellolibrary)
- 在根目錄的CMakefile.txt文件中,添加指令,以搜索找到自定義庫的頭文件
target_include_directories(helloworld PUBLIC
"${PROJECT_BINARY_DIR}"
"${PROJECT_SOURCE_DIR}/sayhellolibrary"
)
- 爲可執行程序鏈接庫
target_link_libraries(helloworld PUBLIC sayhello)
最終我們看到的根目錄的CMakefile.txt內容爲:
cmake_minimum_required(VERSION 3.0.0)
project(helloworld VERSION 0.1.0)
add_executable(helloworld main.cpp)
add_subdirectory(sayhellolibrary)
target_include_directories(helloworld PUBLIC
"${PROJECT_BINARY_DIR}"
"${PROJECT_SOURCE_DIR}/sayhellolibrary"
)
target_link_libraries(helloworld PUBLIC sayhello)
最後構建並運行可執行程序
cd build
cmake ..
make
構建可選項
可以通過開關項,來決定庫是否啓用,在大型項目中,該功能非常有用。
- 首先在根目錄的CMakefile.txt文件中添加可選項
option(USE_SAYHELLO "use say hello to provide info" OFF)
#配置一個頭文件,以便將CMake的配置傳遞到源代碼中
configure_file(config.h.in config.h)
- 在根目錄創建config.h.in文件,並將配置傳遞到源代碼中
#cmakedefine USE_MYMATH
- USE_SAYHELLO這個可選項可以控制是否啓用該庫,這個配置項會存儲到Cache中,因此不需要每次構建的時候都設置該值。
- 接下來在根目錄的CMakefile.txt文件中添加條件邏輯
if(USE_SAYHELLO)
#添加子CMakefile.txt目錄,以便能夠build
add_subdirectory(sayhellolibrary)
#將庫添加到變量EXTRA_LIBS
list(APPEND EXTRA_LIBS sayhello)
#將頭文件路徑添加到變量EXTRA_INCLUDES中
list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/sayhellolibrary")
endif(USE_SAYHELLO)
target_include_directories(helloworld PUBLIC
"${PROJECT_BINARY_DIR}"
${EXTRA_INCLUDES}
)
target_link_libraries(helloworld PUBLIC ${EXTRA_LIBS})
- 修改源代碼,以使用可選項
#ifdef USE_SAYHELLO
#include "helloworld.h"
#endif
...
完整的CMakefile.txt爲:
cmake_minimum_required(VERSION 3.0.0)
project(helloworld VERSION 0.1.0)
add_executable(helloworld main.cpp)
option(USE_SAYHELLO "use say hello to provide info" OFF)
#配置一個頭文件,以便將CMake的配置傳遞到源代碼中
configure_file(config.h.in config.h)
if(USE_SAYHELLO)
#添加子CMakefile.txt目錄,以便能夠build
add_subdirectory(sayhellolibrary)
#將庫添加到變量EXTRA_LIBS
list(APPEND EXTRA_LIBS sayhello)
#將頭文件路徑添加到變量EXTRA_INCLUDES中
list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/sayhellolibrary")
endif(USE_SAYHELLO)
target_include_directories(helloworld PUBLIC
"${PROJECT_BINARY_DIR}"
${EXTRA_INCLUDES}
)
target_link_libraries(helloworld PUBLIC ${EXTRA_LIBS})
最終構建並運行
cd build
cmake ..
make
可自行修改可選項USE_SAYHELLO的值,可刪除構建緩衝,重新構建運行看看效果
總結
這一節,我們新學習的cmake指令如下
add_library
所屬:項目命令,只能用於CMake項目
使用指定的源文件將庫添加到項目中。
普通的庫
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
[source1] [source2 ...])
根據命令中的源文件構建一個名爲的庫(如果源文件在之後使用target_sources()添加,那麼此處可以忽略),必須是一個合規的名字,並且必須在項目中是唯一的。
STATIC, SHARED, or MODULE這三個關鍵字可以指定生成庫的類型。靜態庫是目標文件的歸檔,以便其他目標鏈接使用。共享庫動態鏈接,並在運行時加載。MODULE庫是一個插件,不會鏈接到其他目標,但是可以動態加載。
如果關鍵字沒有設置,取決於當前變量BUILD_SHARED_LIBS
是否是ON, 關鍵字SHARED和MODULE的配置,會自動將可執行程序的屬性POSITION_INDEPENDENT_CODE(是否創建一個路徑無關的可執行程序或者庫)設置爲ON。
導入的庫
add_library(<name> <SHARED|STATIC|MODULE|OBJECT|UNKNOWN> IMPORTED
[GLOBAL])
一個IMPORTED庫表示一個位於項目以外的庫文件。沒有規則構建它,且IMPORTED屬性是True。
對象庫
add_library(<name> OBJECT <src>...)
創建一個對象庫,它會編譯源文件,但是不會是源文件的歸檔或者鏈接這些文件到庫中。
別名庫
add_library(<name> ALIAS <target>)
創建一個別名目標,以便可用於在後續命令中引用。 不會作爲生成目標出現在生成的構建系統中。
接口庫
add_library(<name> INTERFACE [IMPORTED [GLOBAL]])
創建一個接口庫。 INTERFACE庫目標雖然可以設置屬性,並且可以安裝,導出和導入,但它不會直接創建構建輸出
更多信息請查看: https://cmake.org/cmake/help/latest/command/add_library.html
add_subdirectory
所屬:項目命令,只能用於CMake項目
添加要構建的子目錄
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
source_dir表示CMakefile.txt和代碼文件所在的目錄。相對路徑是基於當前路徑,也可以是絕對路徑。binary_dir表示輸出文件的路徑。如果是相對路徑,是基於當前輸出路徑的相對路徑,也可以是絕對路徑。
target_link_libraries
所屬:項目命令,只能用於CMake項目
指定給定可執行程序的鏈接庫或者標誌。
target_link_libraries(<target> ... <item>... ...)
有多種形式,具體信息可查看: https://cmake.org/cmake/help/latest/command/target_link_libraries.html
option
所屬:腳本指令,總是可用的
提供可選項,供用戶選擇
option(<variable> "<help_text>" [value])
提供一個可選項,供用戶選擇ON或者OFF.[value]默認是OFF。
歡迎各位大佬右側關注、點贊、打賞,我們再會。。。