5.cmake导入第三方库

使用第三方库有两种方式,一种是使用cmake文件导入的方式,另一种是使用pc文件导入的方式

cmake文件导入

cmake文件查找

使用findPackage函数来查找cmake文件并执行cmake文件的代码,查找cmake文件的方式有两种,一种是Config模式,一种是Module模式

Config模式

这种模式一般是由第三方库自己生成的cmake文件,直接使用就行了
cmake文件的搜索路径 <lib_name>_DIRCMAKE_CMAKE_PREFIX_PATH
cmake文件的文件名是<lib_name>Config.cmake<lib_name>-config.cmake

使用方法:

list(APPEND CMAKE_CMAKE_PREFIX_PATH "<lib_name>Config.cmake文件所在目录")
或
set(<lib_name>_DIR "<lib_name>Config.cmake文件所在目录")
#1.单模块
find_package(<lib_name> [version] [EXACT] [QUIET] [MODULE])#包名
#2.多模块
find_package(<lib_name> [version] [EXACT] [QUIET] [MODULE] #包名
             [REQUIRED] [[COMPONENTS] [components...]] #模块名
             [OPTIONAL_COMPONENTS components...]
             [NO_POLICY_SCOPE])

在后面的《cmake安装》这里会介绍单模块和多模块cmake文件的生成和安装方法

Module模式

这种模式一般是由于第三方库自己没有生成cmake文件,需要自己手动写cmake文件
cmake文件的搜索路径为CMAKE_MODULE_PATH
cmake文件的文件名是Find<lib_name>.cmake

使用方法:

  1. 在最外层的CMakeLists.txt文件所在的目录创建cmake文件夹
  2. 在cmake文件夹下添加Find<lib_name>.cmake文件
  3. 在最外层的CMakeLists.txt文件中添加如下代码
    list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") #添加cmake文件夹到CMAKE_MODULE_PATH变量中
    find_package(<lib_name> [version] [EXACT] [QUIET] [MODULE])
    

cmake文件内容

cmake文件的代码的目的是获得第三方库的属性,并能够被创建的目标使用,属性包括库文件路径,头文件路径等等

获取第三方库属性

find_path文档:https://cmake.org/cmake/help/v3.19/command/find_path.html?highlight=find_path

# 搜索头文件路径,如果(搜索目录/suffix)目录下存在name的头文件,则VAR变量设置为(搜索目录/suffix)
find_path(<VAR>
   name | NAMES name1 [name2 ...]  #查找的头文件名称,可以带目录如XX/YY.h
   [HINTS path1 [path2 ... ENV var]] #在默认路径前搜索的目录
   [PATHS path1 [path2 ... ENV var]] #在默认路径后搜索的目录
   [PATH_SUFFIXES suffix1 [suffix2 ...]]) #搜索目录=搜索目录/suffix

VAR变量的名称一般设置为<lib_name>_INCLUDE_DIRS

find_library文档:https://cmake.org/cmake/help/v3.19/command/find_library.html?highlight=find_library

# 搜索头文件路径,如果(搜索目录/suffix)目录下存在lib<name>.so的库文件,则VAR变量设置为(搜索目录/suffix)
find_library (<VAR>
	name | NAMES name1 [name2 ...] [NAMES_PER_DIR] #查找的库文件名称
	[HINTS path1 [path2 ... ENV var]] #在默认路径前搜索的目录
	[PATHS path1 [path2 ... ENV var]] #在默认路径后搜索的目录
	[PATH_SUFFIXES suffix1 [suffix2 ...]]) #搜索目录=搜索目录/suffix
VAR变量的名称一般设置为<lib_name>_LIBRARIES

判断是否查找成功

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(<PackageName>
  [FOUND_VAR <result-var>] #如果required-var都有定义,result-var设置成TRUE,否则设置FALSE
  [REQUIRED_VARS <required-var>...])

required-var配置上面的两个变量名
result-var的名称一般设置成<lib_name>_FOUND

输出第三方库属性

为了之后创建的目标能够使用这些属性,有两种方式来输出这些属性,一种是把这些属性设置到变量中,另一种是创建IMPRTED类型的目标,并把这些属性设置到目标的属性中

设置变量
#设置这些变量为缓存变量,即是全局变量
mark_as_advanced([CLEAR|FORCE] <var1> ...)

上面一步已经将属性设置到变量中了,新创建的目标可以使用
target_link_libraries(<target_name> <lib_name>_LIBRARIES)来链接第三方库的库文件
target_include_directories(<target_name> <lib_name>_INCLUDE_DIRS)来使用第三方库的头文件

创建IMPRTED类型目标
if(<lib_name>_FOUND AND NOT TARGET <lib_name>) #头文件目录和库文件目录都找到了
    add_library(<lib_name> UNKNOWN IMPORTED) #创建IMPRTED类型目标
    set_target_properties(<lib_name> PROPERTIES
                IMPORTED_LOCATION "${<lib_name>_LIBRARIES}"
                INTERFACE_INCLUDE_DIRECTORIES "${<lib_name>_INCLUDE_DIRS}") #设置头文件目录和库文件目录到目标的属性中
endif()

新创建的目标可以使用
target_link_libraries(<target_name> <lib_name>)来链接第三方库的库文件和使用第三方库的头文件

pc导入

# 创建IMPRTED类型目标
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
      pkg_check_modules(<lib_name> QUIET IMPORTED_TARGET <pc_name>) 
      if(<lib_name>_FOUND)
         #创建了一个名为PkgConfig::<lib_name>的IMPRTED类型目标,与上面一样处理就行
      endif()
   endif()
endif()
pkg_check_modules:在/usr/local/lib/pkgconfig或/usr/lib/pkgconfig目录下查找名为<pc_name>.pc的文件解析库文件位置,头文件位置以及依赖库的名称,并输出这些属性到IMPRTED类型目标<lib_name>中


# 输出到变量
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
      pkg_check_modules(<lib_name> QUIET <pc_name>) 
      if(<lib_name>_FOUND)
         #输出到变量中,与上面一样处理就行
      endif()
   endif()
endif()
pkg_check_modules:在/usr/local/lib/pkgconfig或/usr/lib/pkgconfig目录下查找名为<pc_name>.pc的文件解析库文件位置,头文件位置以及依赖库的名称,并输出这些属性到变量中
库文件路径:<lib_name>_LIBRARIES
头文件路径: <lib_name>_INCLUDE_DIRS

pc文件内容解析

prefix=/usr/local/ffmpeg  #库的安装根目录
exec_prefix=${prefix} #执行文件的安装路径,通常与prefix相同
libdir=${exec_prefix}/lib #库文件所在的目录
includedir=${prefix}/include #头文件所在的目录

Name: libavformat  #库文件的名称
Description: A simple example library #描述
Version: 1.0.0
Requires: zib yaml-cpp  #依赖的库名称,会继续寻找这些依赖库的pc文件
Cflags: -I${includedir}  #编译参数
Libs: -L${libdir} -lavformat #链接参数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值