cmake:pkg_check_modules
此文为:轻松入门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_PATH
和NO_CMAKE_ENVIRONMENT_PATH
,也是可选的
- 默认情况下,CMAKE_PREFIX_PATH、CMAKE_FRAMEWORK_PATH和CMAKE_APPBUNDLE_PATH缓存和环境变量将被添加到pkg-config搜索路径。
- 如果填写了这两个参数,
NO_CMAKE_PATH
和NO_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相关推荐
- CMake:安装自己编写的动态库,报错
CMake:安装自己编写的动态库,报错"file INSTALL cannot copy file" 具体情况如下: 原因: 权限问题. 安装共享库有时需要root密码,执行sud ...
- 【C++】mingw32-make+cmake:error: ‘nullptr‘ was not declared in this scope解决方法
###问题 使用cmake成功(Configuring done Generating done)后,在cmd终端中执行 mingw32-make报错: error: 'nullptr' was no ...
- Linux 7 cmake:curses library not found
CentOS7 上面安装MySQL5.7出现以下问题: Curses library not found. Please install appropriate package 解决方法: # yum ...
- cmake:add_library生成静态库和动态库
此文为:轻松入门cmake系列教程 有时我们只需要编译出动态库,静态库,然后等着让其它程序去使用.让我们看下这种情况该如何使用cmake 实验 实验一:生成静态库 编写代码 项目结构如下: [CMak ...
- CMake:aux_source_directory
aux_source_directory 查找在某个路径下的所有源文件. aux_source_directory(< dir > < variable >) 具体用法: au ...
- cmake:命令行工具cmake
概要 Generate a Project Buildsystemcmake [<options>] <path-to-source>cmake [<options> ...
- cmake:macro、endmacro
macro 开始记录一个宏,以便以后作为命令调用 macro(<name> [<arg1> ...])<commands> endmacro() 定义了一个名为&l ...
- cmake:gcc-stack-protector
gcc-stack-protector 以堆栈溢出为代表的缓冲区溢出已成为最为普遍的安全漏洞,由此引发的安全问题比比皆是.我们知道攻击者利用堆栈溢出漏洞时,通常会破坏当前的函数栈. 那有没有一种机制来 ...
- 【Linux杂学】CMake:编写 CMakeLists
[CMake官网]:掌握CMake 1.变量 CMake 变量名称区分大小写,且只能包含字母数字字符和下划线 CMAKE_ 变量[存储均为字符串]是CMake 自定义变量,命名应避开 set 可设变量 ...
最新文章
- 实例教程一:电话拨号器
- 使用IntelliJ IDEA开发SpringMVC网站(一)开发环境
- SAP物料移动类型和自动科目设置(包含财务,pp)
- python restful服务部署_用python为mysql实现restful接口
- ImagesLazyLoad 图片延迟加载效果
- 5个趣味Python练手项目
- python url解析path_Django(CBV解析、模板层)
- 人工智能作业考试汇总
- 去找工作还要先交押金我认为不太靠谱
- power supply surges detected
- 汽车驾驶 - 道路交通标线和标志
- 自动化测试 (二) 连连看外挂
- Dubbo thread pool is exhausted
- 【计算机网络】谢希仁笔记 应用层
- 坐标转换(像素转换米)
- 深入理解生成对抗网络(GAN 基本原理,训练崩溃,训练技巧,DCGAN,CGAN,pix2pix,CycleGAN)
- 小根堆创建,插入,删除,排序等操作图解
- Java基于opencv—矫正图像
- 【软件工具类】常用科研办公软件工具汇总
- 2021 各式免費 sorce code final