Attributes

Package reference

Recipe attributes that can define the main pkg/version@user/channel package reference.

name

The name of the package. A valid name is all lowercase and has:

  • A minimum of 2 and a maximum of 101 characters (though shorter names are recommended).

  • Matches the following regex ^[a-z0-9_][a-z0-9_+.-]{1,100}$: so starts with alphanumeric or _,

    then from 1 to 100 characters between alphanumeric, _, +, . or -.

The name is only necessary for export-ing the recipe into the local cache (export, export-pkg

and create commands), if they are not defined in the command line with --name=<pkgname>.

version

The version of the package. A valid version follows the same rules than the name attribute. In case the version follows semantic versioning in the form X.Y.Z-pre1+build2, that value might be used for requiring this package through version ranges instead of exact versions.

The version is only strictly necessary for export-ing the recipe into the local cache (export, export-pkg and create commands), if they are not defined in the command line with --version=<pkgversion>

The version can be dynamically defined in the command line, and also programmatically in the recipe with the set_version() method.

user

A valid string for the user field follows the same rules than the name attribute. This is an optional attribute. It can be used to identify your own packages with pkg/version@user/channel, where user could be the name of your team, org or company. ConanCenter recipes don’t have user/channel, so they are in the form of pkg/version only. You can also name your packages without user and channel, or using only the user as pkg/version@user.

The user can be specified in the command line with --user=<myuser>

channel

A valid string for the channel field follows the same rules than the name attribute. This is an optional attribute. It is sometimes used to identify a maturity of the package (“stable”, “testing”…), but in general this is not necessary, and the maturity of packages is better managed by putting them in different server repositories.

The channel can be specified in the command line with --channel=<mychannel>

Metadata

Optional metadata, like license, description, author, etc. Not necessary for most cases, but can be useful to have.

description

This is an optional, but recommended text field, containing the description of the package, and any information that might be useful for the consumers. The first line might be used as a short description of the package.

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

License of the target source code and binaries, i.e. the code that is being packaged, not the conanfile.py itself. Can contain several, comma separated licenses. It is a text string, so it can contain any text, but it is strongly recommended that recipes of Open Source projects use SPDX identifiers from the SPDX license list

This will help people wanting to automate license compatibility checks, like consumers of your package, or you if your package has Open-Source dependencies.

class Pkg(ConanFile):
    license = "MIT"

author

Main maintainer/responsible for the package, any format. This is an optional attribute.

class HelloConan(ConanFile):
    author = "John J. Smith (john.smith@company.com)"

topics

Tags to group related packages together and describe what the code is about. Used as a search filter in ConanCenter. Optional attribute. It should be a tuple of strings.

class ProtocInstallerConan(ConanFile):
    name = "protoc_installer"
    version = "0.1"
    topics = ("protocol-buffers", "protocol-compiler", "serialization", "rpc")

homepage

The home web page of the library being packaged.

Used to link the recipe to further explanations of the library itself like an overview of its features, documentation, FAQ as well as other related information.

class EigenConan(ConanFile):
    name = "eigen"
    version = "3.3.4"
    homepage = "http://eigen.tuxfamily.org"

url

URL of the package repository, i.e. not necessarily of the original source code. Recommended, but not mandatory attribute.

class HelloConan(ConanFile):
    name = "hello"
    version = "0.1"
    url = "https://github.com/conan-io/libhello.git"

Requirements

Attribute form of the dependencies simple declarations, like requires, tool_requires. For more advanced way to define requirements, use the requirements(), build_requirements() methods instead.

requires

List or tuple of strings for regular dependencies in the host context, like a library.

class MyLibConan(ConanFile):
    requires = "hello/1.0", "otherlib/2.1@otheruser/testing"

You can specify version ranges, the syntax is using brackets:

class HelloConan(ConanFile):
    requires = "pkg/[>1.0 <1.8]"

Accepted expressions would be:

Expression

Versions in range

Versions outside of range

