requirements()¶
requirements() 方法用于指定包的依赖项。
def requirements(self):
self.requires("zlib/1.3.1")
对于简单的情况,可以使用属性语法,例如 requires = "zlib/1.3.1"。
依赖项特性¶
特性是 requires 子句的属性。它们决定了 Conan 如何处理和传播依赖项的各个部分。特性的值通常由 Conan 基于依赖项的 package_type 计算得出,但也可以手动指定。
Conan 2.0 中的高级依赖项模型 (Advanced Dependencies Model in Conan 2.0) 演示文稿提供了对特性的良好介绍。
在下面的示例中,headers 和 libs 是特性。
self.requires("math/1.0", headers=True, libs=True)
headers¶
指示在此包中存在将在编译时通过 #include 引用的头文件。依赖项将处于 host 上下文中。
libs¶
依赖项包含将在使用者链接时使用的库或构件。此特性对于直接共享库和静态库通常为 True,但对于通过共享库使用的间接静态库可能为 False。依赖项将处于 host 上下文中。
build¶
此依赖项是构建工具、应用程序或可执行文件,例如 cmake,仅在构建时使用。它不会链接/嵌入到二进制文件中,并将处于 build 上下文中。
警告
定义了 build=True 的构建时依赖项(tool_requires、build_requires)被设计为与它们的默认 visible=False 一起工作,并且目前强烈建议将其保持为 visible=False。如果您认为您可能有某种用例,最好先在 https://github.com/conan-io/conan/issues 上讨论并询问,而不是尝试启用 visible=True。
对于一些非常特殊的情况,存在对具有 build=True 的构建/工具依赖项的**实验性**支持,这些依赖项也定义了 visible=True,但这是实验性的,并且可能会在未来的 Conan 版本中发生破坏性更改。它也被已知并设计为不传播所有特性,例如,headers/libs 不会被传播,因为来自“build”上下文的头文件和库不能在 host 上下文中链接。
run¶
此依赖项包含一些可执行文件,无论是应用程序还是共享库,这些都需要可用才能执行(通常在 PATH 或其他系统环境变量中)。此特性对于 build=False 可以是 True,在这种情况下,包将包含一些可在安装时在 host 系统上运行的可执行文件,通常类似于最终用户应用程序。此特性对于 build=True 可以是 True,包将包含在 build 上下文中运行的可执行文件,通常在使用它来构建其他包时。
visible¶
此 require 将向下游传播,即使它不传播 headers、libs 或 run 特性。会传播的依赖项可能导致版本冲突。这通常是 True,因为在大多数情况下,在同一个依赖关系图中存在同一库的 2 个不同版本至少会很复杂,如果不直接违反 ODR 或导致链接错误的话。在高级场景中,可以将其设置为 False,当我们想在构建期间使用同一包的不同版本时。
警告
如果传递依赖项有一个 visible=True 的需求,而当前配方将其声明为 visible=False,那么 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 存在。
注意
最佳实践
不建议将
force和override特性作为通用的版本控制解决方案来解决冲突,仅作为解决版本冲突的临时变通方法。应尽可能避免使用它们,而推荐的方法是更新图中的版本或版本范围以在不使用 override 和 force 的情况下避免冲突。一个关键的收获是,
override特性不会从您的包创建直接依赖项,而force特性则会。这意味着override特性仅在您想覆盖传递依赖项的版本而不添加直接依赖项时才有用。
direct¶
如果依赖项是直接的,即它已由当前配方显式声明,或者它是传递的。
options¶
可以定义依赖项的选项值作为特性
self.requires("mydep/0.1", options={"dep_option": "value"})
警告
在配方中定义选项值没有严格的保证,请检查 关于依赖项选项值的 FAQ。定义选项值的推荐方法是在配置文件中。
no_skip¶
此特性是 Conan 2.16 中引入的**实验性**功能,并可能发生破坏性更改。有关更多信息,请参阅 Conan 稳定性 部分。
Conan 能够避免下载传递依赖项的包二进制文件,当它们不需要时。例如,如果一个 package_type = "application" 包(其中包含一个可执行文件)依赖(requires)另一个 package_type = "static-library"(或常规库,但选项 shared=False)的包,那么安装应用程序包二进制文件就不需要静态库依赖项的二进制文件来工作。Conan 随后会“跳过”这些二进制文件的下载,从而节省下载和安装的时间和传输成本。这些二进制文件在 Conan 命令输出中标记为“Skipped binaries”。
tools.graph:skip_binaries 配置可以更改默认行为,如果设置为 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 值自动推断的,如果配方没有明确设置的话。
注意
除非在下面列出的列表中另有说明,或者用户手动将它们设置为 False,否则 libs、headers 和 visible 特性默认设置为 True。
推断规则如下:
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=False, libs=False, run=True。这些随后可以通过在 requires 中显式设置来覆盖。
此外,基于您的配方的 package_type,会推断出一些额外的特性。
header-library:transitive_headers=True,transitive_libs=True
这意味着,如果您的包是 header-library,那么它所有的依赖项将默认具有 transitive_headers=True 和 transitive_libs=True。
每种 require 类型的默认特性¶
每种 require 类型都会在上一节所述特性的基础上,另外设置一些默认特性。它们是:
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 的有效特性将是:
从
mypkg的package_type推断:run=True从您的包的
package_type推断:transitive_headers=True,transitive_libs=True根据
requires类型:build=False默认:
headers=True,libs=True