以下内容的完整演示代码请参考我的github项目https://github.com/BrightXiaoHan/CMakeTutorial​github.com

本节主要介绍如何引入外部项目源码作为自己项目的Library。与FindPackage引入头文件编译好的库不同的是,本节介绍的方法直接将第三方库源码引入到项目中,编译自己的项目时也会连同第三方库的源码一同编译。特别是当我们使用git等工具引入代码时,我们可以很方便地控制第三方代码的版本,防止本地安装的库文件版本与项目存在冲突。下面我们逐一介绍引入外部项目的几种方式,并对比他们的优劣。(以spdlog为例)

通过Submodle的方式引入

克隆spdlog作为项目的子项目

git submodule add https://github.com/gabime/spdlog.git

切换到我们需要的版本

git checkout v1.4.2

我们已经clone好了,现在只需要将spdlog作为subdirectory加入CMakeLists.txt当中就行了

project(ImportExternalProject)cmake_minimum_required(VERSION 3.5)add_definitions(-std=c++11) # 指定采用c++11进行编译(spdlog需要c++11)add_subdirectory(spdlog)

在编译时下载项目并引入

首先新建cmake目录,在目录下创建spdlog.cmake并加入以下内容

include(ExternalProject)set(SPDLOG_ROOT ${CMAKE_BINARY_DIR}/thirdparty/SPDLOG)set(SPDLOG_GIT_TAG v1.4.1) # 指定版本set(SPDLOG_GIT_URL https://github.com/gabime/spdlog.git) # 指定git仓库地址set(SPDLOG_CONFIGURE cd ${SPDLOG_ROOT}/src/SPDLOG && cmake -D CMAKE_INSTALL_PREFIX=${SPDLOG_ROOT} .) # 指定配置指令(注意此处修改了安装目录,否则默认情况下回安装到系统目录)set(SPDLOG_MAKE cd ${SPDLOG_ROOT}/src/SPDLOG && make) # 指定编译指令(需要覆盖默认指令,进入我们指定的SPDLOG_ROOT目录下)set(SPDLOG_INSTALL cd ${SPDLOG_ROOT}/src/SPDLOG && make install) # 指定安装指令(需要覆盖默认指令,进入我们指定的SPDLOG_ROOT目录下)ExternalProject_Add(SPDLOG

PREFIX ${SPDLOG_ROOT}

GIT_REPOSITORY ${SPDLOG_GIT_URL}

GIT_TAG ${SPDLOG_GIT_TAG}

CONFIGURE_COMMAND ${SPDLOG_CONFIGURE}

BUILD_COMMAND ${SPDLOG_MAKE}

INSTALL_COMMAND ${SPDLOG_INSTALL}

)# 指定编译好的静态库文件的路径set(SPDLOG_LIB ${SPDLOG_ROOT}/lib/spdlog/libspdlog.a)# 指定头文件所在的目录set(SPDLOG_INCLUDE_DIR ${SPDLOG_ROOT}/include)

需要注意的是,我们此处指定了配置、编译、安装的指令,如果不这样做的话,cmake默认将编译好的库和头文件安装在系统目录,而我们希望他安装在build目录下的指定位置。最后我们设置了静态库文件的位置和头文件所在目录,这样我们在CMakeLists.txt中就可以通过target_link_libraries和target_include_directories进行引用了。

project(ImportExternalProject)cmake_minimum_required(VERSION 3.5)add_definitions(-std=c++11) # 指定采用c++11进行编译(spdlog需要c++11)add_executable(test_spdlog testspdlog.cc)set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}")include(spdlog)target_link_libraries(test_spdlog ${SPDLOG_LIB})target_include_directories(test_spdlog PRIVATE ${SPDLOG_INCLUDE_DIR})

使用FetchContent (CMake 3.11+)

细心的朋友已经发现了,上述使用ExternalProject_Add的方式引入spdlog是在编译时进行的,也就是说在Configure过程中我们并没有从git上下载项目,这就导致我们无法像submodule那样直接通过add_subdirectory引入项目,而是要预先定义好编译后库文件和头文件的位置,通过target_link_libraries和target_include_directories进行引入。在cmake3.11以及以上的版本,cmake又为我们提供了一种Configure过程引入外部项目的方法--FetchContent。

使用FetchContent的步骤总结起来就是:使用FetchContent_Declare(MyName) 获取项目。可以是一个URL也可以是一个Git仓库。

使用FetchContent_GetProperties(MyName) 获取我们需要的变量MyName_*。

使用add_subdirectory(${MyName_SOURCE_DIR} ${MyName_BINARY_DIR})引入项目。

在cmake3.14版本,官方又为我们提供了更方便的FetchContent_MakeAvailable方法,将步骤2,3集成在了一起。为了兼容3.11版本,我们可以把它封装成一个宏,这样我们就可以统一使用FetchContent_MakeAvailable方法了。

# Campatible with cmake 3.11 and above.macro(FetchContent_MakeAvailable NAME)FetchContent_GetProperties(${NAME})if(NOT ${NAME}_POPULATED) FetchContent_Populate(${NAME}) add_subdirectory(${${NAME}_SOURCE_DIR} ${${NAME}_BINARY_DIR})endif()endmacro()macro(FetchContent_MakeAvailable NAME) FetchContent_GetProperties(${NAME}) if(NOT ${NAME}_POPULATED) FetchContent_Populate(${NAME}) add_subdirectory(${${NAME}_SOURCE_DIR} ${${NAME}_BINARY_DIR}) endif()endmacro()

与前面类似,我们在cmake目录下新建spdlog2.cmake,使用FetchContent引入spdlog

