此文为:轻松入门cmake系列教程

理论

是什么?

pkg_check_modules是 CMake 自己的 pkg-config 模块的一个用来简化的封装:你不用再检查 CMake 的版本,加载合适的模块,检查是否被加载,等等,参数和传给 find_package 的一样:先是待返回变量的前缀,然后是包名(pkg-config 的)。这样就定义了<prefix>_INCLUDE_DIRS和其他的这类变量,后续的用法就与find_package一致。

工作原理

当安装某些库时(例如从RPM,deb或其他二进制包管理系统),会包括一个后缀名为 pc 的文件,它会放入某个文件夹下(依赖于系统设置,例如,Linux 为该库文件所在文件夹/lib/pkgconfig),并把该子文件夹加入pkg-config的环境变量PKG_CONFIG_PATH作为搜索路径。

pkg_check_modules实质上是检测系统中的 pkg-config 是否存在指定的 .pc 文件。

关于PKG_CONFIG_PATH

会在目录${PKG_CONFIG_PATH}寻找.pc文件

在环境变量中设置

执行echo $PKG_CONFIG_PATH

echo $PKG_CONFIG_PATH


解决:
1、查看自己的 pkgconfig 路径在哪里

find / -name pkgconfig


可以看出有三个,随意选择一个就可以

2、设置路径

export PKG_CONFIG_PATH=/usr/lib64/pkgconfig/:$PKG_CONFIG_PATH

在cmakelists.txt中设置

set(ENV{PKG_CONFIG_PATH}${CMAKE_SOURCE_DIR}/libs/lib/pkgconfig:/opt/ffmpeg/lib/pkgconfig:$ENV{PKG_CONFIG_PATH})

what is the difference between find_package and pkg_search_module

  • pkg_search_module使用pkg-config工具确定请求的库的位置。这在已经使用pkg-config的系统上最有用,因此您不需要为CMake复制所有信息。请注意,此方法存在潜在的可移植性问题,因为它要求在构建计算机上正确设置pkg-config。

  • 另一方面,find_package是CMake自己解决相同问题的机制。为此,您可能需要一个用于请求的库的CMake查找脚本(CMake已经附带了其中的两个,但您可以轻松编写自己的脚本),或者是由请求的库本身提供的软件包配置脚本。无论哪种情况,您都可能需要调整CMAKE_MODULE_PATH才能使CMake能够找到相应的脚本。

使用哪种选择非常简单:

  • 如果库提供的话,优先选择软件包配置脚本。
  • 使用查找脚本作为不了解CMake的库的后备。
  • 如果要利用pkg-config的协同作用,请使用pkg_search_module。特别是,请注意,可以使用pkg_search_module来实现查找脚本,作为获取所需信息的一种方法。

使用示例

find_package(PkgConfig REQUIRED)pkg_check_modules(LIBUV REQUIRED libuv)
set(NETDATA_COMMON_CFLAGS ${NETDATA_COMMON_CFLAGS} ${LIBUV_CFLAGS_OTHER})
set(NETDATA_COMMON_LIBRARIES ${NETDATA_COMMON_LIBRARIES} ${LIBUV_LIBRARIES})
set(NETDATA_COMMON_INCLUDE_DIRS ${NETDATA_COMMON_INCLUDE_DIRS} ${LIBUV_INCLUDE_DIRS})

前提:安装了libuv,并且将libuv.pc复制到了/usr/lib64/pkgconfig/路径下。否则出错: – Checking for module ‘libuv’
– No package ‘libuv’ found

官网翻译

官方文档

FindPkgConfig

CMake的pkg-config模块。

找到pkg-config可执行文件并添加pkg_get_variable()、pkg_check_modules()和pkg_search_module()命令。以下变量也将被设置:

  • PKG_CONFIG_FOUND:是否找到pkg-config可执行文件
  • PKG_CONFIG_EXECUTABLE:pkg-config程序的路径
  • PKG_CONFIG_VERSION_STRING:pkg-config版本(自CMake 2.8.8以来)

pkg_check_modules

检查所有给定的模块,在调用范围内设置各种结果变量

pkg_check_modules(<prefix>[REQUIRED] [QUIET][NO_CMAKE_PATH][NO_CMAKE_ENVIRONMENT_PATH][IMPORTED_TARGET [GLOBAL]]<moduleSpec> [<moduleSpec>...])

(0)<prefix>。举个例子

pkg_check_modules(SDL2 IMPORTED_TARGET  sdl2)
  • 意思是:

    • 我们要去默认路径下找叫做sdl2模块的库
    • 如果找到了,就生成一个叫做PkgConfig:SDL2的导入目标,这个目标可以直接用到target_link_libraries语句中
    • pkg_check_modules(....)执行完毕之后,会生成如下变量(SDL2就是<prefix>,可以自己起一个容易记住的名字,随便起):
SDL2_FOUND:如果模块存在,则设置为1
SDL2_LIBRARIES:只有库(没有“-l”)
SDL2_LINK_LIBRARIES:库及其绝对路径
SDL2_LIBRARY_DIRS:库的路径(没有“-L”)
SDL2_LDFLAGS:所有必需的链接器标志
.....
  • 然后,我们就可以这样利用了
