c++ cmake及包管理工具conan簡單入門

MicroDeLe發表於2021-12-08

cmake是一個跨平臺的c/c++工程管理工具,可以通過cmake輕鬆管理我們的專案
conan是一個包管理工具,能夠自動幫助我們下載及管理依賴,可以配合cmake使用

這是一個入門教程,想深入瞭解的我在後面放了幾個連結可以去學習

1 cmake

1.1 下載cmake

1.2 cmake的主要命令

cmake -B [target]

[target] 表示我們希望cmake生成檔案存放的目錄,一般命名為build, 我們也可以進入到build資料夾下使用cmake .. 將cmake生成的檔案存放到當前目錄
這個命令作用是自動幫我們生成makefile檔案
注意事項:build 檔案的上一級目錄中要有CMakeLists.txt檔案,即cmake的描述檔案

cmake --build [target]

開始編譯,[target]是上一步存放cmake生成檔案的目錄,如果我們在該目錄中 使用cmake --build . 即可

1.3 cmake描述檔案CMakeLists.txt初體驗

(1)宣告需要的cmake的最低版本: 這行必須在描述檔案的第一行,這裡我設定的最低版本是3.16

cmake_minimum_required(VERSION 3.16)

(2) 新增專案名: 這裡我把專案名稱設定為cmake

project(cmake)

(3) 新增可執行檔名:這裡我設定的可執行檔名是cmake,他依賴的檔案是main.cpp,在編譯完成後回生成cmake.out或cmake.exe檔案

add_executable(cmake main.cpp)

以上三行程式碼就簡單定義好一個cmake描述檔案了,這三行也是一個camke描述檔案必不可少的

1.4 cmake描述檔案再探

上一節介紹了cmake的簡單使用,我們的工程不會只有一個檔案,也不會只有一個資料夾,否則也不會使用cmake來幫助我們管理,接下來介紹cmake的更多用法

(1) 設定c++版本:指定c++最低編譯版本,這裡我設定的是14

set(CMAKE_CXX_STANDARD 14)

(2) 指定工程的版本號及語言:使用1.3節第(2)步的命令我們可以為工程設定版本號和指定語言,這裡設定的版本號是1.0.0,語言CXX表示c++, 我們可以設定4個欄位的版本資訊,通過使用配置檔案生成標頭檔案在我們的專案中使用版本資訊, 4個欄位見附錄

project(cmake VERSION 1.0.0 LANGUAGES CXX)

(3) 生成靜態連結庫: 有時候我們的檔案可能分散在多個資料夾中,這時我們就可以通過生成靜態庫的方式將他們連結並生成可執行檔案,我們需要在子檔案中同樣包含CMakeLists.txt檔案,然後新增

add_library(libmyHeap STATIC ${CMAKE_CURRENT_SOURCE_DIR}/MyHeap.cpp) # 當前庫檔案

target_include_directories(libmyHeap PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) # 標頭檔案

這裡通過add_library()指定生成庫,libmyHeap 是庫的名字,STATIC 指定生成的靜態庫,${CMAKE_CURRENT_SOURCE_DIR}/MyHeap.cpp 指定我們生成庫依賴原始檔的路徑
${CMAKE_CURRENT_SOURCE_DIR}表示當前CMakeLists.txt所在的檔案路徑

target_include_directories() 指定生成庫依賴的標頭檔案
libmyHeap是生成靜態庫的名字
PUBLIC 表示當前靜態庫的依賴可以被上層cmake發現,同時該庫也依賴該標頭檔案,當然還有其它設定,作為入門不做介紹
${CMAKE_CURRENT_SOURCE_DIR} 表示當前CMakeLists.txt所在的檔案路徑

通過這兩句命令即可生成一個靜態庫,要想能被可執行程式連結到,我們只需在頂層CMakeLists.txt檔案中新增
add_subdirectory(myHeap) # 新增子目錄搜尋路徑 以及
target_link_libraries(cmake libmyHeap)

首先,第一句add_subdirectory()指定底層CMakeLists.txt的路徑,這樣我們的頂層CMakeLists.txt就能找到並編譯
target_link_libraries()第一個引數指定target即我們的專案名,第二個引數指定要連結的庫名
由於我們在上面設定生成靜態庫時設定可見屬性為PUNLIC 因此這裡不需要指定標頭檔案路徑,cmake就可以通過底層CMakeLists.txt 找到我們需要的標頭檔案,這也是現代cmake的做法

以上就是cmake的基本使用,我們可以把檔案放在不同資料夾,並通過生成靜態庫的方式將各個檔案連結起來,這裡列出總的CMakeLists.txt檔案
頂層CMakeLists.txt

cmake_minimum_required(VERSION 3.16)  # 設定cmake最低版本

project(cmake VERSION 1.0.0 LANGUAGES CXX) # 設定檔名及版本資訊

set(CMAKE_CXX_STANDARD 14) # 設定c++版本

