使用 `cmake` 中的 `pkg-config` 的正确方法是什么? [英] What is the proper way to use `pkg-config` from `cmake`?

查看:52
本文介绍了使用 `cmake` 中的 `pkg-config` 的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在网上找了很多这样的代码:

Looking around on the net I have seen a lot of code like this:

include(FindPkgConfig)
pkg_search_module(SDL2 REQUIRED sdl2)

target_include_directories(app SYSTEM PUBLIC ${SDL2_INCLUDE_DIRS})
target_link_libraries(app ${SDL2_LIBRARIES})

然而,这似乎是错误的做法,因为它只使用包含目录和库,而忽略了定义、库路径和其他可能由 pkg-config 返回的标志.

However that seems to be the wrong way about doing it, as it only uses the include directories and libraries, but ignored defines, library paths and other flags that might be returned by pkg-config.

执行此操作并确保pkg-config 返回的所有编译和链接标志都被编译后的app 使用的正确方法是什么?是否有一个命令可以完成此操作,即诸如 target_use(app SDL2) 之类的东西?

What would be the correct way to do this and ensure that all compile and link flags returned by pkg-config are used by the compiled app? And is there a single command to accomplish this, i.e. something like target_use(app SDL2)?

参考:

推荐答案

如果您以非常正常的方式使用 cmake 和 pkg-config,则此解决方案有效.

If you're using cmake and pkg-config in a pretty normal way, this solution works.

但是,如果您的库存在于某个开发目录(例如/home/me/hack/lib)中,则使用此处看到的其他方法无法配置链接器路径.在典型安装位置下找不到的库会导致链接器错误,例如 /usr/bin/ld: cannot find -lmy-hacking-library-1.0.此解决方案修复了这种情况下的链接器错误.

If, however, you have a library that exists in some development directory (such as /home/me/hack/lib), then using other methods seen here fail to configure the linker paths. Libraries that are not found under the typical install locations would result in linker errors, like /usr/bin/ld: cannot find -lmy-hacking-library-1.0. This solution fixes the linker error for that case.

另一个问题可能是 pkg-config 文件没有安装在正常位置,需要在 cmake 运行时使用 PKG_CONFIG_PATH 环境变量添加项目的 pkg-config 路径(请参阅有关此的其他堆栈溢出问题).当您使用正确的 pkg-config 路径时,此解决方案也很有效.

Another issue could be that the pkg-config files are not installed in the normal place, and the pkg-config paths for the project need to be added using the PKG_CONFIG_PATH environment variable while cmake is running (see other Stack Overflow questions regarding this). This solution also works well when you use the correct pkg-config path.

使用IMPORTED_TARGET 是解决上述问题的关键.此解决方案是对 此早期答案 的改进,归结为可运行的 CMakeLists.txt 的最终版本:

Using IMPORTED_TARGET is key to solving the issues above. This solution is an improvement on this earlier answer and boils down to this final version of a working CMakeLists.txt:

cmake_minimum_required(VERSION 3.14)
project(ya-project C)

# the `pkg_check_modules` function is created with this call
find_package(PkgConfig REQUIRED) 

# these calls create special `PkgConfig::<MODULE>` variables
pkg_check_modules(MY_PKG REQUIRED IMPORTED_TARGET any-package)
pkg_check_modules(YOUR_PKG REQUIRED IMPORTED_TARGET ya-package)

add_executable(program-name file.c ya.c)

target_link_libraries(program-name PUBLIC
        PkgConfig::MY_PKG
        PkgConfig::YOUR_PKG)

请注意,target_link_libraries 不仅仅是更改链接器命令.它还传播指定目标的其他 PUBLIC 属性,如编译器标志、编译器定义、包含路径等,因此,请谨慎使用 PUBLIC 关键字.

Note that target_link_libraries does more than change the linker commands. It also propagates other PUBLIC properties of specified targets like compiler flags, compiler defines, include paths, etc., so, use the PUBLIC keyword with caution.

这篇关于使用 `cmake` 中的 `pkg-config` 的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