requirements()¶
方法 requirements()
用于指定软件包的依赖关系。
def requirements(self):
self.requires("zlib/1.3.1")
对于简单情况,可以使用属性语法,例如 requires = "zlib/1.3.1"
。
依赖特性¶
特性是 require 子句的属性。它们决定了 Conan 如何处理和传播依赖关系的不同部分。特性的值通常由 Conan 根据依赖的 package_type 计算得出,但也可以手动指定。
在 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
将不会被传播,因为“构建”上下文中的头文件和库不能链接到主机上下文中。
run¶
此依赖包含一些可执行文件,可以是应用程序或共享库,它们需要可用于执行(通常在路径或其他系统环境变量中)。当 build=False
时,此特性可以为 True
,在这种情况下,软件包将包含在安装时可以在主机系统上运行的可执行文件,通常类似于最终用户应用程序。当 build=True
时,此特性可以为 True
,软件包将包含在构建环境中运行的可执行文件,通常在用于构建其他软件包时使用。
visible¶
即使此 require
不传播 headers
、libs
或 run
特性,它也会向下游传播。向下游传播的依赖项可能导致版本冲突。此特性通常为 True
,因为在大多数情况下,在同一依赖图中使用同一库的两个不同版本至少很复杂,如果不是直接违反 ODR 或导致链接错误的话。在高级场景中,当我们希望在构建期间使用同一软件包的不同版本时,可以将其设置为 False
。
警告
visible
特性可能会引起冲突,如果一个传递性依赖项对当前配方声明为 visible=False
的相同软件包具有 visible=True
依赖。在这些不同可见性规则作用于同一软件包的情况下,可见的传递性依赖项将被使用并向下游传播。
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
特性仅在您想要覆盖某个传递性依赖的版本,同时不向其添加直接依赖时才有用。
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 命令输出中被标记为“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
的值自动推断。
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