add_subdirectory(myHeap) # 新增子目錄搜尋路徑,這裡值myHeap路徑

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

target_link_libraries(cmake libmyHeap)  # 連結庫名稱

底層CMakeLists.txt

add_library(libmyHeap STATIC ${CMAKE_CURRENT_SOURCE_DIR}/MyHeap.cpp) # 當前庫檔案

target_include_directories(libmyHeap PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) # 標頭檔案

檔案結構

Ok,上面就列出了cmake的簡單使用,有時候我們寫專案的時候需要使用別人寫的庫,這個時候一般會下載原始碼在本地編譯或者下載對應版本的編譯後的檔案,但是我們使用的庫還可能包含別人的庫,別人的庫可能還使用了別別人寫的庫,這樣一個個下載編譯太過麻煩,而且有些庫還存在多次引入的可能,因此我們需要一個工具幫助我們管理包和依賴,這裡介紹conan

2 conan

conan是一個c++包管理工具,一行程式碼就能將我們需要的包下載到本地並進行編譯

注意:目前已知在windows + gcc存在bug,導致編譯失敗,我也不知什麼原因,stackoverflow上有一個提問,說是由於相容性問題,這裡我是直接在linux平臺使用

2.1 下載conan

下載很簡單,直接通過pip下載

pip install conan

稍等片刻,就下載好了,這個時候如果我們輸入conan --version 可能會找不到命令,這是因為環境變數沒有新增,新增環境變數網上教程很多

2.2 新增conan配置檔案

conanfile.txt這裡包含兩項,第一項是要下載的庫和版本號,第二項是指定生成的管理格式,這裡我們選擇cmake
以使用poco庫為例,我們只需在conanfile.txt中寫

 [requires]
 poco/1.11.1

 [generators]
 cmake

這裡我們怎麼知道所使用的庫有哪些版本呢?
可以使用命令conan search poco -r conancenter 獲取,其中-r conancenter指定我們需要在conan中央倉庫搜尋,否則預設本地搜尋,要新增其它庫,直接在[requires]下新增庫名和版本號,然後重新安裝就好了

2.3 安裝庫

我們以及建立好好conan配置檔案,下一步,進入build資料夾(這個資料夾就是我們存放cmake生成檔案的地方哦),然後一行命令conan install . 即可靜靜等待下載安裝完成了

注意事項: 這個時候可能需要我們指定一些配置資訊,配置資訊在~/.conan/profiles/default檔案裡,配置資訊需要新增的內容在~/.conan/settings.yml檔案裡,對於gcc,需要配置compiler.libcxx=libstdc++11 否則以舊版本安裝,這裡列出我的配置檔案供參考

[settings]
os=Linux
os_build=Linux
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=gcc
compiler.libcxx=libstdc++11
compiler.version=9
[options]
[build_requires]
[env]

在這插一條 剛剛吃完飯準備把build資料夾的快取刪了,然後測試一下看看寫的對不對,準備輸rm -rf build/* 結果輸成了rm -rf /*,好傢伙.....自閉中...

2.4 在cmake中配置

只需要在頂層CMakeLists.txt檔案中新增

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()

${CMAKE_BINARY_DIR}表示當前build資料夾路徑, 然後在mian.cpp裡引用標頭檔案即可

2.5 使用

現在我麼可以使用cmake編譯我們我們的工程了
進入到build資料夾下,輸入cmake .. 等待生成makefile檔案完成後,輸入cmake build .等待編譯成功了

附錄

附錄1:cmake變數常用變數
PROJECT_SOURCE_DIR:工程的根目錄,頂層CMakeLists.txt所在的目錄

PROJECT_BINARY_DIR:cmake生成檔案儲存的目錄,通常為build目錄

PROJECT_NAME:專案名

CMAKE_CURRENT_SOURCE_DIR:當前CMakeLists.txt所在的路徑

EXECUTABLE_OUTPUT_PATH:重新定義目標二進位制可執行檔案的存放位置

LIBRARY_OUTPUT_PATH:重新定義目標連結庫檔案的存放位置

使用格式 ${value}

附錄2: 版本號欄位 PROJECT-NAME:當前專案名
PROJECT-NAME_VERSION_MAJOR:第一個欄位
PROJECT-NAME_VERSION_MINOR:第二個欄位
PROJECT-NAME_VERSION_PATCH:第三個欄位
PROJECT-NAME_VERSION_TWEAK:第四個欄位
附錄3:更進一步的學習連結

  1. https://www.zhihu.com/column/c_1369781372333240320 知乎: 很酷的程式設計師 cmke
  2. https://blog.csdn.net/weixin_39773239/article/details/113052000 CSDN: weixin_39773239 cmake
  3. https://www.bilibili.com/video/BV14h41187FZ B站:IPADS cmake
  4. https://www.bilibili.com/video/BV1wL411u74B B站: bennyhuo不是算命的 conan
  5. https://cmake.org/cmake/help/v3.22/ cmake官方文件