属性

包引用

配方属性,可以定义主要的 pkg/version@user/channel 包引用。

name

包的名称。有效的名称全部为小写,并且

  • 最少 2 个字符,最多 101 个字符(尽管建议使用较短的名称)。

  • 匹配以下正则表达式 ^[a-z0-9_][a-z0-9_+.-]{1,100}$:因此以字母数字或 _ 开头,

    然后在 1 到 100 个字符之间,可以是字母数字、_+.-

名称仅在将配方 export 到本地缓存时(exportexport-pkg

create 命令)才是必需的,如果它们未在命令行中使用 --name=<pkgname> 定义。

version

包的版本。有效的版本遵循与 name 属性相同的规则。如果版本遵循语义版本控制格式 X.Y.Z-pre1+build2,则该值可能用于通过版本范围而不是确切版本来请求此包。

版本仅在将配方 export 到本地缓存时(exportexport-pkgcreate 命令)才是严格必需的,如果它们未在命令行中使用 --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"

author

包的主要维护者/负责人,任何格式。这是一个可选属性。

class HelloConan(ConanFile):
    author = "John J. Smith ([email protected])"

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"

需求

依赖项简单声明的属性形式,如 requirestool_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

另请参阅

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 的字符串,其中 pyreqpython_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-librarystatic-libraryheader-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_optionsdefault_build_options 字段以定义选项的默认值。

每个选项的值可以是类型化的或纯字符串("value"True42,…)。

有两个特殊值

  • 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_patternname/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 定义了相同的选项,都将具有优先权,从而覆盖当前 recipe 123 的值。此外,profile 文件或命令行中的任何定义也将具有优先权。Recipe 的 default_options 优先级最低。如果某个 recipe 在某些依赖项选项下完全无法工作,则 recipe 可以检查并相应地引发 ConanInvalidConfiguration 错误。

  • 任何依赖于 mypkg同级软件包也将定义其选项,并且这将是唯一被考虑的选项。换句话说,任何其他软件包首次需要 mypkg 时,都将“冻结”其当前分配的选项值。任何其他稍后依赖于 mypkg 的软件包,在依赖关系图中闭合菱形结构时,都不会对 mypkg 选项产生任何影响。只有第一个需要它的软件包会产生影响。

定义选项值的第二种方法是将它们定义为 important!

警告

important! 语法是实验性的,可能会随时更改或删除。

Recipe 可以使用语法 default_options = {"mypkg/*:myoption!", 123} 将其依赖项选项定义为 important!。这意味着 mypkgmyoption 将不会被其他下游软件包、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 来定义此软件包中涉及的编程语言。目前,CC++ 语言是可能的值。例如,纯 C 软件包将定义如下内容

class ZLib(ConanFile):
    languages = "C"

可以定义多种语言,例如 languages = "C", "C++" 是软件包由 C 和 C++ 源代码构建时的正确定义。

关于 languages 定义,将发生以下情况

  • 如果未定义 languagesC 不是声明的语言,则将在软件包 configure() 时自动删除 compiler.cstd 子设置(以实现向后兼容性)。

  • 如果定义了 languages,但不包含 C++,则将在软件包 configure() 时自动删除 compiler.cppstdcompiler.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 计算中删除所有设置、选项、需求(requirestool_requirespython_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_revisionpackage_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:当软件包之间的关系未知时,定义模式。如果无法推断软件包类型,因为未定义 sharedheader_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 以查找已定位的工件,请使用它。

另请参阅

重要提示

此属性仅在 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() 方法中填写。

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 文件,每个文件都以其独特的修订版本导出。

当选择 scmscm_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":自动管理 fPICshared 选项。添加此实现将在 configureconfig_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_cppstdcompatibility_cstd,它们允许禁用 默认 compatibility.py 扩展 的行为,该扩展认为使用不同的 compiler.cppstdcompiler.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 的所需值来手动传播。