[>=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

If pre-releases are activated, like defining configuration core.version_ranges:resolve_prereleases=True:

Expression

Versions in range

Versions outside of range

[>=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

See also

tool_requires

List or tuple of strings for dependencies. Represents a build tool like “cmake”. If there is an existing pre-compiled binary for the current package, the binaries for the tool_require won’t be retrieved. They cannot conflict.

class MyPkg(ConanFile):
    tool_requires = "tool_a/0.2", "tool_b/0.2@user/testing"

This is the declarative way to add tool_requires. Check the tool_requires() conanfile.py method to learn a more flexible way to add them.

build_requires

build_requires are used in Conan 2 to provide compatibility with the Conan 1.X syntax, but their use is discouraged in Conan 2 and will be deprecated in future 2.X releases. Please use tool_requires instead of build_requires in your Conan 2 recipes.

test_requires

List or tuple of strings for dependencies in the host context only. Represents a test tool like “gtest”. Used when the current package is built from sources. They don’t propagate information to the downstream consumers. If there is an existing pre-compiled binary for the current package, the binaries for the test_require won’t be retrieved. They cannot conflict.

class MyPkg(ConanFile):
    test_requires = "gtest/1.11.0", "other_test_tool/0.2@user/testing"

This is the declarative way to add test_requires. Check the test_requires() method to learn a more flexible way to add them.

python_requires

This class attribute allows to define a dependency to another Conan recipe and reuse its code. Its basic syntax is:

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

Read more about this attribute in Python requires

python_requires_extend

This class attribute defines one or more classes that will be injected in runtime as base classes of the recipe class. Syntax for each of these classes should be a string like pyreq.MyConanfileBase where the pyreq is the name of a python_requires and MyConanfileBase is the name of the class to use.

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

List or tuple of strings with file names or fnmatch patterns that should be exported and stored side by side with the conanfile.py file to make the recipe work: other python files that the recipe will import, some text file with data to read,…

For example, if we have some python code that we want the recipe to use in a helpers.py file, and have some text file info.txt we want to read and display during the recipe evaluation we would do something like:

exports = "helpers.py", "info.txt"

Exclude patterns are also possible, with the ! prefix:

exports = "*.py", "!*tmp.py"

exports_sources

List or tuple of strings with file names or fnmatch patterns that should be exported and will be available to generate the package. Unlike the exports attribute, these files shouldn’t be used by the conanfile.py Python code, but to compile the library or generate the final package. And, due to its purpose, these files will only be retrieved if requested binaries are not available or the user forces Conan to compile from sources.

This is an alternative to getting the sources with the source() method. Used when we are not packaging a third party library and we have together the recipe and the C/C++ project:

exports_sources = "include*", "src*"

Exclude patterns are also possible, with the ! prefix:

exports_sources = "include*", "src*", "!src/build/*"

Note, if the recipe defines the layout() method and specifies a self.folders.source = "src" it won’t affect where the files (from the exports_sources) are copied. They will be copied to the base source folder. So, if you want to replace some file that got into the source() method, you need to explicitly copy it from the parent folder or even better, from 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

Read only attribute with a dictionary with the keys and values provided in a conandata.yml file format placed next to the conanfile.py. This YAML file is automatically exported with the recipe and automatically loaded with it too.

You can declare information in the conandata.yml file and then access it inside any of the methods of the recipe. For example, a conandata.yml with information about sources that looks like this:

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

Boolean attribute to opt-in injecting the VirtualBuildEnv generated environment while running the source() method.

Setting this attribute to True (default value False) will inject the VirtualBuildEnv generated environment from tool requires when executing the source() method.

 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

Important attributes that define the package binaries model, which settings, options, package type, etc. affect the final packaged binaries.

package_type

Optional. Declaring the package_type will help Conan:

  • To choose better the default package_id_mode for each dependency, that is, how a change in a dependency should affect the package_id to the current package.

  • Which information from the dependencies should be propagated to the consumers, like headers, libraries, runtime information. See here to see what traits are propagated based on the package_type information.

The valid values are:

  • application: The package is an application.

  • library: The package is a generic library. It will try to determine the type of library (from shared-library, static-library, header-library) reading the self.options.shared (if declared) and the self.options.header_only

  • shared-library: The package is a shared library.

  • static-library: The package is a static library.

  • header-library: The package is a header only library.

  • build-scripts: The package only contains build scripts.

  • python-require: The package is a python require.

  • unknown: The type of the package is unknown.

settings

List of strings with the first level settings (from settings.yml) that the recipe needs, because: - They are read for building (e.g: if self.settings.compiler == “gcc”) - They affect the package_id. If a value of the declared setting changes, the package_id has to be different.

The most common is to declare:

settings = "os", "compiler", "build_type", "arch"

Once the recipe is loaded by Conan, the settings are processed and they can be read in the recipe, also the sub-settings:

settings = "os", "arch"

def build(self):
    if self.settings.compiler == "gcc":
        if self.settings.compiler.cppstd == "gnu20":
            # do some special build commands

If you try to access some setting that doesn’t exist, like self.settings.compiler.libcxx for the msvc setting, Conan will fail telling that libcxx does not exist for that compiler.

If you want to do a safe check of settings values, you could use the get_safe() method:

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")

The get_safe() method returns None if that setting or sub-setting doesn’t exist and there is no default value assigned.

It’s also feasible to check the possible values defined in settings.yml using the possible_values() method:

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)}")

