conan-center-index

ConanFile Attributes

The ConanFile class has a lot of different properties that can help consumers search for projects, help the client build packages for different configurations or are known by ConanCenter’s build service and have special meaning.

Contents

Attributes

These are a key feature which allows the Conan client to understand, identify, and expose recipes and which project they expose.

In ConanCenter, there are a few conventions that need to be respected to ensure recipes can be discovered there conan search command of through the web UI.

Name

Same as the recipe folder and always lowercase.

Please see the FAQs for:

Version

The version attribute MUST NOT be added to any recipe - with exception to “system packages”.

ConanCenter specific releases format

The notation shown below is used for publishing packages which do not match the original library’s official releases.

There are two cases to consider:

In order to create reproducible builds, we also “commit-lock” to the latest commit on that day, so the sources should point to the commit hash of that day. Otherwise, users would get inconsistent results over time when rebuilding the package.

License Attribute

The license attribute is a mandatory field which provides the legal information that summarizes the contents saved in the package. These follow the SPDX license as a standard. This is for consumers, in particular in the enterprise sector, that do rely on SDPX compliant identifiers so that they can flag this as a custom license text.

In case the license changes in a new release, the recipe should update the license attribute accordingly:

class LibfooConan(ConanFile):
    license = "MIT"

    def configure (self):
       # INFO: Version < 2.0 the license was MIT, but changed to BSD-3-Clause now.
       if Version(self.version) >= "2.0.0":
          self.license = "BSD-3-Clause"

Order of methods and attributes

Prefer the following order of documented methods in python code (conanfile.py, test_package/conanfile.py):

For conan create the order is listed here.

Settings

As a general rule, recipes should set the settings attribute to: os, arch, compiler and build_type, and let Conan compute the package ID based on the settings. Some exceptions apply, as detailed below. For cases not covered here, please reach out to the Conan Center maintainers team for assistance. The following list is not exhaustive:

Options

Recipes can list any number of options with any meaning, and defaults are up to the recipe itself. The CI cannot enforce anything in this direction. However, there are a couple of options that have a special meaning for the CI.

Adding options is often needed to toggle specific library features on/off. Regardless of the default, there is a strong preference for using positive naming for options. In order to avoid the fragmentation, we recommend using the following naming conventions for such options:

The actual recipe code then may look like:

    options = {"enable_locales": [True, False]} # Changes which files are compiled in to the library
    default_options = {"enable_locales": True}
    options = {"with_zlib": [True, False]} # Will add a `self.requires` with more deps to link against
    default_options = {"with_zlib": True}
    options = {"use_tzdb": [True, False]} # Might install more headers to expose more features
    default_options = {"use_tzdb": True}

Having the same naming conventions for the options helps consumers. It allows users to specify options with wildcards: -o *:with_threads=True. Therefore, the with_threads options will be enabled for all packages in the graph that support it.

Predefined Options and Known Defaults

By default recipes should use */*:shared=False with */*:fPIC=True. If supported, &:header_only=False is the default.

Usage of each option should follow the rules:

Options to Avoid

### Removing from package_id

By default, options are included in the calculation for the package_id (docs). Options which do not impact the generated packages should be deleted, for instance adding a #define for a package.

def package_id(self):
   del self.info.options.enable_feature

def package_info(self):
   if self.options.enable_feature:
      self.cpp_info.defines.append("FOBAR_FEATURE=1")