Files
conan-center-index/docs/adding_packages/conanfile_attributes.md
Chris Mc 073a9a9909 (#14491) Docs: split up reviewing into new file sections
* cleanup patches from #14377

* subfolder dont exist with new generators

* styling is not enforced

* move attribute to new home + fix FAQ spelling

* delete out date CMake docs from older generators

* move test package docs

* delete empty file :)

* fix links

* wording + remove duplicated sections

* improve mention of future work

* [docs] Regenerate tables of contents

Co-authored-by: prince-chrismc <prince-chrismc@users.noreply.github.com>

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: prince-chrismc <prince-chrismc@users.noreply.github.com>
2022-12-02 14:25:04 +01:00

8.0 KiB

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

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 test packages recipes should append the following methods:

  • deploy
  • test

the order above resembles the execution order of methods on CI. therefore, for instance, build is always executed before package method, so build should appear before the package in conanfile.py.

License Attribute

The mandatory license attribute of each recipe should be a SPDX license short Identifiers when applicable.

Where the SPDX guidelines do not apply, packages should do the following:

  • When no license is provided or it's under the "public domain" - these are not a license by itself. Thus, we have equivalent licenses that should be used instead. If a project fall under these criteria it should be identified as the Unlicense license.
  • When a custom (e.g. project specific) license is given, the value should be set to LicenseRef- as a prefix, followed by the name of the file which contains the custom license. See this example. For more details, read this conversation.

Settings

All recipes should list the four settings os, arch, compiler and build_type so Conan will compute a different package ID for each combination. There are some particular cases for this general rule:

  • Recipes for header only libraries might omit the settings attribute, but in any case they should add

    def package_id(self):
       self.info.clear()
    
  • Recipes that provide applications (b2, cmake, make,...) that are generally used as a build requires, must list all the settings as well, but they should remove the compiler one in the corresponding method unless the recipe provides also libraries that are consumed by other packages:

    def package_id(self):
       del self.info.settings.compiler
    

    Removing the compiler setting reduces the number of configurations generated by the CI, reducing the time and workload and, at the same time, demonstrates the power of Conan behind the package ID logic.

    Note

    Intentionally, the build_type setting should not be removed from the package ID in this case. Preserving this setting will ensure that the package ID for Debug and Release configurations will be different and both binaries can be available in the Conan cache at the same time. This enable consumers to switch from one configuration to the other in the case they want to run or to debug those executables.

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:

  • enable_ / disable_
  • with_ / without_
  • use_

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

ConanCenter supports many combinations, these are outline in the supported configurations document for each platform. By default recipes should use shared=False with fPIC=True. If support, header_only=False is the default.

Usage of each option should follow the rules:

  • shared (with values True or False). The CI inspects the recipe looking for this option. The default should be shared=False and will generate all the configurations with values shared=True and shared=False.

    Note

    : The CI applies shared=True only to the package being built, while every other requirement will shared=False. To consume everything as a shared library you will set --build=always and/or -o *:shared=True) It's important to keep this in mind when trying to consume shared packages from ConanCenter as their requirements were linked inside the shared library. See FAQs for more information.

  • fPIC (with values True or False). The default should be fPIC=True and will generate all the configurations with values fPIC=True and fPIC=False. This option does not make sense on all the support configurations so it should be removed.

     def config_options(self):
         if self.settings.os == "Windows":
             del self.options.fPIC
    
    def configure(self):
       if self.options.shared:
          self.options.rm_safe("fPIC")
    
  • header_only (with values True or False). The default should be header_only=False. If the CI detects this option, it will generate all the configurations for the value header_only=False and add one more configuration with header_only=True. Only one package will be generated for header_only=True, so it is crucial that the package is actually a header only library, with header files only (no libraries or executables inside).

    Recipes with such option should include the following in their package_id method

    def package_id(self):
       if self.options.header_only:
          self.info.clear()
    

    ensuring that, when the option is active, the recipe ignores all the settings and only one package ID is generated.

Options to Avoid

  • build_testing should not be added, nor any other related unit test option. Options affect the package ID, therefore, testing should not be part of that. Instead, use Conan config skip_test feature:

    def generate(self):
       tc = CMakeToolChain(self)
       tc.variables['BUILD_TESTING'] = not self.conf.get("tools.build:skip_test", default=true, check_type=bool)
    

    The skip_test configuration is supported by CMake and Meson.