cmake之引入外部項目(引用其他項目)、FetchContent管理子模塊(fetchcontent用法)


本文CMAKE版本為3.18
演示環境: Windows+CMake+VS2017

源碼下載說明

  • 演示代碼是后來傳上去的,而且做了些修改,將spdlog_demoexe改為了lib,但是,spdlog_demo依然使用FetchContent的方式引用spdlog
  • 這里下載源碼

1. 關於

截至目前,我知道的,有兩種方式引入外部項目

  • A. git下的Submodule
    使用命令可以將克隆的項目添加到當前項目,作為子項目使用,比如,fmt庫為例:
git submodule add https://gitee.com/mohistH/fmt.git

submodule 不熟悉?請參考官方文檔

  • B. cmake的FetchContent
    本文將側重介紹這種方式 ,至於具體需要怎么使用FetchContent,這里就不重復了,請參考官方文檔

2.FetchContent使用步驟

按照下面的順序使用

1.include(FetchContent) 
2.FetchContent_Declare(子模塊名) 獲取項目。
3.FetchContent_MakeAvailable(子模塊),再引入我們的項目中
4.target_link_libraries(主項目 PRIVATE 子模塊::子模塊)

3. FetchContent的一個簡單例子

這里,以下載spdlog庫作為項目的子模塊使用,直接將下載子模塊的代碼配置寫到了top directory下的CMakeLists.txt

  • 3.1 目錄結構
.
├───build		# cmake的輸出文件
├───ext		# spdlog等第三方庫的存放目錄
├───include		# 頭文件路徑
├───src		# 源文件路徑
└───CMakeLists.txt # top directory下的cmake配置文件
  • 3.2 top directory下的cmake配置文件CMakeLists.txt文件源碼
cmake_minimum_required(VERSION 3.18)

project(spdlog_demo VERSION 1.0.1)

# 因為spdlog是基於c++11的庫
set(CMAKE_CXX_STANDARD 11)

# 指定源文件
set(src_file 
	${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
)

# 創建可執行程序項目
add_executable(spdlog_demo ${src_file} )
# 指定頭文件路徑
target_include_directories(spdlog_demo PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
# 指定lib文件路徑
target_link_libraries(	spdlog_demo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)

# fetchcontent重點來了
#-------------------------------------------------------------------
include(fetchcontent)      # 照寫,不需要修改
 fetchcontent_declare(	spdlog	#庫名字
						GIT_REPOSITORY https://gitee.com/mohistH/spdlog.git	# 倉庫地址
						GIT_TAG v1.x # 庫版本
						SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/spdlog # 指定庫下載地址
						)

fetchcontent_makeavailable(spdlog)

# 項目中使用spdlog
target_link_libraries(spdlog_demo PRIVATE spdlog::spdlog)
#-------------------------------------------------------------------

這里創建了一個項目spdlog_demo,該項目引用了子模塊spdlog,本地沒有spdlog,上面的代碼中則是在調用cmakelists.txt的時候下載spdlog的源碼

  • 3.3 轉到build目錄,使用cmake .. , 就開始配置項目了,並下載源碼spdlog, 將spdlog的源碼放到了top directory下的ext文件夾下。

4.將FetchContent分離到cmake文件

上面演示的項目過於簡單,CMakeLists.txt文件也相對簡潔,但是項目復雜了,CMakeLists.txt的內容必然增多,復雜度也上來了。

  • 4.1 創建cmake文件夾
    接着上面的項目,創建一個cmake(文件名任意)的文件夾,此時,目錄結構是這樣的:
.
├───build		# cmake的輸出文件
├───cmake		# cmake文件夾,存放 .cmake文件
├───ext		# spdlog等第三方庫的存放目錄
├───include		# 頭文件路徑
└───src
        main.cc      # 主項目源文件
└───CMakeLists.txt # top directory下的cmake配置文件
  • 4.2 spdlog.cmake
    轉到cmake文件夾,並創建文件spdlog2.cmake文件,將上面的FetchContent相關代碼放入.cmake文件,文件內容如下:
# fetchcontent重點來了
#-------------------------------------------------------------------
include(fetchcontent)
 fetchcontent_declare(	spdlog	#庫名字
						GIT_REPOSITORY https://gitee.com/mohistH/spdlog.git	# 倉庫地址
						GIT_TAG v1.x # 庫版本
						SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/spdlog # 指定庫下載地址
						)

fetchcontent_makeavailable(spdlog)

此時目錄結構如下:

.
│   
├───build
├───cmake
│       spdlog2.cmake	# 新增的文件
│       
├───ext
├───include
└───src
        main.cc
└───CMakeLists.txt
  • 4.3 CMakeLists.txt增加代碼
    Top Directory目錄下的CMakeLists.txt中增加引用 spdlog2.cmake的引用,代碼如下:
# -------------------------------------------------------------------------------------
# 下面開始引入第三方庫
# -------------------------------------------------------------------------------------
# set cmake file'dir: to/path/serial_port/cmake/
# -------------------------------------------------------------------------------------
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}")

# 引入spdlog2.camake, 
include(spdlog2)	# 填寫文件名

# 項目中使用spdlog
target_link_libraries(spdlog_demo PRIVATE spdlog::spdlog)
# -------------------------------------------------------------------------------------

此時,CMakeLists.txt的內容如下:

cmake_minimum_required(VERSION 3.18)

project(spdlog_demo VERSION 1.0.1)


# 因為spdlog是基於c++11的庫
set(CMAKE_CXX_STANDARD 11)

# 指定源文件
set(src_file 
	${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
)

# 創建可執行程序項目
add_executable(spdlog_demo ${src_file} )
# 指定頭文件路徑
target_include_directories(spdlog_demo PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
# 指定lib文件路徑
target_link_libraries(	spdlog_demo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)


# -------------------------------------------------------------------------------------
# 下面開始引入第三方庫
# -------------------------------------------------------------------------------------
# set cmake file'dir: to/path/serial_port/cmake/
# -------------------------------------------------------------------------------------
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}")

# 引入spdlog2.camake, 
include(spdlog2)	# 填寫文件名

# 項目中使用spdlog
target_link_libraries(spdlog_demo PRIVATE spdlog::spdlog)
# -------------------------------------------------------------------------------------

4.4 下載子模塊源碼

轉到build目錄,下載源碼,指令:

$ cd to/path/build 
$ cmake .. 

命令結束后,可見ext目錄下多了spdlog源碼目錄,且 build目錄下多了項目的配置文件:

  • 4.5 查看項目
    可見,spdlog項目已經添加

5. 調用子模塊

上面的文件main.cc文件源碼如下:

#pragma once

#include <iostream>
#include <spdlog/spdlog.h>

using namespace std;

int main(int argc, char *argv[])
{
	spdlog::info("i love c++");

	system("PAUSE");
	return 0;
}

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM