CMake manual of Qt 5使用find_package
并说:
为每个Qt模块创建导入的目标。应首选导入的目标名称,而不是在CMake命令(如target_link_libraries)中使用
Qt5<Module>_LIBRARIES
之类的变量。
Qt是特殊的还是find_package
为所有库生成导入的目标? documentation of find_package
in CMake 3.0说:
当找到包时,通过变量和包本身记录的导入目标提供特定于包的信息。
使用
find_package
的结果可以是一组IMPORTED目标,也可以是与构建相关信息对应的一组变量。
但我没有看到另一个FindXXX.cmake
- 脚本,其中文档说明已创建导入的目标。
答案 0 :(得分:15)
find_package
这几天是双头野兽:
CMake为两种形式的包提供直接支持,Config-file Packages 和Find-module Packages
现在,这究竟意味着什么?
查找模块包是您可能最熟悉的。他们执行一个CMake代码脚本(例如this one),它对find_library
和find_path
等函数进行大量调用,以找出库的位置。
这种方法的一大优点是它非常通用。只要文件系统上有东西,我们就可以找到它。最大的缺点是它通常提供的信息比那个东西的物理位置要多得多。也就是说,查找模块操作的结果通常只是一堆文件系统路径。这意味着对传递依赖或多个构建配置等建模相当困难。
如果您要查找的内容本身是使用CMake构建的,那么这将变得特别痛苦。在这种情况下,您已经在构建脚本中建立了大量的东西,现在您需要为find脚本进行艰苦的重构,以便下游项目可以使用。
这是配置文件包闪耀的地方。与find-modules不同,运行脚本的结果不仅仅是一堆路径,而是创建了功能齐全的CMake目标。对于依赖项目,看起来依赖项已构建为同一项目的一部分。
这允许以非常方便的方式传输更多信息。明显的缺点是配置文件脚本比查找脚本复杂得多。因此,您不想自己编写它们,但让CMake为您生成它们。或者更确切地说,依赖项提供配置文件作为其部署的一部分,然后您可以通过find_package
调用加载。这正是Qt5所做的。
这也意味着,如果您自己的项目是图书馆,请考虑generating a config file as part of the build process。这不是CMake最直接的功能,但结果非常强大。
以下是CMake代码中两种方法的典型比较:
查找模块样式
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 :如果依赖项提供配置文件包,则总是更喜欢它们。如果没有,请改用find-script。
答案 1 :(得分:2)
实际上find_package
的结果没有“魔力”:此命令只搜索相应的FindXXX.cmake
脚本并执行它。
如果Find脚本设置XXX_LIBRARY
变量,则调用者可以使用此变量。
如果“查找”脚本创建导入的目标,则调用者可以使用这些目标。
如果查找脚本既没有设置 XXX_LIBRARY
变量也没有创建导入的目标......那么,脚本的使用在某种程度上是不同的。
find_package
的文档描述了查找脚本的常用用法。但无论如何,您需要查阅有关具体脚本的文档(此文档通常包含在脚本本身中)。