As you can see above, doing self.settings.possible_values() returns the whole settings.yml as a Python dict-like object, and doing self.settings.compiler.version.possible_values() for instance returns the available versions for the compiler used by the consumer.

If you want to do a safe deletion of settings, you could use the rm_safe() method. For example, in the configure() method a typical pattern for a C library would be:

def configure(self):
    self.settings.rm_safe("compiler.libcxx")
    self.settings.rm_safe("compiler.cppstd")

options

Dictionary with traits that affects only the current recipe, where the key is the option name and the value is a list of different values that the option can take. By default any value change in an option, changes the package_id. Check the default_options and default_build_options fields to define default values for the options.

Values for each option can be typed or plain strings ("value", True, 42,…).

There are two special values:

  • None: Allow the option to have a None value (not specified) without erroring.

  • "ANY": For options that can take any value, not restricted to a set.

class MyPkg(ConanFile):
    ...
    options = {
        "shared": [True, False],
        "option1": ["value1", "value2"],
        "option2": ["ANY"],
        "option3": [None, "value1", "value2"],
        "option4": [True, False, "value"],
}

Once the recipe is loaded by Conan, the options are processed and they can be read in the recipe. You can also use the method .get_safe() (see settings attribute) to avoid Conan raising an Exception if the option doesn’t exist:

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

In boolean expressions, like if self.options.shared:

  • equals True for the values True, "True" and "true", and any other value that would be evaluated the same way in Python code.

  • equals False for the values False, "False" and "false", also for the empty string and for 0 and "0" as expected.

Notice that a comparison using is is always False because the types would be different as it is encapsulated inside a Python class.

If you want to do a safe deletion of options, you could use the rm_safe() method. For example, in the config_options() method a typical pattern for Windows library would be:

def config_options(self):
    if self.settings.os == "Windows":
        self.options.rm_safe("fPIC")

See also

  • Read the Getting started, creating packages to know how to declare and how to define a value to an option.

  • Removing options in the package_id() method. <MISSING PAGE>

  • About the package_type and how it plays when a shared option is declared. <MISSING PAGE>

default_options

The attribute default_options defines the default values for the options, both for the current recipe and for any requirement. This attribute should be defined as a python dictionary.

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}

You can also assign default values for options of your requirements using “<reference_pattern>: option_name”, being a valid reference_pattern a name/version or any pattern with * like the example above.

Warning

Defining options values in recipes does not have strong guarantees, please check this FAQ about options values for dependencies. The recommended way to define options values is in profile files.

