属性¶
包引用¶
配方属性,可以定义主要的 pkg/version@user/channel 包引用。
名称¶
包的名称。有效的名称全部为小写,并且具有
至少 2 个字符,最多 101 个字符(尽管建议使用较短的名称)。
- 匹配以下正则表达式
^[a-z0-9_][a-z0-9_+.-]{1,100}$:因此以字母数字或_开头, 然后是 1 到 100 个字符,这些字符介于字母数字、
_、+、.或-之间。
- 匹配以下正则表达式
- 仅当在本地缓存中导出配方时(
export、export-pkg 和
create命令),并且未在命令行中使用--name=<pkgname>定义时,才需要名称。
版本¶
包的版本。有效的版本遵循与 name 属性相同的规则。如果版本遵循语义化版本形式 X.Y.Z-pre1+build2,则该值可用于通过版本范围而不是精确版本来要求此包。
仅当在本地缓存中导出配方时(export、export-pkg 和 create 命令),并且未在命令行中使用 --version=<pkgversion> 定义时,版本才严格必要。
可以使用命令行动态定义 version,也可以在配方中使用 set_version() 方法 以编程方式定义。
用户¶
有效的 user 字段字符串遵循与 name 属性相同的规则。这是一个可选属性。它可以用于使用 pkg/version@user/channel 标识您自己的包,其中 user 可以是您的团队、组织或公司的名称。ConanCenter 配方没有 user/channel,因此它们仅采用 pkg/version 形式。您还可以使用用户作为 pkg/version@user 为您的包命名,而无需用户和通道,或仅使用用户。
可以使用命令行指定用户:--user=<myuser>
通道¶
有效的 channel 字段字符串遵循与 name 属性相同的规则。这是一个可选属性。有时用于标识包的成熟度(“稳定”、“测试”……),但通常这没有必要,并且最好将包的成熟度管理到不同的服务器存储库中。
可以使用命令行指定通道:--channel=<mychannel>。如果指定了通道,则还必须指定用户,因此包引用始终完整为 pkg/version@user/channel。
元数据¶
可选元数据,例如许可协议、描述、作者等。对于大多数情况来说不是必需的,但可能很有用。
描述¶
这是一个可选但推荐的文本字段,包含包的描述以及对消费者可能任何有用的信息。第一行可以用作包的简短描述。
class HelloConan(ConanFile):
name = "hello"
version = "0.1"
description = """This is a Hello World library.
A fully featured, portable, C++ library to say Hello World in the stdout,
with incredible iostreams performance"""
许可协议¶
目标源代码和二进制文件的许可协议,即正在打包的代码,而不是 conanfile.py 本身。可以包含多个逗号分隔的许可协议。这是一个文本字符串,因此可以包含任何文本,但强烈建议开源项目的配方使用 SPDX 标识符来自 SPDX 许可列表
这将帮助希望自动执行许可协议兼容性检查的人员,例如您的包的消费者,或者如果您的包具有开源依赖项,则可以帮助您。
class Pkg(ConanFile):
license = "MIT"
主题¶
用于将相关包分组在一起并描述代码内容。用作 ConanCenter 中的搜索过滤器。可选属性。它应该是一个字符串元组。
class ProtocInstallerConan(ConanFile):
name = "protoc_installer"
version = "0.1"
topics = ("protocol-buffers", "protocol-compiler", "serialization", "rpc")
主页¶
正在打包的库的主页。
用于将配方链接到有关库本身的进一步说明,例如其功能的概述、文档、常见问题解答以及其他相关信息。
class EigenConan(ConanFile):
name = "eigen"
version = "3.3.4"
homepage = "http://eigen.tuxfamily.org"
网址¶
包存储库的 URL,即不一定是原始源代码的 URL。推荐但不是必需的属性。
class HelloConan(ConanFile):
name = "hello"
version = "0.1"
url = "https://github.com/conan-io/libhello.git"
依赖¶
依赖项简单声明的属性形式,例如 requires、tool_requires。对于定义依赖项的更高级方法,请使用 requirements()、build_requirements() 方法。
requires¶
主机上下文中常规依赖项的字符串列表或元组,例如一个库。
class MyLibConan(ConanFile):
requires = "hello/1.0", "otherlib/2.1@otheruser/testing"
您可以指定版本范围,语法是使用方括号
class HelloConan(ConanFile):
requires = "pkg/[>1.0 <1.8]"
接受的表达式是
表达式 |
范围内的版本 |
范围外的版本 |
|---|---|---|
[>=1.0 <2] |
1.0.0, 1.0.1, 1.1, 1.2.3 |
0.2, 2.0, 2.1, 3.0 |
[<3.2.1] |
0.1, 1.2, 2.4, 3.1.1 |
3.2.2 |
[>2.0] |
2.1, 2.2, 3.1, 14.2 |
1.1, 1.2, 2.0 |
插入符号 ^ 和波浪号 ~ 运算符基本上是下限和上限的紧凑表示形式
范围
[~2.5.1]可以写成[>=2.5.1 <2.6.0]范围
[^1.2.3]可以写成[>=1.2.3 <2.0.0]
通常,建议使用完整的表达式 [>=lower <upper] 而不是插入符号或波浪号快捷方式,因为它更明确,并且所有读者都清楚该范围内的有效版本是什么。
如果激活了预发布版本,例如定义配置 core.version_ranges:resolve_prereleases=True
表达式 |
范围内的版本 |
范围外的版本 |
|---|---|---|
[>=1.0 <2] |
1.0.0-pre.1, 1.0.0, 1.0.1, 1.1, 1.2.3 |
0.2, 2.0-pre.1, 2.0, 2.1, 3.0 |
[<3.2.1] |
0.1, 1.2, 1.8-beta.1, 2.0-alpha.2, 2.4, 3.1.1 |
3.2.1-pre.1, 3.2.1, 3.2.2, 3.3 |
[>2.0] |
2.1-pre.1, 2.1, 2.2, 3.1, 14.2 |
1.1, 1.2, 2.0-pre.1, 2.0 |
另请参阅
请查看 范围表达式 版本范围教程部分
请查看 requirements() 方法文档
tool_requires¶
主机上下文中依赖项的字符串列表或元组。表示一个构建工具,例如“cmake”。如果当前包存在预编译二进制文件,则工具要求的二进制文件将不会被检索。它们不能冲突。
class MyPkg(ConanFile):
tool_requires = "tool_a/0.2", "tool_b/0.2@user/testing"
这是添加 tool_requires 的声明方式。请查看 tool_requires() conanfile.py 方法,以了解更灵活的添加方式。
build_requires¶
build_requires 在 Conan 2 中用于提供与 Conan 1.X 语法的兼容性,但其使用在 Conan 2 中不鼓励,并且将在未来的 2.X 版本中弃用。请使用 tool_requires 代替 Conan 2 配方中的 build_requires。
test_requires¶
主机上下文中依赖项的字符串列表或元组。表示一个测试工具,例如“gtest”。仅当从源代码构建当前包时使用。它们不会将信息传播到下游消费者。如果当前包存在预编译二进制文件,则测试要求的二进制文件将不会被检索。它们不能冲突。
class MyPkg(ConanFile):
test_requires = "gtest/1.17.0", "other_test_tool/0.2@user/testing"
这是添加 test_requires 的声明方式。请查看 test_requires() 方法,以了解更灵活的添加方式。
python_requires¶
这个类属性允许依赖于另一个 Conan 配方并重用其代码。其基本语法是
from conan import ConanFile
class Pkg(ConanFile):
python_requires = "pyreq/0.1@user/channel" # recipe to reuse code from
def build(self):
self.python_requires["pyreq"].module # access to the whole conanfile.py module
self.python_requires["pyreq"].module.myvar # access to a variable
self.python_requires["pyreq"].module.myfunct() # access to a global function
self.python_requires["pyreq"].path # access to the folder where the reused file is
有关此属性的更多信息,请参阅 Python requires
python_requires_extend¶
这个类属性定义了一个或多个类,这些类将在运行时作为配方类的基类注入。每个类的语法应为字符串,例如 pyreq.MyConanfileBase,其中 pyreq 是 python_requires 的名称,MyConanfileBase 是要使用的类名。
from conan import ConanFile
class Pkg(ConanFile):
python_requires = "pyreq/0.1@user/channel", "utils/0.1@user/channel"
python_requires_extend = "pyreq.MyConanfileBase", "utils.UtilsBase" # class/es to inject
来源¶
导出¶
字符串列表或元组,包含 文件名 或 fnmatch 模式,这些文件应该与 conanfile.py 文件一起导出并存储,以使配方正常工作:其他配方将导入的 Python 文件、包含要读取的数据的文本文件等。
例如,如果我们有一些 Python 代码,希望配方在 helpers.py 文件中使用,并且有一些名为 info.txt 的文本文件,我们希望读取并在配方评估期间显示,那么我们可以这样做
exports = "helpers.py", "info.txt"
也可以使用 ! 前缀排除模式
exports = "*.py", "!*tmp.py"
导出源文件¶
字符串列表或元组,包含文件名或 fnmatch 模式,这些文件应该被导出,并且可以用于生成包。与 exports 属性不同,这些文件不应该被 conanfile.py Python 代码使用,而是用于编译库或生成最终包。并且,由于其用途,只有在请求的二进制文件不可用或用户强制 Conan 从源代码编译时,这些文件才会被检索。
这是使用 source() 方法获取源代码的替代方法。用于我们不是打包第三方库,而是将配方和 C/C++ 项目一起使用时
exports_sources = "include*", "src*"
也可以使用 ! 前缀排除模式
exports_sources = "include*", "src*", "!src/build/*"
请注意,如果配方定义了 layout() 方法并指定了 self.folders.source = "src",这不会影响文件(来自 exports_sources)被复制到哪里。它们将被复制到基本源代码文件夹。因此,如果您想替换一些进入 source() 方法的文件,您需要从父文件夹显式复制它,或者更好的是,从 self.export_sources_folder 复制。
import os, shutil
from conan import ConanFile
from conan.tools.files import save, load
class Pkg(ConanFile):
...
exports_sources = "CMakeLists.txt"
def layout(self):
self.folders.source = "src"
self.folders.build = "build"
def source(self):
# emulate a download from web site
save(self, "CMakeLists.txt", "MISTAKE: Very old CMakeLists to be replaced")
# Now I fix it with one of the exported files
shutil.copy("../CMakeLists.txt", ".")
shutil.copy(os.path.join(self.export_sources_folder, "CMakeLists.txt"), ".")
conan_data¶
只读属性,包含一个字典,其中包含以 conandata.yml 文件格式提供的键和值,该文件放置在 conanfile.py 旁边。此 YAML 文件会自动与配方一起导出,并自动与配方一起加载。
您可以在 conandata.yml 文件中声明信息,然后在配方的任何方法中访问它。例如,一个包含有关来源信息的 conandata.yml 文件如下所示
sources:
"1.1.0":
url: "https://www.url.org/source/mylib-1.0.0.tar.gz"
sha256: "8c48baf3babe0d505d16cfc0cf272589c66d3624264098213db0fb00034728e9"
"1.1.1":
url: "https://www.url.org/source/mylib-1.0.1.tar.gz"
sha256: "15b6393c20030aab02c8e2fe0243cb1d1d18062f6c095d67bca91871dc7f324a"
def source(self):
get(self, **self.conan_data["sources"][self.version])
source_buildenv¶
布尔属性,用于选择在运行 source() 方法时注入 VirtualBuildEnv 生成的环境。
将此属性设置为 True(默认值 False)将注入来自工具要求的 VirtualBuildEnv 生成的环境,在执行 source() 方法时。
class MyConan:
name = "mylib"
version = "1.0.0"
source_buildenv = True
tool_requires = "7zip/1.2.0"
def source(self):
get(self, **self.conan_data["sources"][self.version])
self.run("7z x *.zip -o*") ## Can run 7z in the source method
二进制模型¶
定义包二进制模型的关键属性,哪些设置、选项、包类型等会影响最终打包的二进制文件。
package_type¶
可选。声明 package_type 将帮助 Conan
更好地选择每个依赖项的默认
package_id_mode,即依赖项的更改如何影响当前包的package_id。哪些信息应该从依赖项传播到使用者,例如头文件、库、运行时信息。请参阅 此处,了解基于
package_type信息传播哪些特征。
有效值是
application:包是一个应用程序。
library:包是一个通用库。它将尝试确定库的类型(从
shared-library、static-library、header-library),读取self.options.shared(如果已声明)和self.options.header_onlyshared-library:包是一个共享库。
static-library:包是一个静态库。
header-library:包是一个仅头文件库。
build-scripts:包只包含构建脚本。
python-require:包是一个 python require。
unknown:包的类型未知。
请注意,包之间的关系并不总是明确定义的,并且可能导致错误,例如,build-scripts 不能对编译库具有常规 requires 依赖项,并且尚不清楚这些应该如何通过用作 tool_requires 的内容传播。如果某个包既想使用一些构建脚本,又想链接到给定的库,则应该将 tool_requires() 定义到 build-scripts 包,并将常规 requires() 定义到编译库。
设置¶
字符串列表,包含来自 settings.yml 的第一级设置,配方需要这些设置,因为:- 它们被读取用于构建(例如:if self.settings.compiler == “gcc”)- 它们影响 package_id。如果声明的设置的值发生变化,则 package_id 必须不同。
最常见的是声明
settings = "os", "compiler", "build_type", "arch"
一旦配方被 Conan 加载,settings 就会被处理,并且可以在配方中读取它们,也可以读取子设置
settings = "os", "arch"
def build(self):
if self.settings.compiler == "gcc":
if self.settings.compiler.cppstd == "gnu20":
# do some special build commands
如果您尝试访问不存在的设置,例如对于 msvc 设置的 self.settings.compiler.libcxx,Conan 将会失败,并提示 libcxx 不存在于该编译器中。
如果您想安全地检查设置值,可以使用 get_safe() 方法
def build(self):
# Will be None if doesn't exist (not declared)
arch = self.settings.get_safe("arch")
# Will be None if doesn't exist (doesn't exist for the current compiler)
compiler_version = self.settings.get_safe("compiler.version")
# Will be the default version if the return is None
build_type = self.settings.get_safe("build_type", default="Release")
get_safe() 方法如果该设置或子设置不存在且没有分配默认值,则返回 None。
您还可以使用 possible_values() 方法检查在 settings.yml 中定义的可能值
def generate(self):
# Print if Android exists as OS in the whole settings.yml
is_android = "Android" in self.settings.possible_values()["os"]
self.output.info(f"Android in settings.yml: {is_android}")
# Print the available versions for the compiler used by the HOST profile
compiler_versions = self.settings.compiler.version.possible_values()
self.output.info(f"[HOST] Versions for {str(self.settings.compiler)}: {', '.join(compiler_versions)}")
# Print the available versions for the compiler used by the BUILD profile
compiler_versions = self.settings_build.compiler.version.possible_values()
self.output.info(f"[BUILD] Versions for {str(self.settings_build.compiler)}: {', '.join(compiler_versions)}")
如上所示,执行 self.settings.possible_values() 会返回整个 settings.yml 作为 Python 类似字典的对象,而执行 self.settings.compiler.version.possible_values() 例如,会返回消费者使用的编译器的可用版本。
如果您想安全地删除设置,可以使用 rm_safe() 方法。例如,在 configure() 方法中,C 库的典型模式是
def configure(self):
self.settings.rm_safe("compiler.libcxx")
self.settings.rm_safe("compiler.cppstd")
选项¶
字典,其中包含仅影响当前配方的特征,其中键是选项名称,值是可以采用的不同值的列表。默认情况下,任何选项值的更改都会更改 package_id。请查看 default_options 和 default_build_options 字段以定义选项的默认值。
每个选项的值可以是类型化的或纯字符串("value"、True、42,…)。
有两种特殊值
None:允许该选项具有None值(未指定)而不出错。"ANY":对于可以采用任何值的选项,不限于一组值。
class MyPkg(ConanFile):
...
options = {
"shared": [True, False],
"option1": ["value1", "value2"],
"option2": ["ANY"],
"option3": [None, "value1", "value2"],
"option4": [True, False, "value"],
}
一旦配方被 Conan 加载,options 就会被处理,并且可以在配方中读取它们。您还可以使用 .get_safe() 方法(请参阅 settings 属性)以避免 Conan 在选项不存在时引发异常
class MyPkg(ConanFile):
options = {"shared": [True, False]}
def build(self):
if self.options.shared:
# build the shared library
if self.options.get_safe("foo", True):
pass
在布尔表达式中,例如 if self.options.shared
等于
True对于值True、"True"和"true",以及 Python 代码中以相同方式评估的任何其他值。等于
False对于值False、"False"和"false",以及空字符串和0和"0"如预期的那样。
请注意,使用 is 进行比较始终为 False,因为类型将不同,因为它封装在 Python 类中。
如果您想安全地删除选项,可以使用 rm_safe() 方法。例如,在 config_options() 方法中,Windows 库的典型模式是
def config_options(self):
if self.settings.os == "Windows":
self.options.rm_safe("fPIC")
另请参阅
阅读 入门,创建包,了解如何声明以及如何为选项定义值。
default_options¶
属性 default_options 定义了选项的默认值,既适用于当前配方,也适用于任何要求。此属性应定义为 Python 字典。
class MyPkg(ConanFile):
...
requires = "zlib/1.2.8", "zwave/2.0"
options = {"build_tests": [True, False],
"option2": "ANY"}
default_options = {"build_tests": True,
"option1": 42,
"z*:shared": True}
您还可以使用“<reference_pattern>: option_name”为您的要求中的选项分配默认值,其中有效的 reference_pattern 是 name/version 或任何带有 * 的模式,如上面的示例所示。
警告
在配方中定义选项值没有强烈的保证,请查看 关于依赖项选项值的常见问题解答。定义选项值的推荐方法是在配置文件中。
您还可以使用 configure() 而不是使用 default_options 以条件方式为最终值设置选项
class OtherPkg(ConanFile):
settings = "os", "arch", "compiler", "build_type"
options = {"some_option": [True, False]}
# Do NOT declare 'default_options', use 'config_options()'
def configure(self):
if self.options.some_option == None:
if self.settings.os == 'Android':
self.options.some_option = True
else:
self.options.some_option = False
请注意,如果在 configure() 方法中分配了值,则无法覆盖它。
另请参阅
配方可以尝试为依赖项定义选项值的方式有两种。使用 default_options = {"mypkg/*:myoption", 123},当前配方可以将 123 值定义为依赖项 mypkg 的 myoption。这种定义依赖项选项的方式有一些限制
任何下游用户当前配方,为
mypkg定义了相同的选项,都将具有优先权,覆盖当前配方的123值。配置文件或命令行中的任何定义也将具有优先权。配方的default_options具有最低优先级。如果配方不能与某些依赖项选项一起工作,则配方可以检查并引发ConanInvalidConfiguration错误。任何依赖于
mypkg的兄弟包也将定义其选项,并且只有它们才会被考虑。换句话说,第一次要求mypkg的包将“冻结”其当前分配的选项值。之后依赖于mypkg的任何其他包,关闭依赖关系图中的菱形结构将不会对mypkg选项产生任何影响。只有第一个要求它的人才会。
第二种定义选项值的方法是将它们定义为 important!。
警告
important! 语法是实验性的,并且可以随时更改或删除。
一个配方可以将其依赖项选项定义为 重要!,语法为 default_options = {"mypkg/*:myoption!", 123}。这意味着 mypkg 的 myoption 将不会被其他下游包、profile 或命令行通过常规选项定义覆盖(例如 -o *:myoption=234)。
但是,在以下两种情况下,这仍然不会定义依赖项的最终值
如果任何下游配方、命令行或 profile 也使用
myoption!语法,那么它也将具有优先权并覆盖上游的值如果存在任何其他需要首先
mypkg的包,那么在该时刻定义的值仍然具有优先权。
通常,定义选项值的建议是在 profile 文件中进行,而不是在配方中,因为配方中的定义可能更复杂,特别是对于复杂的依赖关系图。
default_build_options¶
属性 default_build_options 定义了构建上下文中选项的默认值,通常用于定义 tool_requires 的选项。
from conan import ConanFile
class Consumer(ConanFile):
default_options = {"protobuf/*:shared": True}
default_build_options = {"protobuf/*:shared": False}
def requirements(self):
self.requires("protobuf/1.0")
def build_requirements(self):
self.tool_requires("protobuf/1.0")
options_description¶
属性 options_description 是一个可选属性,可以定义为字典的形式,其中键是选项名称,值是以文本格式描述的选项。此属性对于提供有关每个选项的功能和用途的附加信息很有用,特别是当选项不言自明或具有复杂或特殊行为时。
每个字典条目的格式应为
键:选项名称。必须是字符串,并且必须与
options字典中的一个键匹配。值:选项的描述。必须是字符串,并且可以根据需要长。
例如
class MyPkg(ConanFile):
...
options = {"option1": [True, False],
"option2": "ANY"}
options_description = {
"option1": "Describe the purpose and functionality of 'option1'. ",
"option2": "Describe the purpose and functionality of 'option2'. ",
}
languages¶
警告
此功能是实验性的,可能会发生重大更改。有关更多信息,请参阅 Conan 稳定性 部分。
从 Conan 2.4 开始,conanfile.py 配方属性 languages 可用于定义此包中涉及的编程语言。目前,C 和 C++ 语言是可能的值。例如,纯 C 包会定义如下
class ZLib(ConanFile):
languages = "C"
可以定义多种语言,例如 languages = "C", "C++" 是当包同时从 C 和 C++ 源代码构建时正确的定义。
关于 languages 定义,将发生以下情况
如果未定义
languages或未声明C语言,则在包configure()时会自动删除compiler.cstd子集(以实现向后兼容性)。如果定义了
languages,但它不包含C++,则在包configure()时会自动删除compiler.cppstd和compiler.libcxx子集。
info¶
仅在 package_id() 方法中使用的对象
用于控制包的唯一 ID 的 :ref:package_id method<reference_conanfile_methods_package_id> 方法
def package_id(self): self.info.clear()
方法 self.info.clear() 会删除用于 package_id 计算的所有设置、选项、需求(requires、tool_requires、python_requires)和配置(conf),因此 package_id 总是会产生相同的二进制文件,无论这些事情如何。这通常是仅头文件库的情况,在这种情况下,打包的工件(文件)始终相同。
package_id_{embed,non_embed,python,unknown}_mode, build_mode¶
类属性 package_id_embed_mode, package_id_non_embed_mode, package_id_python_mode, package_id_unknown_mode 可以在配方中定义,以定义它们对其作为 requires 消耗时消费者的 package_id 的影响。
属性 build_mode(实验性)是一个类属性,它会影响当这些消费者将其用作 tool_requires 时消费者的包。可以声明为
from conan import ConanFile
class Pkg(ConanFile):
name = "pkg"
version = "1.0.0"
# They are not mandatory, and it is not necessary to define all
package_id_embed_mode = "full_mode"
package_id_non_embed_mode = "patch_mode"
package_id_unknown_mode = "minor_mode"
package_id_python_mode = "major_mode"
build_mode = "patch_mode" # (experimental) when used as tool_requires
通常,Conan 的默认值很好,并且允许用户很好地控制何时需要从源代码重新构建或不重新构建。此外,可以通过 global.conf 文件全局更改 Conan 默认值(它们应全局更改给所有用户、CI 等),通过 core.package_id:xxxx 配置。配方中的属性定义对于定义偏离默认值的行为很有用。
可能的值是(遵循 MAJOR.MINOR.PATCH 的语义版本定义)
patch_mode:此包的新补丁、次要版本和主要版本将需要消费者的新的二进制文件(新的package_id)。新的配方修订版不需要消费者的新的二进制文件。例如,如果创建了新的pkg/1.0.1版本,而某个消费者具有requires = "pkg/[>=1.0 <2.0]",则该消费者将针对这个特定的新1.0.1版本构建新的二进制文件。但是,如果只是更改了配方,生成了新的recipe_revision,则消费者不需要构建新的二进制文件。minor_mode:此包的新次要版本和主要版本将需要消费者的新的二进制文件。新的补丁和新的修订版不需要消费者的新的二进制文件。这是“非嵌入模式”的默认值,因为它允许用户很好地控制何时重新构建事物。major_mode:只有新的主要版本才需要新的二进制文件。任何其他修改和新版本都不需要消费者的新的二进制文件。full_mode:此包的完整标识符,包括pkgname/version@user/channel#recipe_revision:package_id将在消费者的package_id中使用,然后需要为该包的任何更改(因为任何更改都会产生不同的recipe_revision或package_id)构建消费者的新的二进制文件。这是“嵌入模式”的默认值。unrelated_mode:此包的任何更改都不会在消费者中产生新的二进制文件。revision_mode:在消费者的package_id中使用pkgname/version@user/channel#recipe_revision,即完整的引用,不包括依赖项的package_id。semver_mode:如果版本>=1.0,则等效于major_mode,如果版本<1.0,则等效于patch_mode(或者如果版本有 3 位以上数字,则等效于完整版本)。
4 种不同的属性是
package_id_embed_mode:定义“嵌入”情况的模式,即共享库链接静态库、应用程序链接静态库、应用程序或库链接仅头文件库。此模式的默认值为full_modepackage_id_non_embed_mode。定义“非嵌入”情况的模式,即共享库链接另一个共享库、静态库链接另一个静态库、应用程序可执行文件链接共享库。此模式的默认值为minor_mode。package_id_unknown_mode:定义当包之间的关系未知时使用的模式。如果由于没有定义shared或header_only选项,或者因为未定义package_type而无法推断包类型,则将使用此模式。此模式的默认值为semver_mode(类似于 Conan 1.X 的行为)。package_id_python_mode:定义python_requires的消费者的模式。默认情况下,它将是minor_mode,强烈建议使用此默认值,并且不要定义package_id_python_mode。提供此属性是为了完整性和临时迁移等特殊情况。build_mode:(实验性)定义将此依赖项作为tool_requires使用的消费者的模式。默认值为None,这意味着tool_requires不会直接影响消费者的package_id。启用此build_mode会引入对tool_requires的更严格的依赖关系,这将在更多情况下需要解析消费者的package_id。
另请参阅
请阅读 binary model reference 以全面了解 Conan 二进制模型。
context¶
警告
此功能是实验性的,可能会发生重大更改。有关更多信息,请参阅 Conan 稳定性 部分。
配方属性 conanfile.py context 将包含“build”或“host”值,以表示当前包实例被评估的上下文。请记住,根据使用情况,某些配方可能同时存在于“build”和“host”上下文中。
对于绝大多数情况,不应该使用此属性,因此建议避免使用它。此建议的一个潜在例外是打破否则无限的依赖循环,将某些条件依赖项定义为
def requirements(self):
if self.context == "host":
self.tool_requires("mytool/1.0")
Build¶
generators¶
生成器名称的列表或元组。
class MyLibConan(ConanFile):
generators = "CMakeDeps", "CMakeToolchain"
生成器也可以在 generate() 方法 中显式实例化。
from conan.tools.cmake import CMakeToolchain
class MyLibConan(ConanFile):
...
def generate(self):
tc = CMakeToolchain(self)
tc.generate()
build_policy¶
控制在 conan install 期间构建当前包的时间。允许的值是
"missing":如果找不到二进制文件,Conan 将从源代码构建它。"never":此包不能从源代码构建,始终使用conan export-pkg创建。None(默认值):除非在命令行中指定策略(例如--build=foo*),否则此包不会被构建。class PocoTimerConan(ConanFile): build_policy = "missing"
win_bash¶
当 True 时,它启用了 Windows 中新的在子系统 bash 中运行机制。
from conan import ConanFile
class FooRecipe(ConanFile):
...
win_bash = True
它也可以根据任何条件声明为 property
from conan import ConanFile
class FooRecipe(ConanFile):
...
@property
def win_bash(self):
return self.settings.arch == "armv8"
win_bash_run¶
当 True 时,它启用了在 "run" 范围内运行命令,以便在 bash shell 中运行它们。
from conan import ConanFile
class FooRecipe(ConanFile):
...
win_bash_run = True
def build(self):
self.run(cmd, scope="run") # will run <cmd> inside bash
文件夹和布局¶
source_folder¶
源代码所在的文件夹。路径是通过将基本目录(在缓存中运行时是缓存目录,或者在本地运行时是 output folder)与在 layout() 方法中声明的 folders.source 的值连接起来构建的。
请注意,在缓存中运行时 source_folder 的基本目录将指向构建的基本文件夹,除非将 no_copy_source 设置为 True。但无论如何,它始终指向源代码所在的正确文件夹。
export_sources_folder¶
其值取决于你访问它的方法
在
source(self)中:指向基本源代码文件夹(这意味着 self.source_folder,但不考虑在layout()方法中声明的folders.source)。声明的 exports_sources 始终复制到该基本源代码文件夹。在
exports_sources(self)中:指向缓存中必须复制导出源的文件夹。
build_folder¶
用于构建源代码的文件夹。路径是通过将基本目录(在缓存中运行时是缓存目录,或者在本地运行时是 output folder)与在 layout() 方法中声明的 folders.build 的值连接起来构建的。
generators_folder¶
在 generate() 方法中应该生成文件的文件夹。路径是从布局的 self.folders.generators 属性构建的。
package_folder¶
用于复制最终二进制包工件的文件夹。在本地缓存中,为每个不同的包 ID 创建一个包文件夹。
最常见的 self.package_folder 用法是在 package() 方法 中 copy 文件。
import os
from conan import ConanFile
from conan.tools.files import copy
class MyRecipe(ConanFile):
...
def package(self):
copy(self, "*.so", self.build_folder, os.path.join(self.package_folder, "lib"))
...
recipe_folder¶
存储配方 conanfile.py 的文件夹,无论是本地文件夹还是缓存。这对于访问与配方一起导出的文件,或者在 export(self) 和 export_sources(self) 方法中导出文件时的原始文件夹很有用。
最常见的 self.recipe_folder 用法是在 export(self) 和 export_sources(self) 方法中,作为我们复制文件的文件夹。
from conan import ConanFile
from conan.tools.files import copy
class MethodConan(ConanFile):
exports = "file.txt"
def export(self):
copy(self, "LICENSE.md", self.recipe_folder, self.export_folder)
recipe_metadata_folder¶
self.recipe_metadata_folder(**实验性**)可以在 export() 和 export_sources() 和 source() 方法中使用,以保存或复制**配方**元数据文件。有关更多信息,请参阅 元数据部分。
package_metadata_folder¶
self.package_metadata_folder(**实验性**)可以在 generate()、build() 和 package() 方法中使用,以保存或复制**包**元数据文件。有关更多信息,请参阅 元数据部分。
no_copy_source¶
属性 no_copy_source 告诉配方源代码不会从 source_folder 复制到 build_folder。这主要是对具有大型源代码库或仅包含头文件的包的优化,以避免额外的复制。
如果你激活 no_copy_source=True,则**必须**保证源代码在配置或构建脚本中根本不会被修改,因为源代码将在所有构建之间共享。
配方应始终使用 self.source_folder 属性,该属性在 no_copy_source=False 时将指向 build 文件夹,在 no_copy_source=True 时将指向 source 文件夹。
另请参阅
阅读 仅包含头文件的包部分,了解使用 no_copy_source 属性的示例。
test_package_folder¶
类属性 test_package_folder 允许在配方中为 conan create 命令定义不同的默认 test_package 文件夹。当 conan create 运行时,在缓存中创建包后,它将查找 test_package 文件夹,或者查找在 --test-folder=xxx 参数中指定的文件夹,并启动包测试。
此属性允许更改默认名称
import os
from conan import ConanFile
class Pkg(ConanFile):
test_package_folder = "my/test/folder"
它允许定义任何文件夹,始终相对于 conanfile.py 的位置。
布局¶
folders¶
folders 属性必须仅在 layout() 方法中设置。请查看 layout() 方法文档,以了解有关此属性的更多信息。
cpp¶
存储包的消费者所需的所有信息的对象:包含目录、库名称、库路径… 对于可编辑包和缓存中的常规包。它仅在 layout() 方法中可用。
self.cpp.package:对于从 Conan 缓存使用的常规包。与在package_info()方法中声明self.cpp_info相同。self.cpp.source:对于“可编辑”包,用于描述self.source_folder下的工件。self.cpp.build:对于“可编辑”包,用于描述self.build_folder下的工件。
cpp 属性必须仅在 layout() 方法中设置。请查看 layout() 方法文档,以了解有关此属性的更多信息。
layouts¶
layouts 属性必须仅在 layout() 方法中设置。请查看 layout() 方法文档,以了解有关此属性的更多信息。
layouts 属性包含有关环境变量和 conf 的信息,这些信息将取决于路径,因此当包处于可编辑模式或在缓存中时,将包含不同的值。 layouts 子属性是
self.layouts.build:与相对self.folders.build相关的信self.layouts.source:与相对self.folders.source相关的信self.layouts.package:与最终package_folder相关的信
每个子属性都将包含
buildenv_info:消费者的构建环境信息变量(相当于self.buildenv_info在package_info()中)。runenv_info:消费者的运行环境信息变量(相当于self.runenv_info在package_info()中)。conf_info:消费者的配置信息(相当于self.conf_info在package_info()中)。请注意,只有当此包是直接tool_require时,此信息才会自动传播到消费者的self.conf。
例如,如果我们有一个包含 AndroidNDK 的 androidndk 配方,并且我们希望将该配方置于“可编辑”模式,则有必要在创建包之前确定 androidndk 在本地的位置
import os
from conan import ConanFile
from conan.tools.files import copy
class AndroidNDK(ConanFile):
def layout(self):
# When developing in user space it is in a "mybuild" folder (relative to current dir)
self.layouts.build.conf_info.define_path("tools.android:ndk_path", "mybuild")
# but when packaged it will be in a "mypkg" folder (inside the cache package folder)
self.layouts.package.conf_info.define_path("tools.android:ndk_path", "mypkg")
def package(self):
copy(self, "*", src=os.path.join(self.build_folder, "mybuild"),
dst=os.path.join(self.package_folder, "mypkg"))
消费者包信息¶
cpp_info¶
与在 layout() 中使用 self.cpp.package 相同。如果你需要读取 package_folder 以找到已定位的工件,请使用它。
另请参阅
CppInfo 模型。
重要
此属性仅在 package_info() 方法中定义,在其他地方为 None。
buildenv_info¶
对于依赖配方,声明的环境变量将在构建过程中存在。应仅在 package_info() 方法中填充。
重要
此属性仅在 package_info() 方法中定义,在其他地方为 None。
def package_info(self):
self.buildenv_info.append_path("PATH", self.package_folder)
另请参阅
请查看 Environment 对象的参考,了解如何填充 self.buildenv_info。
runenv_info¶
对于依赖的配方,声明的环境变量在运行时会存在。应仅在 package_info() 方法中填充。
重要
此属性仅在 package_info() 方法中定义,在其他地方为 None。
def package_info(self):
self.runenv_info.define_path("RUNTIME_VAR", "c:/path/to/exe")
另请参阅
请查看 Environment 对象的参考,了解如何填充 self.runenv_info。
conf_info¶
要传递给依赖配方的配置变量。应仅在 package_info() 方法中填充。
class Pkg(ConanFile):
name = "pkg"
def package_info(self):
self.conf_info.define("tools.build:verbosity", "debug")
self.conf_info.get("tools.build:verbosity") # == "debug"
self.conf_info.append("user.myconf.build:ldflags", "--flag3") # == ["--flag1", "--flag2", "--flag3"]
self.conf_info.update("tools.microsoft.msbuildtoolchain:compile_options", {"ExpandAttributedSource": "false"})
self.conf_info.unset("tools.microsoft.msbuildtoolchain:compile_options")
self.conf_info.remove("user.myconf.build:ldflags", "--flag1") # == ["--flag0", "--flag2", "--flag3"]
self.conf_info.pop("tools.system.package_manager:sudo")
另请参阅
请在此处阅读 self.conf_info 的完整参考。
generator_info¶
警告
此功能是实验性的,可能会发生重大更改。有关更多信息,请参阅 Conan 稳定性 部分。
要传递给依赖配方的生成器。应仅在 package_info() 方法中填充,默认为 None。
另请参阅
请参阅 此处的使用示例 和 self.generator_info 的完整参考。
deprecated¶
此属性声明配方已弃用,每当使用它时都会发出用户友好的警告消息
例如,以下代码
from conan import ConanFile
class Pkg(ConanFile):
name = "cpp-taskflow"
version = "1.0"
deprecated = True
可能会发出 risk 警告,例如
Deprecated
cpp-taskflow/1.0
WARN: risk: There are deprecated packages in the graph
可选地,该属性可以指定建议的替换名称
from conan import ConanFile
class Pkg(ConanFile):
name = "cpp-taskflow"
version = "1.0"
deprecated = "Not secure, use better taskflow>1.2.3"
这将发出 risk 警告,例如
Deprecated
cpp-taskflow/1.0: Not secure, use better taskflow>1.2.3
WARN: risk: There are deprecated packages in the graph
如果该属性的值计算为 False,则不会打印任何警告。
provides¶
此属性声明配方提供与其他配方相同的功能。通常需要在两个或多个库实现相同的 API 以防止链接时和运行时冲突(ODR 违规)时使用该属性。一个典型的情况是分叉库。一些示例是
如果 Conan 在单个图中遇到两个或多个提供相同功能的库,它将引发错误
At least two recipes provides the same functionality:
- 'libjpeg' provided by 'libjpeg/9d', 'libjpeg-turbo/2.0.5'
该属性值应为配方名称或此类配方名称的元组。
例如,要声明 libjpeg-turbo 配方提供与 libjpeg 配方相同的功能,可以使用以下代码
from conan import ConanFile
class LibJpegTurbo(ConanFile):
name = "libjpeg-turbo"
version = "1.0"
provides = "libjpeg"
要声明配方同时提供多个不同配方的功能,可以使用以下代码
from conan import ConanFile
class OpenBLAS(ConanFile):
name = "openblas"
version = "1.0"
provides = "cblas", "lapack"
如果省略该属性,则假定该属性的值等于当前包名称。因此,对于 libjpeg 配方声明它提供 libjpeg 是多余的,Conan 已经隐式地假设了这一点。
Other¶
dependencies¶
Conan 配方通过 self.dependencies 属性访问其依赖项。
class Pkg(ConanFile):
requires = "openssl/0.1"
def generate(self):
openssl = self.dependencies["openssl"]
# access to members
openssl.ref.version
openssl.ref.revision # recipe revision
openssl.options
openssl.settings
另请参阅
请在此处阅读 self.dependencies 的完整参考。
subgraph¶
(实验性) 配方的只读依赖关系图。应使用 dependencies 属性访问配方的依赖项,因为此属性旨在传递给其他 Conan API 并暴露于高级用法,例如 SBOM 生成。
conf¶
在 self.conf 属性中,我们可以找到在配置文件中的 [conf] 部分中声明的所有 conf 条目,以及从第一层工具要求声明的 self.conf_info 条目。配置文件条目具有优先级。
from conan import ConanFile
class MyConsumer(ConanFile):
tool_requires = "my_android_ndk/1.0"
def generate(self):
# This is declared in the tool_requires
self.output.info("NDK host: %s" % self.conf.get("tools.android:ndk_path"))
# This is declared in the profile at [conf] section
self.output.info("Custom var1: %s" % self.conf.get("user.custom.var1"))
注意
conf 属性是一个**只读**属性。它只能在配置文件和命令行中定义,但绝不应由配方设置。配方只能通过 self.conf.get() 方法读取其值。
Output¶
Output contents¶
使用 self.output 属性将内容打印到输出。
self.output.success("This is good, should be green")
self.output.info("This is neutral, should be white")
self.output.warning("This is a warning, should be yellow")
self.output.error("Error, should be red")
有更多输出方法可用,并且可以使用不同的颜色生成不同的输出。请参阅 输出文档 以获取可用输出方法的列表。
revision_mode¶
此属性允许每个配方声明应如何计算配方本身的修订版本。它可以采用三个不同的值
"hash"(默认值):Conan 将使用配方清单的校验和哈希来计算配方的修订版本。"scm":如果项目位于 Git 存储库中,则提交 ID 将用作配方修订版本。如果没有存储库,则会引发错误。"scm_folder":当您拥有一个单体存储库项目,但仍然希望使用 *scm* 修订版本时,此配置适用。在这种情况下,导出的 conanfile.py 的修订版本将对应于其所在文件夹的提交 ID。这种方法允许在同一个 Git 存储库中存在多个 conanfile.py 文件,每个文件在自己的不同修订版本下导出。
当选择 scm 或 scm_folder 时,将使用 Git 提交,但默认情况下存储库必须是干净的,否则很可能存在未提交的更改并且构建将无法重现。因此,如果有脏文件,Conan 将引发错误。
如果存储库中存在一些可以变脏的文件,但它们根本不属于配方或包,那么可以使用配方属性 revision_mode_excluded 或配置 core.scm:excluded(fnmatch 模式列表)来排除它们进行检查。
from conan import ConanFile
class MyConsumer(ConanFile):
revision_mode = "scm"
# the .tmp files are excluded from revision and dirty check
revision_mode_excluded = ["*.tmp"]
upload_policy¶
控制当前包的构建二进制文件是否上传
"skip":不上传预编译的二进制文件。这对于仅下载和解压缩某些大型内容的“安装程序”包(例如 android-ndk)很有用,并且与build_policy = "missing"一起使用很有用class Pkg(ConanFile): upload_policy = "skip"
required_conan_version¶
配方可以定义模块级别的 required_conan_version,该级别定义了可以加载和理解当前 conanfile.py 的 Conan 版本的有效范围。语法是
from conan import ConanFile
required_conan_version = ">=2.0"
class Pkg(ConanFile):
pass
允许使用 requires 中的版本范围。此外,还有一个 global.conf 文件 core:required_conan_version 配置,可以定义 Conan 运行的全局最小、最大或精确版本,这对于维护开发团队和 CI 机器使用所需的版本范围非常方便。
implements¶
使用列表来定义一系列 Conan 将自动处理的选项配置。这对于避免在大多数配方中重复出现的样板代码非常有用。语法如下
from conan import ConanFile
class Pkg(ConanFile):
implements = ["auto_shared_fpic", "auto_header_only", ...]
目前 Conan 提供的自动实现如下
"auto_shared_fpic":自动管理fPIC和shared选项。添加此实现将在 configure 和 config_options 步骤中产生影响,当这些方法未在配方中显式定义时。"auto_header_only":自动管理包 ID 清除设置。添加此实现将在 package_id 步骤中产生影响,当该方法未在配方中显式定义时。
警告
这是一个仅限 2.0 的功能,它在 1.X 中将不起作用
alias¶
警告
虽然在 Conan 2 中技术上仍然可以使用别名,但不建议使用它们,并且它们可能会在未来的版本中完全删除。鼓励用户适应 新的版本控制功能,以获得更标准化和高效的包管理体验。
在 Conan 2 中,alias 属性仍然是配方的一部分,允许用户为包版本定义别名。通常,您可以使用 conan new 命令和 alias 模板以及使用 conan export 导出配方来创建它
$ conan new alias -d name=mypkg -d version=latest -d target=1.0
$ conan export .
请注意,在使用别名时,必须将版本放在括号中 (),以显式声明将别名作为要求使用
class Consumer(ConanFile):
...
requires = "mypkg/(latest)"
...
extension_properties¶
extensions_properties 属性是一个字典,旨在定义并将信息从配方传递给 Conan 扩展。
目前,定义的属性只有 compatibility_cppstd 和 compatibility_cstd,它允许禁用 默认 compatibility.py 扩展 的行为,该行为认为使用不同的 compiler.cppstd 和 compiler.cstd 值构建的二进制文件是 ABI 兼容的。要为当前包禁用此行为,可以使用
class Pkg(ConanFile):
extension_properties = {"compatibility_cppstd": False}
如果需要有条件地执行此操作,也可以在配方的 compatibility() 方法中定义其值
class Pkg(ConanFile):
def compatibility(self):
self.extension_properties = {"compatibility_cppstd": False}
注意
默认情况下,extension_properties 的值不会从依赖项传递到使用者,但可以通过迭代 self.dependencies 并检查其 extension_properties 的所需值来手动传播。