pkg_check_modules(SDL2  IMPORTED_TARGET sdl2)
if (SDL2_FOUND)include_directories(${SDL2_INCLUDE_DIRS})link_directories(${SDL2_LIBRARY_DIRS})list(APPEND LINK_LIB_LIST ${SDL2_LIBRARIES})target_link_libraries(${PROJECT_NAME}  PkgConfig::SDL2)message(STATUS "found library:${SDL2_LIBRARIES}")
endif ()

再举个例子,如下:

pkg_check_modules(ffmpeg REQUIRED IMPORTED_TARGET libavcodec libavformat libavutil)
  • 去默认路径下,libavcodec libavformat libavutil这三个库,如果都找到了,那么,会生成如下变量:
ffmpeg_FOUND:如果模块存在,则设置为1
ffmpeg_LIBRARIES:只有库(没有“-l”)
......

(1) REQUIRED:可选。意为“必须”

  • 如果找不到模块,命令将失败并报错,并停止运行
  • 如果不选择,那么没有找到这个模块,那么就跳过

(2)QUIET:也是可选的。意为“安静”,当填写此参数,将会静默输出,不会打印任何信息
(3)NO_CMAKE_PATHNO_CMAKE_ENVIRONMENT_PATH,也是可选的

  • 默认情况下,CMAKE_PREFIX_PATH、CMAKE_FRAMEWORK_PATH和CMAKE_APPBUNDLE_PATH缓存和环境变量将被添加到pkg-config搜索路径。
  • 如果填写了这两个参数,NO_CMAKE_PATHNO_CMAKE_ENVIRONMENT_PATH参数就不去缓存路径和环境变量路径中搜索了

(4)[IMPORTED_TARGET [GLOBAL]]

  • IMPORTED_TARGET参数将创建一个名为PkgConfig::< prefix>的导入目标,该目标可以作为参数直接传递给target_link_libraries()。
  • GLOBAL参数将使导入的目标在全局作用域中可用。

(5)< moduleSpec >

  • 每个< moduleSpec >可以是裸模块名,也可以是带有版本约束的模块名(支持运算符=、<、>、<=和>=)。以下是具有各种约束的名为foo的模块的示例:

    • Foo匹配任何版本。
    • Foo <2只匹配2之前的版本。
    • Foo >=3.1匹配3.1或更高版本的任何版本。
    • Foo =1.2.3要求Foo必须是1.2.3版本。

(6)返回值
返回时可以设置以下变量。存在两组值:一组用于普通情况(< XXX > = < prefix>),另一组用于pkg-config在使用——static选项调用时提供的信息(< XXX > = < prefix>_STATIC)。

< XXX > _FOUND:如果模块存在,则设置为1
< XXX > _LIBRARIES:只有库(没有“-l”)
< XXX > _LINK_LIBRARIES:库及其绝对路径
< XXX > _LIBRARY_DIRS:库的路径(没有“-L”)
< XXX > _LDFLAGS:所有必需的链接器标志
< XXX > _LDFLAGS_OTHER:所有其他链接器标志
< XXX > _INCLUDE_DIRS:预处理器标记’-I’(没有’-I’)
< XXX > _CFLAGS:所有必需的cflags
< XXX > _CFLAGS_OTHER:其他编译器标志
< YYY > _VERSION:模块版本
< YYY > _PREFIX:模块的前缀目录
< YYY > _INCLUDEDIR:包含模块的目录
< YYY > _LIBDIR:模块的Lib目录

例子:

pkg_check_modules(ffmpeg REQUIRED IMPORTED_TARGET libavcodec libavformat libavutil)target_link_libraries(${PROJECT_NAME} PRIVATE PkgConfig::ffmpeg)

例子:

pkg_check_modules (GLIB2 glib-2.0)

查找任何版本的glib2。如果找到,输出变量GLIB2_VERSION将保存找到的实际版本。

pkg_check_modules (GLIB2 glib-2.0>=2.10)

查找glib2至少2.10版本。如果找到,输出变量GLIB2_VERSION将保存找到的实际版本。

pkg_check_modules (FOO glib-2.0>=2.10 gtk+-2.0)

查找glib2-2.0(至少2.10版本)和gtk2±2.0的任何版本。只有当两者都被找到时,才会认为FOO被找到。FOO_glib-2.0_VERSION和FOO_gtk±2.0_VERSION变量将被设置为它们各自找到的模块版本。

pkg_check_modules (XRENDER REQUIRED xrender)

这句话的意思是“你可以去路径中找xrender这个库,任何版本都可以”。如果能够找到,那么就会设置宏XRENDER_LIBRARIES,XRENDER_STATIC_LIBRARIES。举个例子 :

XRENDER_LIBRARIES=Xrender;X11
XRENDER_STATIC_LIBRARIES=Xrender;X11;pthread;Xau;Xdmcp

pkg_search_module