You can also set the options conditionally to a final value with configure() instead of using 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

Take into account that if a value is assigned in the configure() method it cannot be overridden.

There are 2 different ways that a recipe can try to define options values for its dependencies. Using default_options = {"mypkg/*:myoption", 123} the current recipe can define the 123 value to the dependency mypkg myoption. This way of defining options for dependencies has some limitations:

  • Any other downstream user of the current recipe that defines the same option for mypkg will have precedence, overwriting the current recipe 123 value. Also any definition in the profile or command line will also have precedence. The recipe default_options have the least precedence. If a recipe will not work at all with some dependencies options, then recipes can check and raise ConanInvalidConfiguration errors accordingly.

  • Any sibling package that depends on mypkg will also define its options and it will be the only one being taken into account. In other words, the first time mypkg is required by any other package will “freeze” its currently assigned options values. Any other package that depends later on mypkg, closing the diamond structures in the dependency graph will not have any influence on the mypkg options. Only the first one requiring it will.

The second way to define the options values is defining them as important!.

Warning

The important! syntax is experimental and can be changed or removed at any time.

A recipe can define its dependencies options as important! with the syntax default_options = {"mypkg/*:myoption!", 123}. That means that the mypkg myoption will not be overriden by other downstream packages, profile or command line doing regular definition of options (like -o *:myoption=234).

But there are 2 cases in which this will still not define the final value of the dependency:

  • If any downstream recipe, command line or profile also uses the myoption! syntax, that will also have precedence and override the value upstream

  • If there is any other package that requires first mypkg, the values defined at that moment will still have precedence.

In general the recommendation for defining options values is to do it in profile files, not in recipes, as in-recipe definition can be more complicated specially for complex dependency graphs.

default_build_options

The attribute default_build_options defines the default values for the options in the build context and is typically used for defining options for 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

The options_description attribute is an optional attribute that can be defined in the form of a dictionary where the key is the option name and the value is a description of the option in text format. This attribute is useful for providing additional information about the functionality and purpose of each option, particularly when the option is not self-explanatory or has complex or special behavior.

The format for each dictionary entry should be:

  • Key: Option name. Must be a string and must match one of the keys in the options dictionary.

  • Value: Description of the option. Must be a string and can be as long as necessary.

For example:

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

Warning

This feature is experimental and subject to breaking changes. See the Conan stability section for more information.

From Conan 2.4, the conanfile.py recipe attribute languages can be used to define the programming languages involved in this package. At the moment the C and C++ languages are the possible values. For example a pure C package would define something as:

class ZLib(ConanFile):
    languages = "C"

It is possible to define more than one language, for example languages = "C", "C++" is the correct definition when a package is built from both C and C++ sources.

Regarding languages definition, the following will happen:

  • If no languages is defined or C is not a declared language, compiler.cstd subsetting will be automatically removed at package configure() time (to achieve backward compatibility).

  • If languages is defined, but it doesn’t contain C++, compiler.cppstd and compiler.libcxx subsettings will be automatically removed at package configure() time.

info

Object used exclusively in package_id() method:

  • The :ref:package_id method<reference_conanfile_methods_package_id> to control the unique ID for a package:

    def package_id(self):
        self.info.clear()
    

The self.info.clear() method removes all the settings, options, requirements (requires, tool_requires, python_requires) and configuration (conf) from the package_id computation, so the package_id will always result in the same binary, irrespective of all those things. This would be the typical case of a header-only library, in which the packaged artifacts (files) are always identical.

package_id_{embed,non_embed,python,unknown}_mode

The package_id_embed_mode, package_id_non_embed_mode, package_id_python_mode, package_id_unknown_mode are class attributes that can be defined in recipes to define the effect they have on their consumers package_id. Can be declared as:

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"

In general, the Conan defaults are good ones, and allow providing users good control over when the consumers need to be re-built from source or not. Also, the Conan defaults can be changed globally in the global.conf file (they should be changed globally for all users, CI, etc.) via the core.package_id:xxxx configurations. The in-recipe attribute definition is useful to define behavior that deviates from the defaults.

Possible values are (following the semver definition of MAJOR.MINOR.PATCH):

  • patch_mode: New patches, minors, and major releases of the package will require a new binary (new package_id) of the consumers. New recipe revisions will not require new binaries of the consumers. For example if we create a new pkg/1.0.1 version and some consumer has requires = "pkg/[>=1.0 <2.0]", such a consumer will build a new binary against this specific new 1.0.1 version. But if we just change the recipe, producing a new recipe_revision, the consumers will not require building a new binary.

  • minor_mode: New minor and major releases of this package will require a new binary of the consumers. New patches and new revisions will not require new binaries of the consumers. This is the default for the “non-embed-mode”, as it allows fine control by the users to decide when to rebuild things or not.

  • major_mode: Only new major releases will require new binaries. Any other modifications and new versions will not require new binaries from the consumers.

  • full_mode: The full identifier of this package, including pkgname/version@user/channel#recipe_revision:package_id will be used in the consumers package_id, then requiring to build a new binary of the consumer for every change of this package (as any change either in source or configuration will produce a different recipe_revision or package_id respectively). This is the default for the “embed-mode”.

  • unrelated_mode: No change in this package will ever produce a new binary in the consumer.

  • revision_mode: Uses the pkgname/version@user/channel#recipe_revision in the consumers’ package_id, that is the full reference except the package_id of the dependency.

The 4 different attributes are:

  • package_id_embed_mode: Define the mode for “embedding” cases, that is, a shared library linking a static library, an application linking a static library, an application or a library linking a header-only library. The default for this mode is full_mode

  • package_id_non_embed_mode. Define the mode for “non-embedding” cases, that is, a shared library linking another shared library, a static library linking another static library, an application executable linking a shared library. The default for this mode is minor_mode.

  • package_id_unknown_mode: Define the mode when the relationship between packages is unknown. If it is not possible to deduce the package type, because there are no shared or header_only options defined, or because package_type is not defined, then, this mode will be used. The default for this mode is semver_mode (similar to Conan 1.X behavior).

  • package_id_python_mode: Define the mode for consumers of python_requires. By default it will be minor_mode, and it is strongly recommended to use this default, and not define the package_id_python_mode. This attribute is provided for completeness and exceptional cases like temporary migrations.

See also

Read the binary model reference for a full view of the Conan binary model.

Build

generators

List or tuple of strings with names of generators.

class MyLibConan(ConanFile):
    generators = "CMakeDeps", "CMakeToolchain"

The generators can also be instantiated explicitly in the generate() method.

from conan.tools.cmake import CMakeToolchain

class MyLibConan(ConanFile):
    ...

    def generate(self):
        tc = CMakeToolchain(self)
        tc.generate()

build_policy

Controls when the current package is built during a conan install. The allowed values are:

  • "missing": Conan builds it from source if there is no binary available.

  • "never": This package cannot be built from sources, it is always created with conan export-pkg

  • None (default value): This package won’t be built unless the policy is specified in the command line (e.g --build=foo*)

     class PocoTimerConan(ConanFile):
         build_policy = "missing"
    

win_bash

When True it enables the new run in a subsystem bash in Windows mechanism.

from conan import ConanFile

class FooRecipe(ConanFile):
    ...
    win_bash = True

It can also be declared as a property based on any condition:

from conan import ConanFile

class FooRecipe(ConanFile):
    ...


    @property
    def win_bash(self):
        return self.settings.arch == "armv8"

win_bash_run

When True it enables running commands in the "run" scope, to run them inside a 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

The folder in which the source code lives. The path is built joining the base directory (a cache directory when running in the cache or the output folder when running locally) with the value of folders.source if declared in the layout() method.

Note that the base directory for the source_folder when running in the cache will point to the base folder of the build unless no_copy_source is set to True. But anyway it will always point to the correct folder where the source code is.

