【cmake】pkg_check_modules 使用详解

pkg_check_modules 主要通过 .pc 文件引入整个库,该命令会解析指定的 .pc 文件,并将所需的编译和链接信息提取到 CMake 变量中,以便后续使用。


目录

[1、pkg_check_modules 的检索目录](#1、pkg_check_modules 的检索目录)

[2、pkg_check_modules 语法格式](#2、pkg_check_modules 语法格式)

[3、应用:pkg_check_modules 引入 libavfilter.pc](#3、应用:pkg_check_modules 引入 libavfilter.pc)

[3.1 使用 IMPORTED_TARGETS](#3.1 使用 IMPORTED_TARGETS)

[3.2 不使用 IMPORTED_TARGETS](#3.2 不使用 IMPORTED_TARGETS)


1、pkg_check_modules 的检索目录

一般情况下,pkg_check_modules 会在默认路径(标准路径)下寻找对应的 pc 文件,如 /usr/lib/pkgconfig、/usr/local/lib/pkgconfig,如果 .pc 文件位于非标准位置,可以通过设置 PKG_CONFIG_PATH环境变量来告诉 pkg-config 查找 .pc 文件的路径。

php 复制代码
# ffmpeg 的pc文件位置:${PROJECT_SOURCE_DIR}/3rdparty/ffmpeg/lib/pkgconfig
# 系统环境变量:PKG_CONFIG_PATH
# 格式: set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:<pc文件位置>")
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${PROJECT_SOURCE_DIR}/3rdparty/ffmpeg/lib/pkgconfig")

2、pkg_check_modules 语法格式

pkg_check_modules使用方法和 find_package 类似,基本语法如下:

php 复制代码
pkg_check_modules(<PREFIX> REQUIRED|QUIET|OPTIONAL [IMPORTED_TARGETS] <modules>...)

① <PREFIX>

相当于为后续要引入的库起一个别名,这个别名会被用于多个地方,最典型的就是Cmake变量,头文件路径会被保存到 XXX_INCLUDE_DIRS,库文件路径会被保存到 XXX_LIB,而这里的 <PREFIX> 则用于替换变量中的 XXX

② REQUIRED | QUIT | OPTIONAL

此处有三个可选项,每个可选项的意义如下:

  • REQUIRED:表示该软件包是必需的,如果找不到将会导致配置错误
  • QUIT:表示即使找不到也不会产生错误,只是输出一条警告
  • OPTIONAL:表示查找不到软件包也不会产生错误,且不会输出任何信息。

③ [IMPORTED_TARGETS]

可选参数,指定是否应该为该软件包创建 IMPORTED 目标,如果指定了此参数,CMake 将会为该软件包创建一个 IMPORTED 目标,我们可以在后续的 CMake 文件中使用这个目标来链接该软件包。

主要体现在链接到目标文件的时候可以采用如下方式,下面的 <PREFIX> 对应pkg_check_modules的第一个参数

php 复制代码
target_link_libraries(${PROJECT_NAME} PRIVATE
    PkgConfig::<PREFIX>
}

④ modules

要查询的软件包名称,通常是在系统上安装的软件包的名字。假设要查找 libavcodec.pc 文件,那么这里填入的就是 libavcodec。pkg_check_modules一次可以查找多个pc文件,如

php 复制代码
pkg_check_modules(Avfilter REQUIRED IMPORTED_TARGET 
    libavcodec 
    libavdevice 
    libavfilter
)

3、应用:pkg_check_modules 引入 libavfilter.pc

下面介绍两种,一种是使用了 IMPORTED_TARGETS 选项,一种是不使用IMPORTED_TARGETS选项。二者的区别在于链接到目标文件的方式不同,寻找 pc 文件的方式是几乎一样的。

3.1 使用 IMPORTED_TARGETS

寻找 pc 文件:

php 复制代码
# 添加检索路径
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${PROJECT_SOURCE_DIR}/3rdparty/ffmpeg/lib/pkgconfig")
# 查找 pc 文件
find_package(PkgConfig REQUIRED)
pkg_check_modules(Avfilter REQUIRED IMPORTED_TARGET libavfilter) # 使用 IMPORTED_TARGETS
if(Avfilter_FOUND)
    message(STATUS "found avfilter")
    message(STATUS "    - avfilter include directories: ${Avfilter_INCLUDE_DIRS}")
    message(STATUS "    - avfilter libraries directories: ${Avfilter_LIBRARY_DIRS}")
    message(STATUS "    - avfilter libraries: ${Avfilter_LIBRARIES}")
    include_directories(${Avfilter_INCLUDE_DIRS})
    link_directories(${Avfilter_LIBRARY_DIRS})
else()
    message(FATAL_ERROR "avfilter not found")
endif()

链接到目标文件:

php 复制代码
add_executable(${PROJECT_NAME} ${ALL_SRCS})
target_link_libraries(${PROJECT_NAME} PRIVATE
    PkgConfig::Avfilter       
) # 这里的Avfilter是pkg_check_modules的第一个参数

3.2 不使用 IMPORTED_TARGETS

寻找 pc 文件

php 复制代码
# 添加检索路径
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${PROJECT_SOURCE_DIR}/3rdparty/ffmpeg/lib/pkgconfig")
# 查找 pc 文件
find_package(PkgConfig REQUIRED)
pkg_check_modules(Avfilter REQUIRED libavfilter) # 不使用 IMPORTED_TARGETS
if(Avfilter_FOUND)
    message(STATUS "found avfilter")
    message(STATUS "    - avfilter include directories: ${Avfilter_INCLUDE_DIRS}")
    message(STATUS "    - avfilter libraries directories: ${Avfilter_LIBRARY_DIRS}")
    message(STATUS "    - avfilter libraries: ${Avfilter_LIBRARIES}")
    include_directories(${Avfilter_INCLUDE_DIRS})
    link_directories(${Avfilter_LIBRARY_DIRS})
else()
    message(FATAL_ERROR "avfilter not found")
endif()

链接到目标文件:

php 复制代码
add_executable(${PROJECT_NAME} ${ALL_SRCS})
target_link_libraries(${PROJECT_NAME} PRIVATE
    ${Avfilter_LIBRARIES}
)
相关推荐
电星托马斯2 小时前
C++中顺序容器vector、list和deque的使用方法
linux·c语言·c++·windows·笔记·学习·程序人生
march_birds7 小时前
FreeRTOS 与 RT-Thread 事件组对比分析
c语言·单片机·算法·系统架构
小麦嵌入式7 小时前
Linux驱动开发实战(十一):GPIO子系统深度解析与RGB LED驱动实践
linux·c语言·驱动开发·stm32·嵌入式硬件·物联网·ubuntu
jelasin8 小时前
LibCoroutine开发手记:细粒度C语言协程库
c语言
篝火悟者8 小时前
自学-C语言-基础-数组、函数、指针、结构体和共同体、文件
c语言·开发语言
神里流~霜灭10 小时前
蓝桥备赛指南(12)· 省赛(构造or枚举)
c语言·数据结构·c++·算法·枚举·蓝桥·构造
双叶83610 小时前
(C语言)单链表(1.0)(单链表教程)(数据结构,指针)
c语言·开发语言·数据结构·算法·游戏
艾妮艾妮11 小时前
C语言常见3种排序
java·c语言·开发语言·c++·算法·c#·排序算法
charlie11451419112 小时前
STM32F103C8T6单片机硬核原理篇:讨论GPIO的基本原理篇章1——只讨论我们的GPIO简单输入和输出
c语言·stm32·单片机·嵌入式硬件·gpio·数据手册
矿渣渣12 小时前
int main(int argc, char **argv)C语言主函数参数解析
c语言·开发语言