requirements()

requirements() 方法用于指定软件包的依赖项。

def requirements(self):
    self.requires("zlib/1.2.11")

对于简单的情况,可以使用属性语法,例如 requires = "zlib/1.2.11"

Requirement traits(需求特性)

Traits(特性)是 requires 子句的属性。它们决定了依赖项的各个部分如何被 Conan 处理和传播。 traits(特性)的值通常由 Conan 根据依赖项的 package_type 计算,但也可以手动指定。

Conan 2.0 中的高级依赖模型演示文稿中提供了对 traits(特性)的一个很好的介绍。

在下面的示例中,headerslibs 是 traits(特性)。

self.requires("math/1.0", headers=True, libs=True)

headers(头文件)

表明在编译时将从该软件包中 #included 头文件。 该依赖项将在 host 上下文中。

libs(库文件)

依赖项包含一些将在使用者的链接时使用的库或工件。对于直接共享库和静态库,此特性通常为 True,但对于通过共享库使用的间接静态库,该特性可能为 False。 该依赖项将在 host 上下文中。

build(构建)

此依赖项是一个构建工具、应用程序或可执行文件,例如 cmake,它专门在构建时使用。它不会链接/嵌入到二进制文件中,并且将在 build 上下文中。

警告

定义了 build=True 的构建时需求(tool_requiresbuild_requires)旨在与其默认 visible=False 一起使用,并且目前强烈建议将其保留为 visible=False。 如果您认为您可能有一个用例,最好先在 https://github.com/conan-io/conan/issues 中讨论并询问它,而不是尝试启用 visible=True

对于某些非常特殊的情况,对于同时定义 visible=Truebuild=True 的构建/工具要求,存在实验性支持,但它是实验性的,并且可能会在未来的 Conan 版本中发生重大更改。 众所周知,并且设计为不传播所有特性,例如 headers/libs 将不会传播,因为来自“build”上下文的头文件和库文件无法在 host 上下文中链接。

run(运行)

此依赖项包含一些需要执行的可执行文件、应用程序或共享库(通常在路径中或其他系统环境变量中)。 此特性对于 build=False 可以是 True,在这种情况下,该软件包将包含一些在安装时可以在 host 系统中运行的可执行文件,通常像最终用户应用程序一样。 此特性对于 build=True 可以是 True,该软件包将包含一些将在构建上下文中运行的可执行文件,通常在用于构建其他软件包时。

visible(可见)

即使不传播 headerslibsrun 特性,此 require 也将向下游传播。 向下游传播的需求可能会导致版本冲突。 这通常是 True,因为在大多数情况下,在同一依赖关系图中具有同一库的 2 个不同版本至少很复杂,如果不是直接违反 ODR 或导致链接错误。 在高级场景中,当我们希望在构建期间使用同一软件包的不同版本时,可以将其设置为 False

transitive_headers(传递头文件)

如果 True,则依赖项的头文件将在下游可见。 在 头文件传递性教程中阅读有关此特性的更多信息。

transitive_libs(传递库文件)

如果 True,则与依赖项链接的库将在下游可见。

test(测试)

此需求是测试库或框架,例如 Catch2 或 gtest。 它主要是一个需要包含和链接的库,但不会向下游传播。

package_id_mode(package_id 模式)

如果配方想要指定依赖项版本如何影响当前的软件包 package_id,可以直接在此处指定。

虽然也可以在 package_id() 方法中完成,但似乎在 requires 中指定它更简单,同时避免了一些歧义。

# We set the package_id_mode so it is part of the package_id
self.tool_requires("tool/1.1.1", package_id_mode="minor_mode")

这将等效于

def package_id(self):
  self.info.requires["tool"].minor_mode()

force(强制)

requires 将强制其版本在上游依赖关系图中,覆盖其他现有的版本,即使是传递依赖项的版本,并且还解决了潜在的现有冲突。 下游使用者的 force 特性始终具有更高的优先级。

override(覆盖)

force 特性相同,但不添加 direct 依赖项。 **如果没有要覆盖的传递依赖项,则将丢弃此 ``require`` **。 此特性仅在定义 requires 时存在,但一旦完全评估图形,它将不会作为实际的 requires 存在

注意

最佳实践

  • 不建议使用 forceoverride 特性来解决冲突,这仅仅是一种临时的解决方法来解决版本冲突。 应尽可能避免使用它,并且建议更新图形中的版本或版本范围,以避免没有覆盖和强制的冲突。

  • 一个关键的要点是 override 特性不会从您的软件包创建直接依赖项,而 force 特性会。 这意味着 override 特性仅在您想要覆盖其中一个传递依赖项的版本而不添加对其的直接依赖项时才有用。

direct(直接)

如果依赖项是直接依赖项,即它已由当前配方显式声明,或者它是传递依赖项。

options(选项)

可以定义依赖项的选项值作为特性

self.requires("mydep/0.1", options={"dep_option": "value"})

警告

在配方中定义选项值没有很强的保证,请查看 有关依赖项选项值的常见问题解答。 建议的定义选项值的方式是在配置文件中。

no_skip(不跳过)

此特性是 Conan 2.16 中引入的实验性特性,并且可能会发生重大更改。 有关更多信息,请参见 Conan 稳定性部分。

当不需要传递依赖项的软件包二进制文件时,Conan 能够避免下载它们。 例如,如果包含可执行文件的 package_type = "application" 软件包依赖(requires)另一个 package_type = "static-library"(或常规库,但具有选项 shared=False)的软件包,然后,安装应用程序软件包二进制文件不需要静态库依赖项的二进制文件才能工作。 然后,Conan 将“跳过”这些二进制文件的下载,从而节省此类下载和安装的时间和传输成本。 这些二进制文件在 Conan 命令输出中标记为“已跳过的二进制文件”。

The tools.graph:skip_binaries conf 可以更改默认行为,如果 False,它将避免跳过二进制文件,这在某些情况下很有用。

The no_skip=True 特性可以在依赖项中定义,例如:

name = "mypkg"

def requirements(self):
  self.requires("mydep/0.1", no_skip=True)

mypkg 的二进制文件是必需的时,这将强制下载 mydep/0.1 的二进制文件。

注意

最佳实践

no_skip=True 的使用应该是例外情况,仅适用于非常有限和特殊的用例,Conan 默认的“跳过二进制文件”行为应该适用于绝大多数情况。通常,它不会单独使用,但如果与其他特性(例如 visible=False)一起使用则可以。 除非绝对必要,否则避免使用它,它只应在非常特殊的 recipe 中使用。 如果在许多 recipe 中使用,则很可能是一种滥用。

package_type 特性推断

如果没有由 recipe 显式设置,则某些特性会根据 package_type 的值自动推断。

  • application: headers=False, libs=False, run=True

  • shared-library: run=True

  • static-library: run=False

  • header-library: headers=True, libs=False, run=False

  • build-scripts: headers=False, libs=False, run=True, visible=False

此外,还会根据依赖项的 package_type 在上述基础上推断一些其他特性

  • header-library: transitive_headers=True, transitive_libs=True

每种 requires 的默认特性

每种 requires 在上一节所述的基础上,默认设置一些额外的特性。 它们是

  • requires: build=False

  • build_requires: headers=False, libs=False, build=True, visible=False

  • tool_requires: headers=False, libs=False, build=True, run=True, visible=False

  • test_requires: headers=True, libs=True, build=False, visible=False, test=True