export_sources_folder

The value depends on the method you access it:

  • At source(self): Points to the base source folder (that means self.source_folder but without taking into account the folders.source declared in the layout() method). The declared exports_sources are copied to that base source folder always.

  • At exports_sources(self): Points to the folder in the cache where the export sources have to be copied.

build_folder

The folder used to build the source code. The path is built joining the base directory (a cache directory when running in the cache or the output folder when running locally) with the value of folders.build if declared in the layout() method.

package_folder

The folder to copy the final artifacts for the binary package. In the local cache a package folder is created for every different package ID.

The most common usage of self.package_folder is to copy the files at the package() method:

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

The folder where the recipe conanfile.py is stored, either in the local folder or in the cache. This is useful in order to access files that are exported along with the recipe, or the origin folder when exporting files in export(self) and export_sources(self) methods.

The most common usage of self.recipe_folder is in the export(self) and export_sources(self) methods, as the folder from where we copy the files:

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

The self.recipe_metadata_folder (experimental) can be used in the export() and export_sources() and source() methods to save or copy recipe metadata files. See metadata section for more information.

package_metadata_folder

The self.package_metadata_folder (experimental) can be used in the generate(), build() and package() methods to save or copy package metadata files. See metadata section for more information.

no_copy_source

The attribute no_copy_source tells the recipe that the source code will not be copied from the source_folder to the build_folder. This is mostly an optimization for packages with large source codebases or header-only, to avoid extra copies.

If you activate no_copy_source=True, it is mandatory that the source code must not be modified at all by the configure or build scripts, as the source code will be shared among all builds.

The recipes should always use self.source_folder attribute, which will point to the build folder when no_copy_source=False and will point to the source folder when no_copy_source=True.

See also

Read header-only packages section for an example using no_copy_source attribute.

test_package_folder

The test_package_folder class attribute allows defining in recipe a different default test_package folder for conan create commands. When a conan create runs, after the package is created in the cache, it will look for a test_package folder, or for the folder specified in the --test-folder=xxx argument, and launch the package test.

This attribute allows to change that default name:

import os
from conan import ConanFile

class Pkg(ConanFile):
    test_package_folder = "my/test/folder"

It allows to define any folder, always relative to the location of the conanfile.py.

Layout

folders

The folders attribute has to be set only in the layout() method. Please check the layout() method documentation to learn more about this attribute.

cpp

Object storing all the information needed by the consumers of a package: include directories, library names, library paths… Both for editable and regular packages in the cache. It is only available at the layout() method.

  • self.cpp.package: For a regular package being used from the Conan cache. Same as declaring self.cpp_info at the package_info() method.

  • self.cpp.source: For “editable” packages, to describe the artifacts under self.source_folder

  • self.cpp.build: For “editable” packages, to describe the artifacts under self.build_folder.

The cpp attribute has to be set only in the layout() method. Please check the layout() method documentation to learn more about this attribute.

layouts

The layouts attribute has to be set only in the layout() method. Please check the layout() method documentation to learn more about this attribute.

The layouts attribute contains information about environment variables and conf that would be path-dependent, and as a result it would contain a different value when the package is in editable mode, or when the package is in the cache. The layouts sub-attributes are:

  • self.layouts.build: information related to the relative self.folders.build

  • self.layouts.source: information related to the relative self.folders.source

  • self.layouts.package: information related to the final package_folder

Each one of those will contain:

  • buildenv_info: environment variables build information for consumers (equivalent to self.buildenv_info in package_info())

  • runenv_info: environment variables run information for consumers (equivalent to self.runenv_info in package_info())

  • conf_info: configuration information for consumers (equivalent to self.conf_info in package_info()). Note this is only automatically propagated to self.conf of consumers when this package is a direct tool_require.

For example, if we had an androidndk recipe that contains the AndroidNDK, and we want to have that recipe in “editable” mode, it is necessary where the androidndk will be locally, before being in the created package:

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 information for consumers

