属性¶
包引用¶
配方属性,可以定义主要的 pkg/version@user/channel
包引用。
name¶
包的名称。有效的名称全部为小写,并且
最少 2 个字符,最多 101 个字符(尽管建议使用较短的名称)。
- 匹配以下正则表达式
^[a-z0-9_][a-z0-9_+.-]{1,100}$
:因此以字母数字或_
开头, 然后在 1 到 100 个字符之间,可以是字母数字、
_
、+
、.
或-
。
- 匹配以下正则表达式
- 名称仅在将配方
export
到本地缓存时(export
、export-pkg
和
create
命令)才是必需的,如果它们未在命令行中使用--name=<pkgname>
定义。
version¶
包的版本。有效的版本遵循与 name
属性相同的规则。如果版本遵循语义版本控制格式 X.Y.Z-pre1+build2
,则该值可能用于通过版本范围而不是确切版本来请求此包。
版本仅在将配方 export
到本地缓存时(export
、export-pkg
和 create
命令)才是严格必需的,如果它们未在命令行中使用 --version=<pkgversion>
定义
version
可以在命令行中动态定义,也可以在配方中使用 set_version() 方法 以编程方式定义。
user¶
user
字段的有效字符串遵循与 name
属性相同的规则。这是一个可选属性。它可以用于使用 pkg/version@user/channel
标识您自己的包,其中 user
可能是您的团队、组织或公司的名称。ConanCenter 配方没有 user/channel
,因此它们的格式仅为 pkg/version
。您也可以在没有用户和通道的情况下命名您的包,或者仅使用用户作为 pkg/version@user
。
用户可以在命令行中使用 --user=<myuser>
指定
channel¶
channel
字段的有效字符串遵循与 name
属性相同的规则。这是一个可选属性。有时用于标识包的成熟度(“stable”、“testing”等),但通常这不是必需的,最好通过将包放在不同的服务器存储库中来管理包的成熟度。
通道可以在命令行中使用 --channel=<mychannel>
指定
元数据¶
可选元数据,如许可证、描述、作者等。对于大多数情况不是必需的,但可能有用。
description¶
这是一个可选但推荐的文本字段,包含包的描述以及对消费者可能有用的任何信息。第一行可以用作包的简短描述。
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"""
license¶
目标源代码和二进制文件的许可证,即正在打包的代码,而不是 conanfile.py
本身。可以包含多个以逗号分隔的许可证。它是一个文本字符串,因此可以包含任何文本,但强烈建议开源项目的配方使用来自 SPDX 许可证列表 的 SPDX 标识符
这将帮助希望自动化许可证兼容性检查的人员,例如您的包的消费者,或者如果您的包具有开源依赖项,则可以帮助您。
class Pkg(ConanFile):
license = "MIT"
topics¶
用于将相关包分组在一起并描述代码用途的标签。在 ConanCenter 中用作搜索过滤器。可选属性。它应该是一个字符串元组。
class ProtocInstallerConan(ConanFile):
name = "protoc_installer"
version = "0.1"
topics = ("protocol-buffers", "protocol-compiler", "serialization", "rpc")
homepage¶
正在打包的库的主页。
用于将配方链接到库本身的进一步说明,例如其功能概述、文档、FAQ 以及其他相关信息。
class EigenConan(ConanFile):
name = "eigen"
version = "3.3.4"
homepage = "http://eigen.tuxfamily.org"
url¶
包存储库的 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 |
如果预发布版本已激活,例如定义配置 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 |
另请参阅
查看 范围表达式 version_ranges 教程部分
tool_requires¶
依赖项的字符串列表或元组。表示构建工具,如“cmake”。如果当前包存在预编译的二进制文件,则不会检索 tool_require 的二进制文件。它们不能冲突。
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 版本中弃用。请在您的 Conan 2 配方中使用 tool_requires 代替 build_requires。
test_requires¶
仅在主机上下文中使用的依赖项的字符串列表或元组。表示测试工具,如“gtest”。当从源代码构建当前包时使用。它们不会将信息传播给下游消费者。如果当前包存在预编译的二进制文件,则不会检索 test_require 的二进制文件。它们不能冲突。
class MyPkg(ConanFile):
test_requires = "gtest/1.11.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
源¶
exports¶
字符串列表或元组,其中包含 文件名 或 fnmatch 模式,这些模式应与 conanfile.py 文件并排导出和存储,以使配方正常工作:配方将导入的其他 python 文件、一些包含要读取的数据的文本文件……
例如,如果我们有一些我们希望配方在 helpers.py
文件中使用的 python 代码,并且有一些我们想要在配方评估期间读取和显示的文本文件 info.txt,我们将执行类似以下操作
exports = "helpers.py", "info.txt"
排除模式也是可能的,使用 !
前缀
exports = "*.py", "!*tmp.py"
exports_sources¶
字符串列表或元组,其中包含文件名或 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)将在执行 source() 方法时注入来自工具需求的 VirtualBuildEnv
生成的环境。
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_only
shared-library:包是一个共享库。
static-library:包是一个静态库。
header-library:包是一个仅包含头文件的库。
build-scripts:包仅包含构建脚本。
python-require:包是一个 python require。
unknown:包的类型未知。
settings¶
字符串列表,其中包含配方需要的顶级设置(来自 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.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")
options¶
字典,其中包含仅影响当前配方的特性,其中键是选项名称,值是选项可以采用的不同值的列表。默认情况下,选项中的任何值更改都会更改 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"
,以及任何其他将在 Python 代码中以相同方式评估的值,等于True
。对于值
False
、"False"
和"false"
,以及空字符串以及0
和"0"
(如预期的那样),等于False
。
请注意,使用 is
进行比较始终为 False
,因为类型会不同,因为它封装在 Python 类中。
如果您想安全地删除选项,可以使用 rm_safe()
方法。例如,在 config_options()
方法中,Windows 库的典型模式是
def config_options(self):
if self.settings.os == "Windows":
self.options.rm_safe("fPIC")
另请参阅
阅读 入门,创建包,了解如何声明以及如何为选项定义值。
在
package_id()
方法中删除选项。 <缺少页面>关于 package_type 以及当声明
shared
选项时它如何发挥作用。 <缺少页面>
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()
方法中分配了值,则无法覆盖它。
另请参阅
配方可以通过 2 种不同的方式尝试为其依赖项定义选项值。使用 default_options = {"mypkg/*:myoption", 123}
,当前配方可以将 123
值定义为依赖项 mypkg
myoption
。这种为依赖项定义选项的方式有一些限制
对于当前 recipe 的任何其他下游用户,如果为
mypkg
定义了相同的选项,都将具有优先权,从而覆盖当前 recipe123
的值。此外,profile 文件或命令行中的任何定义也将具有优先权。Recipe 的default_options
优先级最低。如果某个 recipe 在某些依赖项选项下完全无法工作,则 recipe 可以检查并相应地引发ConanInvalidConfiguration
错误。任何依赖于
mypkg
的同级软件包也将定义其选项,并且这将是唯一被考虑的选项。换句话说,任何其他软件包首次需要mypkg
时,都将“冻结”其当前分配的选项值。任何其他稍后依赖于mypkg
的软件包,在依赖关系图中闭合菱形结构时,都不会对mypkg
选项产生任何影响。只有第一个需要它的软件包会产生影响。
定义选项值的第二种方法是将它们定义为 important!
。
警告
important!
语法是实验性的,可能会随时更改或删除。
Recipe 可以使用语法 default_options = {"mypkg/*:myoption!", 123}
将其依赖项选项定义为 important!
。这意味着 mypkg
的 myoption
将不会被其他下游软件包、profile 文件或命令行对选项进行常规定义(例如 -o *:myoption=234
)所覆盖。
但是,在以下两种情况下,这仍然无法定义依赖项的最终值
如果任何下游 recipe、命令行或 profile 文件也使用了
myoption!
语法,则它也将具有优先权并覆盖上游的值如果还有任何其他软件包首先需要
mypkg
,则在该时刻定义的值仍将具有优先权。
一般来说,定义选项值的建议是在 profile
文件中进行,而不是在 recipe 中进行,因为在 recipe 中定义可能更复杂,特别是对于复杂的依赖关系图。
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
recipe 属性 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()
方法中
:ref:package_id 方法<reference_conanfile_methods_package_id> 用于控制软件包的唯一 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¶
package_id_embed_mode, package_id_non_embed_mode, package_id_python_mode, package_id_unknown_mode
是可以在 recipe 中定义的类属性,用于定义它们对其消费者的 package_id
的影响。可以声明为
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"
一般来说,Conan 默认值是很好的,并且允许为用户提供良好的控制,以便控制何时需要从源代码重新构建消费者。此外,Conan 默认值可以在 global.conf
文件中全局更改(应该为所有用户、CI 等全局更改),通过 core.package_id:xxxx
配置。Recipe 内属性定义对于定义偏离默认值的行为非常有用。
可能的值为(遵循 MAJOR.MINOR.PATCH 的 semver 定义)
patch_mode
:软件包的新补丁、次要版本和主要版本将需要消费者的新二进制文件(新的package_id
)。新的 recipe 修订版将不需要消费者的新二进制文件。例如,如果我们创建一个新的pkg/1.0.1
版本,并且某些消费者具有requires = "pkg/[>=1.0 <2.0]"
,则此类消费者将针对此特定的新1.0.1
版本构建新的二进制文件。但是,如果我们仅更改 recipe,生成新的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
之外的完整引用。
4 个不同的属性是
package_id_embed_mode
:定义“嵌入”情况的模式,即共享库链接静态库、应用程序链接静态库、应用程序或库链接仅包含头文件的库。此模式的默认值为full_mode
package_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
。提供此属性是为了完整性和临时迁移等特殊情况。
另请参阅
阅读 二进制模型参考 以全面了解 Conan 二进制模型。
构建¶
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
值连接而构建的。
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¶
recipe conanfile.py 所在的文件夹,无论是在本地文件夹还是在缓存中。这对于访问随 recipe 一起导出的文件,或者在 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()
方法中使用,以保存或复制 recipe 元数据文件。有关更多信息,请参阅 元数据部分。
package_metadata_folder¶
self.package_metadata_folder
(实验性的) 可以在 generate()
、build()
和 package()
方法中使用,以保存或复制 package 元数据文件。有关更多信息,请参阅 元数据部分。
no_copy_source¶
属性 no_copy_source
告诉 recipe,源代码不会从 source_folder
复制到 build_folder
。这主要是针对具有大型代码库或仅包含头文件的软件包的优化,以避免额外的复制。
如果您激活 no_copy_source=True
,则强制性要求配置或构建脚本不得修改源代码,因为源代码将在所有构建之间共享。
Recipe 应始终使用 self.source_folder
属性,当 no_copy_source=False
时,该属性将指向 build
文件夹,当 no_copy_source=True
时,该属性将指向 source
文件夹。
另请参阅
阅读 仅包含头文件的软件包部分,以获取使用 no_copy_source
属性的示例。
test_package_folder¶
test_package_folder
类属性允许在 recipe 中为 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
:消费者的环境变量构建信息(等效于package_info()
中的self.buildenv_info
)runenv_info
:消费者的环境变量运行信息(等效于package_info()
中的self.runenv_info
)conf_info
:消费者的配置信息(等效于package_info()
中的self.conf_info
)。请注意,只有当此软件包是直接tool_require
时,才会自动将此信息传播到消费者的self.conf
。
例如,如果我们有一个包含 AndroidNDK 的 androidndk
recipe,并且我们希望在“可编辑”模式下拥有该 recipe,则在创建的软件包之前,必须知道 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¶
对于依赖 recipe,声明的环境变量将在构建过程中存在。应仅在 package_info()
方法中填写。
重要提示
此属性仅在 package_info()
方法内部定义,在其他地方为 None。
def package_info(self):
self.buildenv_info.append_path("PATH", self.package_folder)
另请参阅
查看 Environment 对象的参考,以了解如何填写 self.buildenv_info
。
runenv_info¶
对于依赖 recipe,声明的环境变量将在运行时存在。应仅在 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¶
要传递给依赖 recipe 的配置变量。应仅在 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 稳定性 部分。
要传递给依赖 recipe 的生成器。应仅在 package_info()
方法中填写。
另请参阅
请参阅 此处的示例用法 和 self.generator_info 的完整参考。
deprecated¶
此属性声明 recipe 已弃用,导致在使用它时发出用户友好的警告消息
例如,以下代码
from conan import ConanFile
class Pkg(ConanFile):
name = "cpp-taskflow"
version = "1.0"
deprecated = True
可能会发出类似以下的警告
cpp-taskflow/1.0: WARN: Recipe 'cpp-taskflow/1.0' is deprecated. Please, consider changing your requirements.
可选地,该属性可以指定建议的替换名称
from conan import ConanFile
class Pkg(ConanFile):
name = "cpp-taskflow"
version = "1.0"
deprecated = "taskflow"
这将发出类似以下的警告
cpp-taskflow/1.0: WARN: Recipe 'cpp-taskflow/1.0' is deprecated in favor of 'taskflow'. Please, consider changing your requirements.
如果属性的值评估为 False
,则不会打印任何警告。
provides¶
此属性声明 recipe 提供的功能与其他 recipe 相同。如果两个或多个库实现相同的 API 以防止链接时和运行时冲突(ODR 违规),则通常需要此属性。一种典型情况是派生库。一些例子是
如果 Conan 在单个依赖关系图中遇到两个或更多库提供相同的功能,它会引发错误
At least two recipes provides the same functionality:
- 'libjpeg' provided by 'libjpeg/9d', 'libjpeg-turbo/2.0.5'
属性值应为包含 recipe 名称的字符串或此类 recipe 名称的元组。
例如,要声明 libjpeg-turbo
recipe 提供与 libjpeg
recipe 相同的功能,可以使用以下代码
from conan import ConanFile
class LibJpegTurbo(ConanFile):
name = "libjpeg-turbo"
version = "1.0"
provides = "libjpeg"
要声明一个 recipe 同时提供多个不同 recipe 的功能,可以使用以下代码
from conan import ConanFile
class OpenBLAS(ConanFile):
name = "openblas"
version = "1.0"
provides = "cblas", "lapack"
如果省略该属性,则该属性的值被假定为等于当前的软件包名称。因此,libjpeg
recipe 声明它提供 libjpeg
是多余的,Conan 已经隐式地假定了这一点。
其他¶
dependencies¶
Conan recipe 通过 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¶
(实验性)recipe 的只读依赖关系图。dependencies
属性应用于访问 recipe 的依赖项,因为此属性旨在传递给其他 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
属性是一个 只读 属性。它只能在配置文件和命令行中定义,但绝不应由 recipe 设置。Recipe 只能通过 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¶
此属性允许每个 recipe 声明应如何计算 recipe 本身的修订版本。它可以采用三个不同的值
"hash"
(默认值):Conan 将使用 recipe 清单的校验和哈希来计算 recipe 的修订版本。"scm"
:如果项目位于 Git 仓库中,则提交 ID 将用作 recipe 修订版本。如果没有仓库,它将引发错误。"scm_folder"
:当您有一个单仓库项目,但仍想使用 scm 修订版本时,此配置适用。在这种情况下,导出的 conanfile.py 的修订版本将对应于其所在文件夹的提交 ID。这种方法允许在同一 Git 仓库中存在多个 conanfile.py 文件,每个文件都以其独特的修订版本导出。
当选择 scm
或 scm_folder
时,将使用 Git 提交,但默认情况下,仓库必须是干净的,否则很可能存在未提交的更改,并且构建将不可重现。因此,如果存在脏文件,Conan 将引发错误。如果仓库中存在可能是脏文件的文件,但不属于 recipe 或软件包,则可以使用 core.scm:excluded
配置从检查中排除它们,该配置是排除模式(fnmatch)的列表。
upload_policy¶
控制何时上传或不上传当前构建的软件包二进制文件
"skip"
:不上传预编译的二进制文件。这对于仅下载和解压缩一些大型内容(例如 android-ndk)的“安装程序”软件包很有用,并且与build_policy = "missing"
一起使用很有用class Pkg(ConanFile): upload_policy = "skip"
required_conan_version¶
Recipe 可以定义一个模块级别的 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 将自动处理的一系列选项配置。这对于避免在大多数 recipe 中倾向于重复的样板代码尤其方便。语法如下
from conan import ConanFile
class Pkg(ConanFile):
implements = ["auto_shared_fpic", "auto_header_only", ...]
目前,这些是 Conan 提供的自动实现
"auto_shared_fpic"
:自动管理fPIC
和shared
选项。添加此实现将在 configure 和 config_options 步骤中产生影响,当这些方法未在 recipe 中显式定义时。"auto_header_only"
:自动管理软件包 ID 清除设置。添加此实现将在 package_id 步骤中产生影响,当该方法未在 recipe 中显式定义时。
警告
这是一个仅限 2.0 的功能,它在 1.X 中不起作用
alias¶
警告
虽然别名在技术上仍可在 Conan 2 中使用,但不建议使用它们,并且它们可能会在未来的版本中完全删除。鼓励用户适应 更新的版本控制功能,以获得更标准化和高效的软件包管理体验。
在 Conan 2 中,alias 属性仍然是 recipe 的一部分,允许用户为软件包版本定义别名。通常,您可以使用带有 alias
模板的 conan new
命令创建一个别名,并使用 conan export 导出 recipe
$ 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
属性是一个字典,旨在定义信息并将其从 recipe 传递到 Conan 扩展。
目前,唯一定义的属性是 compatibility_cppstd
和 compatibility_cstd
,它们允许禁用 默认 compatibility.py 扩展 的行为,该扩展认为使用不同的 compiler.cppstd
和 compiler.cstd
值构建的二进制文件彼此之间 ABI 兼容。要为当前软件包禁用此行为,可以使用以下方法
class Pkg(ConanFile):
extension_properties = {"compatibility_cppstd": False}
如果需要有条件地执行此操作,也可以在 recipe 的 compatibility()
方法中定义其值
class Pkg(ConanFile):
def compatibility(self):
self.extension_properties = {"compatibility_cppstd": False}
注意
extension_properties
的值默认情况下不会从依赖项传递到消费者,但可以通过迭代 self.dependencies
并检查其 extension_properties
的所需值来手动传播。