通过“find_package"获取导入的目标? [英] Getting imported targets through `find_package`?

查看:25
本文介绍了通过“find_package"获取导入的目标?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Qt 5的CMake手册使用find_package 并说:

为每个 Qt 模块创建导入的目标.应首选导入的目标名称,而不是在 target_link_libraries 等 CMake 命令中使用 Qt5_LIBRARIES 等变量.

Imported targets are created for each Qt module. Imported target names should be preferred instead of using a variable like Qt5<Module>_LIBRARIES in CMake commands such as target_link_libraries.

它是 Qt 专用的还是 find_package 为所有库生成导入目标?CMake 3.0 中find_package 的文档 说:

Is it special for Qt or does find_package generate imported targets for all libraries? The documentation of find_package in CMake 3.0 says:

当找到包时,包特定的信息通过包本身记录的变量和导入目标提供.

When the package is found package-specific information is provided through variables and Imported Targets documented by the package itself.

以及 cmake-packages 手册 说:

使用 find_package 的结果要么是一组 IMPORTED 目标,要么是一组与构建相关信息相对应的变量.

The result of using find_package is either a set of IMPORTED targets, or a set of variables corresponding to build-relevant information.

但我没有看到另一个 FindXXX.cmake 脚本,其中文档说创建了一个导入的目标.

But I did not see another FindXXX.cmake-script where the documentation says that a imported target is created.

推荐答案

find_package 这几天是个双头野兽:

find_package is a two-headed beast these days:

CMake 直接支持两种形式的包,配置文件包查找模块包

CMake provides direct support for two forms of packages, Config-file Packages and Find-module Packages

来源

现在,这究竟意味着什么?

Now, what does that actually mean?

查找模块包可能是您最熟悉的包.他们执行 CMake 代码的脚本(例如 这个)它对 find_library 等函数进行了大量调用find_path找出图书馆的位置.

Find-module packages are the ones you are probably most familiar with. They execute a script of CMake code (such as this one) that does a bunch of calls to functions like find_library and find_path to figure out where to locate a library.

这种方法的一大优点是它非常通用.只要文件系统上有东西,我们就可以找到它.最大的缺点是它通常提供的信息比该东西的物理位置多一点.也就是说,查找模块操作的结果通常只是一堆文件系统路径.这意味着建模诸如传递依赖或多个构建配置之类的东西相当困难.

The big advantage of this approach is that it is extremely generic. As long as there is something on the filesystem, we can find it. The big downside is that it often provides little more information than the physical location of that something. That is, the result of a find-module operation is typically just a bunch of filesystem paths. This means that modelling stuff like transitive dependencies or multiple build configurations is rather difficult.

如果您要查找的东西本身是用 CMake 构建的,这将变得特别痛苦.在这种情况下,您已经在构建脚本中建模了一堆东西,您现在需要为 find 脚本精心重构这些内容,以便下游项目可以使用它.

This becomes especially painful if the thing you are trying to find has itself been built with CMake. In that case, you already have a bunch of stuff modeled in your build scripts, which you now need to painstakingly reconstruct for the find script, so that it becomes available to downstream projects.

这是配置文件包的亮点.与 find-modules 不同,运行脚本的结果不仅仅是一堆路径,而是创建功能齐全的 CMake 目标.对于依赖项目,这些依赖关系似乎是作为同一个项目的一部分构建的.

This is where config-file packages shine. Unlike find-modules, the result of running the script is not just a bunch of paths, but it instead creates fully functional CMake targets. To the dependent project it looks like the dependencies have been built as part of that same project.

这允许以非常方便的方式传输更多信息.明显的缺点是配置文件脚本比查找脚本复杂得多.因此,您不想自己编写它们,而是让 CMake 为您生成它们.或者更确切地说,依赖项提供一个配置文件作为其部署的一部分,然后您可以简单地使用 find_package 调用加载它.而这正是 Qt5 所做的.

This allows to transport much more information in a very convenient way. The obvious downside is that config-file scripts are much more complex than find-scripts. Hence you do not want to write them yourself, but have CMake generate them for you. Or rather have the dependency provide a config-file as part of its deployment which you can then simply load with a find_package call. And that is exactly what Qt5 does.

这也意味着,如果您自己的项目是库,请考虑 生成配置文件作为构建过程的一部分.这不是 CMake 最直接的功能,但结果非常强大.

This also means, if your own project is a library, consider generating a config file as part of the build process. It's not the most straightforward feature of CMake, but the results are pretty powerful.

以下是两种方法在 CMake 代码中的典型外观的快速比较:

Here is a quick comparison of how the two approaches typically look like in CMake code:

查找模块样式

find_package(foo)
target_link_libraries(bar ${FOO_LIBRARIES})
target_include_directories(bar ${FOO_INCLUDE_DIR})
# [...] potentially lots of other stuff that has to be set manually

配置文件样式

find_package(foo)
target_link_libraries(bar foo)
# magic!

tl;dr:如果依赖项提供了配置文件包,则始终首选配置文件包.如果没有,请改用查找脚本.

tl;dr: Always prefer config-file packages if the dependency provides them. If not, use a find-script instead.

这篇关于通过“find_package"获取导入的目标?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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