cpp_info

Same as using self.cpp.package in the layout() method. Use it if you need to read the package_folder to locate the already located artifacts.

See also

Important

This attribute is only defined inside package_info() method being None elsewhere.

buildenv_info

For the dependant recipes, the declared environment variables will be present during the build process. Should be only filled in the package_info() method.

Important

This attribute is only defined inside package_info() method being None elsewhere.

def package_info(self):
    self.buildenv_info.append_path("PATH", self.package_folder)

See also

Check the reference of the Environment object to know how to fill the self.buildenv_info.

runenv_info

For the dependant recipes, the declared environment variables will be present at runtime. Should be only filled in the package_info() method.

Important

This attribute is only defined inside package_info() method being None elsewhere.

def package_info(self):
    self.runenv_info.define_path("RUNTIME_VAR", "c:/path/to/exe")

See also

Check the reference of the Environment object to know how to fill the self.runenv_info.

conf_info

Configuration variables to be passed to the dependant recipes. Should be only filled in the package_info() method.

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")

generator_info

Warning

This feature is experimental and subject to breaking changes. See the Conan stability section for more information.

Generators to be passed to the dependant recipes. Should be only filled in the package_info() method.

deprecated

This attribute declares that the recipe is deprecated, causing a user-friendly warning message to be emitted whenever it is used

For example, the following code:

from conan import ConanFile

class Pkg(ConanFile):
    name = "cpp-taskflow"
    version = "1.0"
    deprecated = True

may emit a warning like:

cpp-taskflow/1.0: WARN: Recipe 'cpp-taskflow/1.0' is deprecated. Please, consider changing your requirements.

Optionally, the attribute may specify the name of the suggested replacement:

from conan import ConanFile

class Pkg(ConanFile):
    name = "cpp-taskflow"
    version = "1.0"
    deprecated = "taskflow"

This will emit a warning like:

cpp-taskflow/1.0: WARN: Recipe 'cpp-taskflow/1.0' is deprecated in favor of 'taskflow'. Please, consider changing your requirements.

If the value of the attribute evaluates to False, no warning is printed.

provides

This attribute declares that the recipe provides the same functionality as other recipe(s). The attribute is usually needed if two or more libraries implement the same API to prevent link-time and run-time conflicts (ODR violations). One typical situation is forked libraries. Some examples are:

If Conan encounters two or more libraries providing the same functionality within a single graph, it raises an error:

At least two recipes provides the same functionality:
- 'libjpeg' provided by 'libjpeg/9d', 'libjpeg-turbo/2.0.5'

The attribute value should be a string with a recipe name or a tuple of such recipe names.

For example, to declare that libjpeg-turbo recipe offers the same functionality as libjpeg recipe, the following code could be used:

from conan import ConanFile

class LibJpegTurbo(ConanFile):
    name = "libjpeg-turbo"
    version = "1.0"
    provides = "libjpeg"

To declare that a recipe provides the functionality of several different recipes at the same time, the following code could be used:

from conan import ConanFile

class OpenBLAS(ConanFile):
    name = "openblas"
    version = "1.0"
    provides = "cblas", "lapack"

If the attribute is omitted, the value of the attribute is assumed to be equal to the current package name. Thus, it’s redundant for libjpeg recipe to declare that it provides libjpeg, it’s already implicitly assumed by Conan.

Other

dependencies

Conan recipes provide access to their dependencies via the self.dependencies attribute.

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

conf

In the self.conf attribute we can find all the conf entries declared in the [conf] section of the profiles. in addition of the declared self.conf_info entries from the first level tool requirements. The profile entries have priority.

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"))

Note

The conf attribute is a read-only attribute. It can only be defined in profiles and command lines, but it should never be set by recipes. Recipes can only read its value via self.conf.get() method.

Output

Output contents

Use the self.output to print contents to the 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")

Additional output methods are available and you can produce different outputs with different colors. See the output documentation for the list of available output methods.