此命令的行为与pkg_check_modules()相同,不同之处是它只搜索第一个成功匹配的模块,而不是检查所有指定的模块。

pkg_search_module(<prefix>[REQUIRED] [QUIET][NO_CMAKE_PATH][NO_CMAKE_ENVIRONMENT_PATH][IMPORTED_TARGET [GLOBAL]]<moduleSpec> [<moduleSpec>...])

3.16新版功能:如果找到一个模块,< prefix >_MODULE_NAME变量将包含匹配模块的名称。如果需要运行pkg_get_variable(),可以使用这个变量。

例子:

pkg_search_module (BAR libxml-2.0 libxml2 libxml>=2)

pkg_get_variable

3.4新版功能。

检索pkg-config变量varName的值,并将其存储在调用范围内的结果变量resultVar中。

pkg_get_variable(<resultVar> <moduleName> <varName>)

如果pkg-config返回指定变量的多个值,resultVar将包含一个;-list。

例如:

pkg_get_variable(GI_GIRDIR gobject-introspection-1.0 girdir)

cmake:pkg_check_modules相关推荐

  1. CMake:安装自己编写的动态库,报错

    CMake:安装自己编写的动态库,报错"file INSTALL cannot copy file" 具体情况如下: 原因: 权限问题. 安装共享库有时需要root密码,执行sud ...

  2. 【C++】mingw32-make+cmake:error: ‘nullptr‘ was not declared in this scope解决方法

    ###问题 使用cmake成功(Configuring done Generating done)后,在cmd终端中执行 mingw32-make报错: error: 'nullptr' was no ...

  3. Linux 7 cmake:curses library not found

    CentOS7 上面安装MySQL5.7出现以下问题: Curses library not found. Please install appropriate package 解决方法: # yum ...

  4. cmake:add_library生成静态库和动态库

    此文为:轻松入门cmake系列教程 有时我们只需要编译出动态库,静态库,然后等着让其它程序去使用.让我们看下这种情况该如何使用cmake 实验 实验一:生成静态库 编写代码 项目结构如下: [CMak ...

  5. CMake:aux_source_directory

    aux_source_directory 查找在某个路径下的所有源文件. aux_source_directory(< dir > < variable >) 具体用法: au ...

  6. cmake:命令行工具cmake

    概要 Generate a Project Buildsystemcmake [<options>] <path-to-source>cmake [<options> ...

  7. cmake:macro、endmacro

    macro 开始记录一个宏,以便以后作为命令调用 macro(<name> [<arg1> ...])<commands> endmacro() 定义了一个名为&l ...

  8. cmake:gcc-stack-protector

    gcc-stack-protector 以堆栈溢出为代表的缓冲区溢出已成为最为普遍的安全漏洞,由此引发的安全问题比比皆是.我们知道攻击者利用堆栈溢出漏洞时,通常会破坏当前的函数栈. 那有没有一种机制来 ...

  9. 【Linux杂学】CMake:编写 CMakeLists

    [CMake官网]:掌握CMake 1.变量 CMake 变量名称区分大小写,且只能包含字母数字字符和下划线 CMAKE_ 变量[存储均为字符串]是CMake 自定义变量,命名应避开 set 可设变量 ...

最新文章

  1. 实例教程一:电话拨号器
  2. 使用IntelliJ IDEA开发SpringMVC网站(一)开发环境
  3. SAP物料移动类型和自动科目设置(包含财务,pp)
  4. python restful服务部署_用python为mysql实现restful接口
  5. ImagesLazyLoad 图片延迟加载效果
  6. 5个趣味Python练手项目
  7. python url解析path_Django(CBV解析、模板层)
  8. 人工智能作业考试汇总
  9. 去找工作还要先交押金我认为不太靠谱
  10. power supply surges detected
  11. 汽车驾驶 - 道路交通标线和标志
  12. 自动化测试 (二) 连连看外挂
  13. Dubbo thread pool is exhausted
  14. 【计算机网络】谢希仁笔记 应用层
  15. 坐标转换(像素转换米)
  16. 深入理解生成对抗网络(GAN 基本原理,训练崩溃,训练技巧,DCGAN,CGAN,pix2pix,CycleGAN)
  17. 小根堆创建,插入,删除,排序等操作图解
  18. Java基于opencv—矫正图像
  19. 【软件工具类】常用科研办公软件工具汇总
  20. 2021 各式免費 sorce code final

热门文章

  1. vue3项目将图片正时针、逆时针旋转
  2. 数字用计算机写大写,微信小程序学习用:大写计算器;数字转换为大写
  3. 干货!ERP系统优化生产管理流程五大步骤
  4. 数据的写出(FileWriter)
  5. 电子学会2020年9月青少年软件编程(图形化)等级考试试卷(一级)答案解析
  6. 量子计算机当游戏服务器,为何需要量子计算机
  7. Unity发布内嵌网页的PC客户端
  8. spring boot拦截器 过滤器
  9. UR机器人PolyScope使用入门教程
  10. PS一次性导出多倍图@1x、@2x、@3x