cmake:pkg_check_modules 刺骨的言语ヽ痛彻心扉 2022-12-31 02:26 139阅读 0赞 > 此文为:[轻松入门cmake系列教程][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 ![在这里插入图片描述][2020122721333262.png] 解决: 1、查看自己的 pkgconfig 路径在哪里 find / -name pkgconfig ![在这里插入图片描述][20201227214249200.png] 可以看出有三个,随意选择一个就可以 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],并且将`libuv.pc`复制到了`/usr/lib64/pkgconfig/`路径下。否则出错: – Checking for module ‘libuv’ – No package ‘libuv’ found # 官网翻译 # [官方文档][Link 1] ## 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>...]) * 当给出REQUIRED参数时,如果找不到模块,命令将失败并报错。 * 当给出QUIET参数时,不会打印任何状态消息。 * 3.1新版功能:CMAKE\_PREFIX\_PATH、CMAKE\_FRAMEWORK\_PATH和CMAKE\_APPBUNDLE\_PATH缓存和环境变量将被添加到pkg-config搜索路径。`NO_CMAKE_PATH`和`NO_CMAKE_ENVIRONMENT_PATH`参数分别禁用缓存变量和环境变量的这种行为。将PKG\_CONFIG\_USE\_CMAKE\_PREFIX\_PATH变量设置为FALSE将全局禁用此行为。 * 版本3.6中的新功能:`IMPORTED_TARGET`参数将创建一个名为PkgConfig::< prefix>的导入目标,该目标可以作为参数直接传递给target\_link\_libraries()。 * 3.13新版功能:`GLOBAL`参数将使导入的目标在全局作用域中可用。 * 每个< moduleSpec >可以是裸模块名,也可以是带有版本约束的模块名(支持运算符=、<、>、<=和>=)。以下是具有各种约束的名为foo的模块的示例: * Foo匹配任何版本。 * Foo <2只匹配2之前的版本。 * Foo >=3.1匹配3.1或更高版本的任何版本。 * Foo =1.2.3要求Foo必须是1.2.3版本。 返回时可以设置以下变量。存在两组值:一组用于普通情况(< 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;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]: https://blog.csdn.net/zhizhengguan/article/details/107034372 [2020122721333262.png]: /images/20221120/a68ac5829c1242c0b19580768ad4c25a.png [20201227214249200.png]: https://img-blog.csdnimg.cn/20201227214249200.png [libuv]: https://blog.csdn.net/zhizhengguan/article/details/111678847 [Link 1]: https://cmake.org/cmake/help/v3.21/module/FindPkgConfig.html?highlight=pkg_check_modules#command:pkg_check_modules
还没有评论,来说两句吧...