属性¶
包引用¶
可以定义主 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,即不一定是原始源代码的 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 |
参见
请查看范围表达式版本范围教程章节
请查看requirements()方法文档
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() method,了解更灵活的添加方式。
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
Sources¶
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¶
只读属性,包含一个字典,该字典具有放置在 conanfile.py 旁边的 conandata.yml 文件格式中提供的键和值。此 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
Binary model¶
定义包二进制模型的重要属性,其中设置、选项、包类型等会影响最终打包的二进制文件。
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 需求。
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
如果您尝试访问一些不存在的设置,例如 self.settings.compiler.libcxx
对于 msvc
设置,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(选项)¶
包含影响当前 recipe 的特征的字典,其中 key 是选项名称,value 是选项可以取的不同值的列表。 默认情况下,选项中的任何值更改都会更改 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"],
}
一旦 recipe 被 Conan 加载,options
就会被处理,它们可以在 recipe 中读取。 您还可以使用 .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")
参见
阅读 入门,创建包,了解如何声明以及如何为选项定义值。
default_options(默认选项)¶
default_options
属性定义了选项的默认值,包括当前 recipe 和任何 requirement 的选项。 此属性应定义为 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” 为 requirement 的选项分配默认值,其中有效的 reference_pattern
是 name/version
或任何带有 *
的模式,如上面的示例。
警告
在 recipe 中定义选项值没有强保证,请检查 此关于依赖项选项值的常见问题解答。 建议的定义选项值的方法是在 profile 文件中。
您还可以使用 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()
方法中分配了值,则无法覆盖它。
Recipe 可以通过 2 种不同的方式尝试为其依赖项定义选项值。 使用 default_options = {"mypkg/*:myoption", 123}
,当前 recipe 可以为依赖项 mypkg
myoption
定义 123
值。 这种为依赖项定义选项的方式有一些限制
当前 recipe 的任何其他下游用户定义了
mypkg
的相同选项都将具有优先权,覆盖当前 recipe 的123
值。 此外,profile 或命令行中的任何定义也将具有优先权。 Recipe 的default_options
优先级最低。 如果 recipe 根本无法与某些依赖项选项一起使用,则 recipe 可以检查并相应地引发ConanInvalidConfiguration
错误。任何依赖于
mypkg
的 *同级* 包也将定义其选项,并且它将是唯一被考虑的选项。 换句话说,任何其他包第一次需要mypkg
将 “冻结” 其当前分配的选项值。 依赖图中稍后依赖于mypkg
的任何其他包,关闭菱形结构,都不会对mypkg
选项产生任何影响。 只有第一个需要它的包才会。
定义选项值的第二种方法是将它们定义为 important!
。
警告
important!
语法是实验性的,可以随时更改或删除。
Recipe 可以使用语法 default_options = {"mypkg/*:myoption!", 123}
将其依赖项选项定义为 important!
。 这意味着 mypkg
myoption
不会被其他下游包、profile 或命令行覆盖,这些下游包、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
属性是一个可选属性,可以以字典的形式定义,其中 key 是选项名称,value 是文本格式的选项描述。 此属性对于提供有关每个选项的功能和用途的附加信息非常有用,尤其是在该选项不是不言自明或具有复杂或特殊行为时。
每个字典条目的格式应为
Key:选项名称。 必须是字符串,并且必须与
options
字典中的一个 key 匹配。值:选项的描述。必须是字符串,并且可以根据需要设置长度。
例如
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"
可以定义多个语言,例如,当一个软件包由 C 和 C++ 源码构建时,languages = "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 默认值是不错的,并且允许用户很好地控制何时需要从源代码重新构建使用者。 此外,Conan 默认值可以在 global.conf
文件中全局更改(应该通过 core.package_id:xxxx
配置为所有用户、CI 等全局更改)。 配方内属性定义对于定义偏离默认值的行为很有用。
可能的值是(遵循 MAJOR.MINOR.PATCH 的 semver 定义):
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_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
。 提供此属性是为了完整性和临时迁移等特殊情况。build_mode
:(实验性) 定义使用者将此依赖项用作tool_requires
的模式。 默认情况下为None
,这意味着tool_requires
不会直接影响其使用者的package_id
。 启用此build_mode
会引入对tool_requires
的更严格的依赖性,在更多情况下,将需要解析使用者的package_id
。
参见
阅读 二进制模型参考,以全面了解 Conan 二进制模型。
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
Folders and layout (文件夹和布局)¶
source_folder (源文件夹)¶
源代码所在的文件夹。 该路径通过连接基本目录(在缓存中运行时为缓存目录,或在本地运行时为 output folder
)与 folders.source
的值(如果在 layout()
方法中声明)来构建。
请注意,在缓存中运行时,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
)与 folders.build
的值(如果在 layout()
方法中声明)来构建。
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
的位置。
Layout (布局)¶
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
的信息,这些变量和 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 处于“可编辑”模式,那么在创建 package 之前,必须知道 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"))
消费者使用的 Package 信息¶
cpp_info¶
与在 layout()
方法中使用 self.cpp.package
相同。 如果你需要读取 package_folder
来定位已定位的 artifacts,请使用它。
参见
CppInfo 模型。
重要
此属性仅在 package_info()
方法内部定义,在其他地方为 None。
buildenv_info¶
对于依赖的 recipes,声明的环境变量将在构建过程中存在。 应仅在 package_info()
方法中填写。
重要
此属性仅在 package_info()
方法内部定义,在其他地方为 None。
def package_info(self):
self.buildenv_info.append_path("PATH", self.package_folder)
参见
查看 Environment 对象的引用,以了解如何填写 self.buildenv_info
。
runenv_info¶
对于依赖的 recipes,声明的环境变量将在运行时存在。 应仅在 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¶
要传递给依赖 recipes 的配置变量。 应仅在 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 稳定性部分。
要传递给依赖 recipes 的生成器。 应仅在 package_info()
方法中填写。
参见
在此处查看 一个示例用法 和 self.generator_info 的完整参考。
deprecated¶
此属性声明该 recipe 已弃用,每当使用它时都会发出一个用户友好的警告消息
例如,以下代码
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¶
此属性声明该 recipe 提供与其他 recipe(s) 相同的功能。 如果两个或多个库实现相同的 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"
如果省略该属性,则该属性的值被假定为等于当前 package 名称。 因此,libjpeg
recipe 声明它提供 libjpeg
是多余的,Conan 已经隐式地假设了这一点。
其他¶
dependencies¶
Conan recipes 通过 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
属性中,我们可以找到在 profiles 的 [conf] 部分中声明的所有 conf 条目。 此外,还有来自第一级工具 requirements 的声明的 self.conf_info 条目。 profile 条目具有优先级。
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
属性是一个只读属性。 它只能在 profiles 和命令行中定义,但永远不应由 recipes 设置。 Recipes 只能通过 self.conf.get()
方法读取其值。
输出¶
输出内容¶
使用 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 本身的 revision。 它可以采用三个不同的值
"hash"
(默认): Conan 将使用 recipe manifest 的校验和哈希来计算 recipe 的 revision。"scm"
: 如果项目位于 Git 存储库中,则 commit ID 将用作 recipe revision。 如果没有存储库,它将引发错误。"scm_folder"
: 当你有一个 mono-repository 项目,但仍然想使用 scm revisions 时,应用此配置。 在这种情况下,导出的 conanfile.py 的 revision 将对应于它所在文件夹的 commit ID。 此方法允许在同一个 Git 存储库中存在多个 conanfile.py 文件,每个文件都以其不同的 revision 导出。
当选择 scm
或 scm_folder
时,将使用 Git commit,但默认情况下,存储库必须是干净的,否则很可能存在未提交的更改,并且构建将不可重现。 因此,如果有 dirty 文件,Conan 将引发错误。 如果存储库中存在可能是 dirty 的文件,但根本不属于 recipe 或 package,则可以使用 core.scm:excluded
配置将其从检查中排除,该配置是要排除的模式列表 (fnmatch)。
upload_policy¶
控制何时上传当前 package 构建的二进制文件
"skip"
: 不上传预编译的二进制文件。 这对于只下载和解压缩一些大型内容(例如 android-ndk)的“installer”packages 很有用,并且与build_policy = "missing"
一起使用很有用class Pkg(ConanFile): upload_policy = "skip"
required_conan_version¶
Recipes 可以定义一个模块级别的 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
的所需值来手动传播。