本文CMAKE版本为3.18

演示环境: Windows+CMake+VS2017

源码下载说明

  • 演示代码是后来传上去的,而且做了些修改,将spdlog_demoexe改为了lib,但是,spdlog_demo依然使用FetchContent的方式引用spdlog
  • 这里下载源码

1. 关于

截至目前,我知道的,有两种方式引入外部项目

  • A. git下的Submodule

    使用命令可以将克隆的项目添加到当前项目,作为子项目使用,比如,fmt库为例:
  1. git submodule add https://gitee.com/mohistH/fmt.git

submodule 不熟悉?请参考官方文档

  • B. cmake的FetchContent

    本文将侧重介绍这种方式 ,至于具体需要怎么使用FetchContent,这里就不重复了,请参考官方文档

2.FetchContent使用步骤

按照下面的顺序使用

  1. 1.include(FetchContent)
  2. 2.FetchContent_Declare(子模块名) 获取项目。
  3. 3.FetchContent_MakeAvailable(子模块),再引入我们的项目中
  4. 4.target_link_libraries(主项目 PRIVATE 子模块::子模块)

3. FetchContent的一个简单例子

这里,以下载spdlog库作为项目的子模块使用,直接将下载子模块的代码配置写到了top directory下的CMakeLists.txt

  • 3.1 目录结构
  1. .
  2. ├───build # cmake的输出文件
  3. ├───ext # spdlog等第三方库的存放目录
  4. ├───include # 头文件路径
  5. ├───src # 源文件路径
  6. └───CMakeLists.txt # top directory下的cmake配置文件
  • 3.2 top directory下的cmake配置文件CMakeLists.txt文件源码
  1. cmake_minimum_required(VERSION 3.18)
  2. project(spdlog_demo VERSION 1.0.1)
  3. # 因为spdlog是基于c++11的库
  4. set(CMAKE_CXX_STANDARD 11)
  5. # 指定源文件
  6. set(src_file
  7. ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
  8. )
  9. # 创建可执行程序项目
  10. add_executable(spdlog_demo ${src_file} )
  11. # 指定头文件路径
  12. target_include_directories(spdlog_demo PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
  13. # 指定lib文件路径
  14. target_link_libraries( spdlog_demo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
  15. # fetchcontent重点来了
  16. #-------------------------------------------------------------------
  17. include(fetchcontent) # 照写,不需要修改
  18. fetchcontent_declare( spdlog #库名字
  19. GIT_REPOSITORY https://gitee.com/mohistH/spdlog.git # 仓库地址
  20. GIT_TAG v1.x # 库版本
  21. SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/spdlog # 指定库下载地址
  22. )
  23. fetchcontent_makeavailable(spdlog)
  24. # 项目中使用spdlog
  25. target_link_libraries(spdlog_demo PRIVATE spdlog::spdlog)
  26. #-------------------------------------------------------------------

这里创建了一个项目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(文件名任意)的文件夹,此时,目录结构是这样的:
  1. .
  2. ├───build # cmake的输出文件
  3. ├───cmake # cmake文件夹,存放 .cmake文件
  4. ├───ext # spdlog等第三方库的存放目录
  5. ├───include # 头文件路径
  6. └───src
  7. main.cc # 主项目源文件
  8. └───CMakeLists.txt # top directory下的cmake配置文件
  • 4.2 spdlog.cmake

    转到cmake文件夹,并创建文件spdlog2.cmake文件,将上面的FetchContent相关代码放入.cmake文件,文件内容如下:
  1. # fetchcontent重点来了
  2. #-------------------------------------------------------------------
  3. include(fetchcontent)
  4. fetchcontent_declare( spdlog #库名字
  5. GIT_REPOSITORY https://gitee.com/mohistH/spdlog.git # 仓库地址
  6. GIT_TAG v1.x # 库版本
  7. SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/spdlog # 指定库下载地址
  8. )
  9. fetchcontent_makeavailable(spdlog)

此时目录结构如下:

  1. .

  2. ├───build
  3. ├───cmake
  4. spdlog2.cmake # 新增的文件

  5. ├───ext
  6. ├───include
  7. └───src
  8. main.cc
  9. └───CMakeLists.txt
  • 4.3 CMakeLists.txt增加代码

    Top Directory目录下的CMakeLists.txt中增加引用 spdlog2.cmake的引用,代码如下:
  1. # -------------------------------------------------------------------------------------
  2. # 下面开始引入第三方库
  3. # -------------------------------------------------------------------------------------
  4. # set cmake file'dir: to/path/serial_port/cmake/
  5. # -------------------------------------------------------------------------------------
  6. set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}")
  7. # 引入spdlog2.camake,
  8. include(spdlog2) # 填写文件名
  9. # 项目中使用spdlog
  10. target_link_libraries(spdlog_demo PRIVATE spdlog::spdlog)
  11. # -------------------------------------------------------------------------------------

此时,CMakeLists.txt的内容如下:

  1. cmake_minimum_required(VERSION 3.18)
  2. project(spdlog_demo VERSION 1.0.1)
  3. # 因为spdlog是基于c++11的库
  4. set(CMAKE_CXX_STANDARD 11)
  5. # 指定源文件
  6. set(src_file
  7. ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
  8. )
  9. # 创建可执行程序项目
  10. add_executable(spdlog_demo ${src_file} )
  11. # 指定头文件路径
  12. target_include_directories(spdlog_demo PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
  13. # 指定lib文件路径
  14. target_link_libraries( spdlog_demo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
  15. # -------------------------------------------------------------------------------------
  16. # 下面开始引入第三方库
  17. # -------------------------------------------------------------------------------------
  18. # set cmake file'dir: to/path/serial_port/cmake/
  19. # -------------------------------------------------------------------------------------
  20. set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}")
  21. # 引入spdlog2.camake,
  22. include(spdlog2) # 填写文件名
  23. # 项目中使用spdlog
  24. target_link_libraries(spdlog_demo PRIVATE spdlog::spdlog)
  25. # -------------------------------------------------------------------------------------

4.4 下载子模块源码

转到build目录,下载源码,指令:

  1. $ cd to/path/build
  2. $ cmake ..

命令结束后,可见ext目录下多了spdlog源码目录,且 build目录下多了项目的配置文件:

  • 4.5 查看项目

    可见,spdlog项目已经添加

5. 调用子模块

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

  1. #pragma once
  2. #include <iostream>
  3. #include <spdlog/spdlog.h>
  4. using namespace std;
  5. int main(int argc, char *argv[])
  6. {
  7. spdlog::info("i love c++");
  8. system("PAUSE");
  9. return 0;
  10. }

参考

cmake之引入外部项目(引用其他项目)、FetchContent管理子模块(fetchcontent用法)的更多相关文章

  1. Java web项目引用java项目,类型找不到

    Java web项目引用java项目,类型找不到 错误信息: java.lang.ClassNotFoundException: org.codehaus.jackson.map.ObjectMapp ...

  2. web项目引用Java项目,连接报错error HTTP Status 500 - Servlet execution threw an exception

    错误信息 项目背景: 一个web项目引用一个java Project,项目中添加了引用,但是打开页面访问,总报500错误.提示:servlet初始化错误. 环境:Eclipse luna JDK: 1 ...

  3. Eclipse web项目引用其它项目时的部署问题

    地址:http://blog.csdn.net/testcs_dn/article/details/43764497

  4. Android 如何在Eclipse 引入外部纯Java项目(不是打成Jar使用)

    应用情景--如标题: 在Eclipse的 “Android启动项目”中引入“外部的纯Java项目”,能运行的只有是基于Android的测试代码才可以. 一直很纳闷,如果外部写好一个Java插件(例如服 ...

  5. MyEclipse 引用其他项目及其jar包

    倘若在工作区有两个项目A和B,B项目引用A项目及其jar包(防止调用时A项目的方法出现NoClassFound),步骤如下: 在A项目上点右键看属性,点击Build Path--->Concon ...

  6. 在 Target 中获取项目引用的所有依赖(dll/NuGet/Project)的路径

    原文:在 Target 中获取项目引用的所有依赖(dll/NuGet/Project)的路径 在项目编译成 dll 之前,如何分析项目的所有依赖呢?可以在在项目的 Target 中去收集项目的依赖. ...

  7. cmake配置项目引用动态库

    note 本文将介绍使用FIND_PACKAGE配置项目动态库的方法 cmake version: 3.18 platform: win10 20H2 概述 创建了一个动态库,再由主项目调用该动态库. ...

  8. vue组件如何被其他项目引用

    自己写的vue组件怎么才能让其他人引用呢,或者是共用组件如何让其他项目引用.本文就粗细的介绍下,如有疑问欢迎共同讨论.在这里你能了解下如下知识点: 1. 如何发布一个包到npmjs仓库上 2.如何引用 ...

  9. GZFramwork数据库层《前言》DLL项目引用

    新建项目: 1. 项目引入GZFramwork.dll NuGet地址:Install-Package GZFramwork 每个项目都引用 2.BLL层 设置数据库连接维护类:继承于:GZFramw ...

随机推荐

  1. 52-Linked List Cycle

    Linked List Cycle My Submissions QuestionEditorial Solution Total Accepted: 102785 Total Submissions ...

  2. js浮点运算的坑

    1,js浮点型小数点运算的问题. 这么简单的计算,js竟然算的是错的,究其原因,是因为js小数在内存存储方式的原因. 具体原因: JavaScript 里的数字是采用 IEEE 754 标准的 64 ...

  3. c#GridView

    分页: 1.先把属性AllowPaging设置为true, 2.pagesize为每一页的行数,PageSize="15". 3.OnPageIndexChanging=" ...

  4. Hive(二)【数据类型、类型转换】

    目录 一.基本数据类型 案例实操 二.集合数据类型 案例实操 Map类型 三.类型转换 1.隐式类型转换 2.显示(强制)类型转换 一.基本数据类型 HIVE MySQL JAVA 长度 例子 TIN ...

  5. 对于Linq关键字和await,async异步关键字的扩展使用

    最近在看neuecc大佬写的一些库:https://neuecc.medium.com/,其中对await,async以及linq一些关键字实现了自定义化使用, 使其不需要引用对应命名空间,不需要多线 ...

  6. 寻找pair

    给定n个整数使其两两组合成一对pair,例如给定 1 ,2 可以组成的pair为(1,1),(1,2),(2,1),(2,2),然后在这些pair中寻找第k小的pair. 输入第一行包含两个数字,第一 ...

  7. 【Other】逻辑分析仪的使用(UART、SPI)

    首先上一张接线示意图 上方是UART的接线方式,下方则是SPI的 事实上,这样接就能收到信号了 如果是SPI,要设定自己为主机,UART则没有这个问题 下面来说明逻辑分析仪的界面设定 设定介绍完了 下 ...

  8. 3.3 GO字符串处理

    strings方法 index 判断子字符串或字符在父字符串中出现的位置(索引)Index 返回字符串 str 在字符串 s 中的索引( str 的第一个字符的索引),-1 表示字符串 s 不包含字符 ...

  9. js中获取url参数

    function getUrlVars() { var vars = [], hash; var hashes = window.location.href.slice(window.location ...

  10. 5、Redis五大基本数据类型——String类型

    一.Redis支持数据类型简介 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). 二.String类 ...