Skip to content

Latest commit

 

History

History
132 lines (83 loc) · 7.38 KB

packaging_policy.md

File metadata and controls

132 lines (83 loc) · 7.38 KB

Packaging Policy

This document gathers all the relevant information regarding the general lines to follow while creating new recipes that will eventually be part of this repository.

Contents

Sources

Origin of sources:

  • Library sources should come from an official origin like the library source code repository or the official release/download webpage.

  • If an official source archive is available, it should be preferred over an auto-generated archive.

Source immutability: Downloaded source code stored under source folder should not be modified. Any patch should be applied to the copy of this source code when a build is executed (basically in build() method).

Building from sources: Recipes should always build packages from library sources.

Sources not accessible:

  • Library sources that are not publicly available will not be allowed in this repository even if the license allows their redistribution.

  • If library sources cannot be downloaded from their official origin or cannot be consumed directly due to their format, the recommendation is to contact the publisher and ask them to provide the sources in a way/format that can be consumed programmatically.

  • In case of needing those binaries to use them as a "build require" for some library, we will consider following the approach of adding it as a system recipe (<build_require>/system) and making those binaries available in the CI machines (if the license allows it).

Dependencies

  • Version range is not allowed.

  • Specify explicit RREV (recipe revision) of dependencies is not allowed.

  • Vendoring in library source code should be removed (best effort) to avoid potential ODR violations. If upstream takes care to rename symbols, it may be acceptable.

  • Only other conan-center recipes are allowed in requires/requirements() and build_requires/build_requirements() of a conan-center recipe.

  • If a requirement is conditional, this condition must not depend on build context. Build requirements don't have this constraint.

  • Forcing options of dependencies inside a conan-center recipe should be avoided, except if it is mandatory for the library.

Build

  • build() method should focus on build only, not installation. During the build, nothing should be written in package folder. Installation step should only occur in package() method.

  • The build itself should only rely on local files. Nothing should be downloaded from internet during this step. If external files are required, they should come from requirements or build_requirements, in addition to source files downloaded in source() or coming from recipe itself.

  • Except CMake and a working build toolchain (compiler, linker, archiver etc), the recipe should not assume that any other build tool is installed on user build machine (like Meson, autotools or pkg-config). On Windows, recipe should not assume that a shell is available (like MSYS2). Therefore, if the buid requires additional build tools, they should be added to build_requirements().

  • It is forbidden to run other conan client commands during build. In other words, if upstream build files call conan under the hood (through cmake-conan for example or any other logic), this logic must be neutralized.

  • Settings from profile should be honored (build_type, compiler.libcxx, compiler.cppstd, compiler.runtime etc).

  • These env vars from profile should be honored and properly propagated to underlying build system during the build: CC, CXX, CFLAGS, CXXFLAGS, LDFLAGS.

Package

  • CMake config files must be removed (they will be generated for consumers by cmake_find_package, cmake_find_package_multi or CMakeDeps generators).

  • pkg-config files must be removed (they will be generated for consumers by pkg_config or PkgConfigDeps generators).

  • On *nix systems, executables and shared libraries should have empty RPATH/RUNPATH/LC_RPATH.

  • On macOS, install name in LC_ID_DYLIB section of shared libs must be @rpath/<libfilename>.

  • Installed files must not contain absolute paths specific to build machine. Relative paths to other packages is also forbidden since relative paths of dependencies during build may not be the same for consumers. Hardcoded relative paths pointing to a location in the package itself are allowed.

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 attibute, but in any case they should add

    def package_id(self):
       self.info.header_only()
  • 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.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:

  • shared (with values True or False). The CI inspects the recipe looking for this option. If it is found, it 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 use their defaults (typically shared=False). 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.

  • header_only (with values True or 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.header_only()

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