This document gathers all the relevant information regarding the general lines to follow while writing either the build()
or the package()
methods.
Both methods often use build helpers to build binaries and install them into the package_folder
.
-
build()
method should focus on build only, not installation. During the build, nothing should be written inpackage
folder. Installation step should only occur inpackage()
method. -
The build itself should only rely on local files. Nothing should be downloaded from the internet during this step. If external files are required, they should come from
requirements
orbuild_requirements
in addition to source files downloaded insource()
or coming from the recipe itself throughexport()
orexport_sources()
. -
Except for CMake, a working build toolchain (compiler, linker, archiver, etc.), and a "native generator" (
make
on *nix platforms,mingw32-make
for MinGW,MSBuild
/NMake
for Visual Studio), the recipe should not assume that any other build tool is installed on the user-build machine (like Meson, autotools, or pkg-config). On Windows, the recipe should not assume that a shell is available (like MSYS2). Therefore, if the build method requires additional tools, they should be added tobuild_requirements()
. Tools explicitly marked as available by users through conf liketools.gnu:make_program
,tools.gnu:pkg_config
,tools.microsoft.bash:path
,tools.microsoft.bash:subsystem
should be taken into account to conditionally inject a build requirement (these conf should have precedence over build requirement equivalent hardcoded in the recipe). -
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 removed. -
Settings from profile should be honored (
build_type
,compiler.libcxx
,compiler.cppstd
,compiler.runtime
etc). -
Compiler paths from host profile should be honored and properly propagated to underlying build system during the build:
compiler type conf / env var C compiler c
key oftools.build:compiler_executables
, otherwiseCC
environment variableC++ compiler cpp
key oftools.build:compiler_executables
, otherwiseCXX
environment variableASM compiler asm
key oftools.build:compiler_executables
, otherwiseCCAS
environment variableCUDA compiler cuda
key oftools.build:compiler_executables
Fortran compiler fortran
key oftools.build:compiler_executables
, otherwiseFC
environment variableObjective-C compiler objc
key oftools.build:compiler_executables
Objective-C++ compiler objcpp
key oftools.build:compiler_executables
Resource files compiler rc
key oftools.build:compiler_executables
, otherwiseRC
environment variableArchiver AR
environment variableLinker LD
environment variableThey should be curated on the fly if underlying build system expects a specific format (no spaces in path, forward slash instead of back slash, etc).
-
These compiler and linker conf from host profile should be honored and propagated to underlying build system during the build:
tools.build:cflags
tools.build:cxxflags
tools.build:defines
tools.build:sharedlinklags
tools.build:exelinkflags
tools.apple:enable_bitcode
(only if host OS isiOS
/watchOS
/tvOS
)
-
Multithread build (if supported by underlying build system):
- if some steps are sensitive to race conditions, monothread should be enforced.
- otherwise multithreaded build should be enabled with a number of cores controlled by
tools.build:jobs
conf from host profile if it is set, otherwise to all cores of build machine.
-
CMake config files must be removed. They will be generated for consumers by
CMakeDeps
generator (or legacycmake_find_package
/cmake_find_package_multi
generators). -
pkg-config files must be removed. They will be generated for consumers by
PkgConfigDeps
generator (or legacypkg_config
generator). -
On *nix systems, executables and shared libraries should have empty
RPATH
/RUNPATH
/LC_RPATH
. Though, a relative path pointing inside package itself is allowed. -
On Apple OS family:
- shared libs: name field of
LC_ID_DYLIB
load command must be@rpath/<libfilename>
. - shared libs & executables: name field of each
LC_LOAD_DYLIB
load command should be@rpath/<libdependencyfilename>
(except those refering to system libs or frameworks).
- shared libs: name field of
-
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.
-
Static and shared flavors of the same library must not be packaged together.
The Conan's documentation is always a good place for technical details. General patterns about how they can be used for OSS in ConanCenterIndex can be found in the package templates sections. These are excellent to copy and start from.
If you are looking for header-only projects, you can take a look on header-only template. Also, Conan Docs have a section about how to package header-only libraries.
For C/C++ projects which use CMake for building, you can take a look on cmake package template.
Another common use case for CMake based projects, both header only and compiled, is modeling components to match the find_package
and export the correct targets from Conan's generators. A basic examples of this is cpu_features, a moderate/intermediate example is cpprestsdk, and a very complex example is OpenCV.
There is an autotools package template amiable to start from.
However, if you need to use autotools for building, you can take a look on libalsa, kmod, libcap.
Many projects offer pkg-config's *.pc
files which need to be modeled using components. A prime example of this is Wayland.
For cases where a project only offers source files, but not a build script, you can add CMake support, but first, contact the upstream and open a PR offering building support. If it's rejected because the author doesn't want any kind of build script, or the project is abandoned, CCI can accept your build script. Take a look at Bzip2 and DirectShowBaseClasses as examples.
Note: For exceptional cases where only system packages can be used and a regular Conan package may result in an incompatible and fragile package, a separated system package may be created. See the FAQs for more.
The SystemPackageTool can easily manage a system package manager (e.g. apt,
pacman, brew, choco) and install packages which are missing on Conan Center but available for most distributions. It is key to correctly fill in the cpp_info
for the consumers of a system package to have access to whatever was installed.
As example there is xorg. Also, it will require an exception rule for conan-center hook, a pull request should be open to allow it over the KB-H032.