cmake之引入外部项目(引用其他项目)、FetchContent管理子模块(fetchcontent用法)
本文CMAKE版本为3.18
演示环境: Windows+CMake+VS2017
源码下载说明
- 演示代码是后来传上去的,而且做了些修改,将spdlog_demo由exe改为了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;
}
参考
cmake之引入外部项目(引用其他项目)、FetchContent管理子模块(fetchcontent用法)的更多相关文章
- Java web项目引用java项目,类型找不到
Java web项目引用java项目,类型找不到 错误信息: java.lang.ClassNotFoundException: org.codehaus.jackson.map.ObjectMapp ...
- web项目引用Java项目,连接报错error HTTP Status 500 - Servlet execution threw an exception
错误信息 项目背景: 一个web项目引用一个java Project,项目中添加了引用,但是打开页面访问,总报500错误.提示:servlet初始化错误. 环境:Eclipse luna JDK: 1 ...
- Eclipse web项目引用其它项目时的部署问题
地址:http://blog.csdn.net/testcs_dn/article/details/43764497
- Android 如何在Eclipse 引入外部纯Java项目(不是打成Jar使用)
应用情景--如标题: 在Eclipse的 “Android启动项目”中引入“外部的纯Java项目”,能运行的只有是基于Android的测试代码才可以. 一直很纳闷,如果外部写好一个Java插件(例如服 ...
- MyEclipse 引用其他项目及其jar包
倘若在工作区有两个项目A和B,B项目引用A项目及其jar包(防止调用时A项目的方法出现NoClassFound),步骤如下: 在A项目上点右键看属性,点击Build Path--->Concon ...
- 在 Target 中获取项目引用的所有依赖(dll/NuGet/Project)的路径
原文:在 Target 中获取项目引用的所有依赖(dll/NuGet/Project)的路径 在项目编译成 dll 之前,如何分析项目的所有依赖呢?可以在在项目的 Target 中去收集项目的依赖. ...
- cmake配置项目引用动态库
note 本文将介绍使用FIND_PACKAGE配置项目动态库的方法 cmake version: 3.18 platform: win10 20H2 概述 创建了一个动态库,再由主项目调用该动态库. ...
- vue组件如何被其他项目引用
自己写的vue组件怎么才能让其他人引用呢,或者是共用组件如何让其他项目引用.本文就粗细的介绍下,如有疑问欢迎共同讨论.在这里你能了解下如下知识点: 1. 如何发布一个包到npmjs仓库上 2.如何引用 ...
- GZFramwork数据库层《前言》DLL项目引用
新建项目: 1. 项目引入GZFramwork.dll NuGet地址:Install-Package GZFramwork 每个项目都引用 2.BLL层 设置数据库连接维护类:继承于:GZFramw ...
随机推荐
- 常见 js 数组方法使用详解
数组常用方法总结 concat filter map some every reduce sort includes join some every 语法:array.every(function(c ...
- FESTUNG 模型介绍 — 2. 对流问题隐式求解
FESTUNG 模型介绍 - 2. 对流问题隐式求解 1. 控制方程 对流问题的控制方程为 \[\partial_t C + \partial_x u^1 C + \partial_y u^2 C = ...
- DAS,NAS,SAN,简介
根据服务器类型分为:封闭系统的存储和开放系统的存储,封闭系统主要指大型机,开放系统指基于Windows.UNIX.Linux等操作系统的服务器;开放系统的存储分为:内置存储和外挂存储;外挂存储根据连接 ...
- [R] read.table/read.delim读入数据行数变少?
以为对read.table/read.delim很熟了,谁知又掉坑里了. 我有个3万多行的数据集,包括样品表达量和注释信息.大概长这样: 本来3万多行,可是读进来的时候变成了1万多行,而且read.d ...
- nginx 文件目录页面
开启文件目录 server { listen 80; #设置自己静态目录的访问域名 server_name xxx.xxxx.com; #防止页面中文乱码一定要在utf-8前面加上gbk,顺序很重要 ...
- EXCEL-批量下拉填充
3.批量下拉填充 => 全选->Ctrl+G定位空值->随意找一个空白单元格输入=还有此单元格想要填充的内容->按Ctrl+Enter,等待几秒,即可,批量下拉填充:
- java中接口可以继承接口
今天阅读别人的代码才发现,接口是可以继承接口的 一个类只能extends一个父类,但可以implements多个接口. 一个接口则可以同时extends多个接口,却不能implements任何接口. ...
- == 和 equals() 方法的区别
== 在比较基本数据类型时,是比较两边的数据的值是否相等 // 整数类型 int num1 = 1; // 双精度浮点数类型 double num2 = 1.0; // 输出结果为 true Syst ...
- Java日期格式转换不用发愁
前言 Java 中日期.时间相关的类相当的多,并且分不同的版本提供了不同的实现,包括 Date . Calendar . LocalDateTime . ZoneDateTime . OffsetDa ...
- 容器之分类与各种测试(四)——unordered-multiset
unordered-multiset是不定序关联式容器,其底部是通过哈希表实现功能. (ps:黑色框就是bucket,白色框即为bucket上挂载的元素) 为了提高查找效率,bucket(篮子)的数量 ...