# 添加第三方依赖包include(FetchContent)# FetchContent_MakeAvailable was not added until CMake 3.14if(${CMAKE_VERSION} VERSION_LESS 3.14) include(add_FetchContent_MakeAvailable.cmake)endif()set(SPDLOG_GIT_TAG v1.4.1) # 指定版本set(SPDLOG_GIT_URL https://github.com/gabime/spdlog.git) # 指定git仓库地址FetchContent_Declare(

spdlog

GIT_REPOSITORY ${SPDLOG_GIT_URL}

GIT_TAG ${SPDLOG_GIT_TAG}

)FetchContent_MakeAvailable(spdlog)

在CMakeLists.txt中,包含cmake/spdlog2.cmake,便可将spdlog作为library来使用了(主义cmake最小版本应当设置为3.11)

project(ImportExternalProject)cmake_minimum_required(VERSION 3.11)add_definitions(-std=c++11) # 指定采用c++11进行编译(spdlog需要c++11)add_executable(test_spdlog testspdlog.cc)set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}")include(spdlog2)target_link_libraries(test_spdlog PRIVATE spdlog)

import是引进外部函数吗_CMake之引入外部项目的三种方法相关推荐

  1. C语言中比较大小的函数模板,关于C++中定义比较函数的三种方法

    关于C++中定义比较函数的三种方法 C++擅长面向对象程序设计的同时,还可以进行基于过程的程序设计,因而C++就适应的问题规模而论,大小由之.以下,小编为大家介绍关于C++中定义比较函数的三种方法,供 ...

  2. html函数splice,js数组的常用函数(slice()和splice())和js引用的三种方法总结—2019年1月16日...

    总结: slice()和splice() slice(参数1,参数2)可以查找数组下对应的数据,参数1为起始位置,参数2为结束位置,参数2可以为负数,-1对应的是从后向前数的第一个数值.splice( ...

  3. python导入模块的三种方法,例子: import numpy和from numpy import * (import matplotlib 和 from matplotlib import *)

    python导入模块有如下几种写法:以matplotlib为例 (跟numpy是一样的) 1,import matplotlib #整个导入matplotlib 2 , from matplotlib ...

  4. js中当等于最小值是让代码不执行_网页中JS函数自动执行常用三种方法

    本文为大家分享了在网页中JS函数自动执行常用方法,供大家参考,具体内容如下 一.JS方法 1.最简单的调用方式,直接写到html的body标签里面: 2.在JS语句调用: function myfun ...

  5. C语言函数怎么像python那样返回多个值?(三种方法:1、设置全局变量 2、传递指针 3、使用结构体返回不同类型的数据)

    引用文章:c语言函数可不可以返回多个值 文章目录 方法一:设置全局变量 例如:利用一个函数求出正方形的周长和面积. 方法二:使用数组名或指针作为函数的形参 实例2:编写函数求一维整形数组的最大值与最小 ...

  6. python调用matlab函数_从 Python 调用 MATLAB 函数的三种方法

    0. 实验环境Ubuntu 16.04 Matlab R2015b 1. 借助于 mlab 库 安装方法非常简单,只需一行命令 sudo pip install mlab 即可. import num ...

  7. 【数学知识】三种方法求 [1,n] 中所有数欧拉函数(线性筛欧拉函数优化至 O(n) )

    整理的算法模板合集: ACM模板 ①直接求小于或等于n,且与n互质的数个数(求[1,n]中所有数的欧拉函数时间复杂度:O(nn)O(n\sqrt{n})O(nn​)) ②求[1,n]之间每个数的质因数 ...

  8. 在网页中JS函数自动执行常用三种方法

    <SCRIPT   LANGUAGE="JavaScript">   functionn MyAutoRun() {   //以下是您的函数的代码,请自行修改先! al ...

  9. php 快速排序函数,PHP实现快速排序算法的三种方法

    摘要:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序 ...

最新文章

  1. 基于jquery仿天猫分类导航banner切换
  2. AJAX(一)XMLHttpRequest
  3. docker 与tomcat整合
  4. C++归并排序递归写法
  5. SM13: 分析SAP事务提交时的FM调用
  6. 为企业选择最合适的SSL证书
  7. python 爬取生意参谋数据_如何爬取生意参谋数据?是不是违规操作?
  8. LeetCode-75. 颜色分类(荷兰国旗问题)
  9. i = i++ 计算过程还不会?C/C++ 的输出语句与Java 有何不同?
  10. tomcat jdbc数据库连接池详解之PoolCleaner
  11. mixamo骨骼_UE4骨骼重定向(二)借助插件Mixamo Converter快速操作Mixamo网站资源
  12. 按键精灵移动端系列 - IOS(苹果版)安装1.3.8 deb 下载地址
  13. Jetson Xavier NX 套件将系统装到SSD
  14. CMU-MOSEI数据集解读
  15. python实现自动答题详解含代码
  16. Transformer解读之:Transformer 中的 Attention 机制
  17. 安搭Share :青藏高原发现10万年前古人类DNA
  18. 年终盘点丨2022边缘计算大事记
  19. 02华为大数据HCIE_Data Mining 数学基础 测试一下
  20. 如何使用网页在线打开.Xmind文件(思维导图文件)和建模文件(.SLDPRT文件和.SLDASM文件)

热门文章

  1. 现代软件工程_团队项目_阿尔法阶段_现有功能汇总_2018.01.04
  2. 带列表写入文件出错先 json.dumps
  3. swfupload使用说明
  4. [转载]linux 出现: Starting MySQL.Manager of pid-file quit without updating file.[FAILED] 已解决...
  5. Flutter Duration详细概述
  6. Codewars-Regex validate PIN code(正则检验PIN码)
  7. 爬虫之操作excel
  8. inotify和epoll
  9. 朴素贝叶斯(Naive Bayesian)
  10. 六时出行 App 隐私政策