cmake之引入外部项目(引用其他项目)、FetchContent管理子模块(fetchcontent用法)
阅读原文时间:2023年07月11日阅读:1

本文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;
}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章