requirements()

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

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

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

依赖项特征

特征是 requires 子句的属性。它们决定了 Conan 如何处理和传播依赖项的各个部分。特征值通常由 Conan 基于依赖项的 package_type 计算得出,但也可以手动指定。

关于特征的良好介绍可以在 Conan 2.0 中的高级依赖模型 演示文稿中找到。

在下面的示例中 headerslibs 是特征。

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

headers

表示在编译时将从此包中 #include 的头文件。依赖项将位于主机上下文中。

libs

依赖项包含将在消费者链接时使用的库或工件。此特征通常对于直接共享和静态库为 True,但对于通过共享库使用的间接静态库,则可能为 false。依赖项将位于主机上下文中。

build

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

警告

定义 build=True 的构建时依赖项(tool_requiresbuild_requires)设计为使用其默认的 visible=False,并且目前强烈建议将其保持为 visible=False。如果您认为您可能有用例,最好先在 https://github.com/conan-io/conan/issues 上讨论并询问,而不是尝试启用 visible=True

对于一些非常特殊的情况,存在对具有 build=Truevisible=True 的构建/工具需求的实验性支持,但实验性且可能在未来的 Conan 版本中发生破坏性更改。 众所周知,它也设计为不传播所有特征,例如 headers/libs 将不会被传播,因为“构建”上下文中的头文件和库无法链接到主机上下文中。

run

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

visible

即使它不传播 headerslibsrun 特征,此 require 也会向下游传播。向下游传播的依赖项可能导致版本冲突。这通常为 True,因为在大多数情况下,在同一个依赖图中拥有 2 个不同版本的同一个库至少是复杂的,如果直接违反 ODR 或导致链接错误。

警告

如果传递依赖项具有对与当前配方声明为 visible=False 的相同包的 visible=True 要求,则 visible 特征可能会创建冲突。在不同的可见性规则到达同一个包的情况下,可见的传递依赖项将被使用并向下游传播。

transitive_headers

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

transitive_libs

如果为 True,则依赖项的用于链接的库将向下游可见。

test

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

package_id_mode

如果配方想要指定依赖项版本如何影响当前包的 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" 包包含一个可执行文件,依赖于另一个包,该包是 package_type = "static-library"(或常规库,但选项 shared=False),那么安装应用程序包二进制文件不需要静态库依赖项的二进制文件即可工作。Conan 随后将“跳过”下载这些二进制文件,从而节省下载和安装的时间和传输成本。这些二进制文件在 Conan 命令输出中标记为“跳过的二进制文件”。

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

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)一起使用。

package_type 特征推断

如果未由配方显式设置,则某些特征会根据依赖项的 package_type 自动推断。

注意

libsheadersvisible 特征默认设置为 True,除非在下面显示的列表中另有说明,或者用户手动将其设置为 False

推断规则是

  • 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

这意味着,如果在您的配方中,您有 self.requires("mypkg/1.0"),并且 mypkg/1.0 具有 package_type="application",那么该 requires 的有效特征将是 headers=Falselibs=Falserun=True。这些然后可以通过在 requires 中显式设置它们来覆盖。

此外,基于您的配方的 package_type,还会推断一些额外的特征

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

这意味着,如果您的包是 header-library,那么它的所有要求默认情况下都将具有 transitive_headers=Truetransitive_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

例如,考虑到所有逻辑,这意味着如果在您的库中,其 package_type="header-library",并且您有一个如下形式的依赖项 self.requires("mypkg/1.0"),而 mypkg/1.0 具有 package_type="shared-library",那么该 requires 的有效特性将是

  • mypkgpackage_type 推断得出:run=True

  • 从您的包的 package_type 推断得出:transitive_headers=Truetransitive_libs=True

  • 通过 requires 类型:build=False

  • 默认情况下:headers=Truelibs=True