revision_mode

This attribute allow each recipe to declare how the revision for the recipe itself should be computed. It can take three different values:

  • "hash" (by default): Conan will use the checksum hash of the recipe manifest to compute the revision for the recipe.

  • "scm": if the project is inside a Git repository the commit ID will be used as the recipe revision. If there is no repository it will raise an error.

  • "scm_folder": This configuration applies when you have a mono-repository project, but still want to use scm revisions. In this scenario, the revision of the exported conanfile.py will correspond to the commit ID of the folder where it’s located. This approach allows multiple conanfile.py files to exist within the same Git repository, with each file exported under its distinct revision.

When scm or scm_folder is selected, the Git commit will be used, but by default the repository must be clean, otherwise it would be very likely that there are uncommitted changes and the build wouldn’t be reproducible. So if there are dirty files, Conan will raise an error. If there are files that can be dirty in the repo, but do not belong at all to the recipe or the package, then it is possible to exclude them from the check with the core.scm:excluded configuration, which is a list of patterns (fnmatch) to exclude.

upload_policy

Controls when the current package built binaries are uploaded or not

  • "skip": The precompiled binaries are not uploaded. This is useful for “installer” packages that just download and unzip something heavy (e.g. android-ndk), and is useful together with the build_policy = "missing"

    class Pkg(ConanFile):
        upload_policy = "skip"
    

required_conan_version

Recipes can define a module level required_conan_version that defines a valid version range of Conan versions that can load and understand the current conanfile.py. The syntax is:

from conan import ConanFile

required_conan_version = ">=2.0"

class Pkg(ConanFile):
    pass

Version ranges as in requires are allowed. Also there is a global.conf file core:required_conan_version configuration that can define a global minimum, maximum or exact Conan version to run, which can be very convenient to maintain teams of developers and CI machines to use the desired range of versions.

implements

A list is used to define a series of option configurations that Conan will handle automatically. This is especially handy for avoiding boilerplate code that tends to repeat in most of the recipes. The syntax is as follows:

from conan import ConanFile

class Pkg(ConanFile):
    implements = ["auto_shared_fpic", "auto_header_only", ...]

Currently these are the automatic implementations provided by Conan:

  • "auto_shared_fpic": automatically manages fPIC and shared options. Adding this implementation will have both effect in the configure and config_options steps when those methods are not explicitly defined in the recipe.

  • "auto_header_only": automatically manages the package ID clearing settings. Adding this implementation will have effect in the package_id step when the method is not explicitly defined in the recipe.

Warning

This is a 2.0-only feature, and it will not work in 1.X

alias

Warning

While aliases can technically still be used in Conan 2, their usage is not recommended and they may be fully removed in future releases. Users are encouraged to adapt to the newer versioning features for a more standardized and efficient package management experience.

In Conan 2, the alias attribute remains a part of the recipe, allowing users to define an alias for a package version. Normally, you would create one using the conan new command with the alias template and the exporting the recipe with conan export:

$ conan new alias -d name=mypkg -d version=latest -d target=1.0
$ conan export .

Note that when requiring the alias, you must place the version in parentheses () to explicitly declare the use of an alias as a requirement:

class Consumer(ConanFile):

    ...
    requires = "mypkg/(latest)"
    ...

extension_properties

The extensions_properties attribute is a dictionary intended to define and pass information from the recipes to the Conan extensions.

At the moment, the only defined properties are compatibility_cppstd and compatibility_cstd, that allows disabling the behavior of the default compatibility.py extension, that considers binaries built with different compiler.cppstd and compiler.cstd values ABI-compatible among them. To disable this behavior for the current package, it is possible to do it with:

class Pkg(ConanFile):
    extension_properties = {"compatibility_cppstd": False}

If it is necessary to do it conditionally, it is also possible to define its value inside recipe compatibility() method:

class Pkg(ConanFile):

    def compatibility(self):
        self.extension_properties = {"compatibility_cppstd": False}