profiles¶
Introduction to profiles¶
Conan profiles allow users to set a complete configuration set for settings, options, environment variables (for build time and runtime context), tool requirements, and configuration variables in a file.
They have this structure:
[settings]
arch=x86_64
build_type=Release
os=Macos
[options]
MyLib:shared=True
[buildenv]
VAR1=value
[tool_requires]
tool1/0.1@user/channel
*: tool4/0.1@user/channel
[conf]
tools.build:jobs=2
Profiles can be created with the detect
option in conan profile command,
and edited later. If you don’t specify a name, the command will create the default
profile:
$ conan profile detect
apple-clang>=13, using the major as version
Detected profile:
[settings]
arch=x86_64
build_type=Release
compiler=apple-clang
compiler.cppstd=gnu17
compiler.libcxx=libc++
compiler.version=14
os=Macos
WARN: This profile is a guess of your environment, please check it.
WARN: Defaulted to cppstd='gnu17' for apple-clang.
WARN: The output of this command is not guaranteed to be stable and can change in future Conan versions.
WARN: Use your own profile files for stability.
Saving detected profile to [CONAN_HOME]/profiles/default
Note
A note about the detected C++ standard by Conan
Conan will always set the default C++ standard as the one that the detected compiler
version uses by default, except for the case of macOS using apple-clang. In this case,
for apple-clang>=11, it sets compiler.cppstd=gnu17
. If you want to use a different
C++ standard, you can edit the default profile file directly.
$ conan profile detect --name myprofile
Found apple-clang 14.0
apple-clang>=13, using the major as version
Detected profile:
[settings]
arch=x86_64
build_type=Release
compiler=apple-clang
compiler.cppstd=gnu17
compiler.libcxx=libc++
compiler.version=14
os=Macos
WARN: This profile is a guess of your environment, please check it.
WARN: Defaulted to cppstd='gnu17' for apple-clang.
WARN: The output of this command is not guaranteed to be stable and can change in future Conan versions.
WARN: Use your own profile files for stability.
Saving detected profile to [CONAN_HOME]/profiles/myprofile
Profile files can be used with -pr
/--profile
option in many commands like conan install or
conan create commands. If you don’t specify any profile at all, the default
profile will be
always used:
$ conan create .
$ conan create . -pr=myprofile
Profiles can be located in different folders:
$ conan install . -pr /abs/path/to/myprofile # abs path
$ conan install . -pr ./relpath/to/myprofile # resolved to current dir
$ conan install . -pr ../relpath/to/myprofile # resolved to relative dir
$ conan install . -pr myprofile # resolved to [CONAN_HOME]/profiles/myprofile
Listing existing profiles in the profiles folder can be done like this:
$ conan profile list
Profiles found in the cache:
default
myprofile1
myprofile2
...
You can also show the profile’s content per context:
$ conan profile show -pr myprofile
Host profile:
[settings]
arch=x86_64
build_type=Release
compiler=apple-clang
compiler.cppstd=gnu17
compiler.libcxx=libc++
compiler.version=14
os=Macos
Build profile:
[settings]
arch=x86_64
build_type=Release
compiler=apple-clang
compiler.cppstd=gnu17
compiler.libcxx=libc++
compiler.version=14
os=Macos
See also
- Manage your profiles and share them using conan config install.
- Check the command and its sub-commands of conan profile.
Profile sections¶
These are the available sections in profiles:
[settings]¶
List of settings available from settings.yml:
[settings]
arch=x86_64
build_type=Release
compiler=apple-clang
compiler.cppstd=gnu17
compiler.libcxx=libc++
compiler.version=14
os=Macos
[options]¶
List of options available from your recipe and its dependencies:
[options]
my_pkg_option=True
shared=True
[tool_requires]¶
List of tool_requires
required by your recipe or its dependencies:
[tool_requires]
cmake/3.25.2
See also
Read more about tool requires in this section: Using build tools as Conan packages.
[system_tools]¶
Warning
This feature is experimental and subject to breaking changes. See the Conan stability section for more information.
This section is similar to the previous one, [tool_requires], but it’s intended to list only the tool requires that are already in your own system and you don’t want Conan to search for, neither remotely nor locally.
For instance, you have already installed cmake==3.24.2
in your system:
$ cmake --version
cmake version 3.24.2
CMake suite maintained and supported by Kitware (kitware.com/cmake).
Now, you have in your recipe (or the transitive dependencies) declared a tool_requires, i.e., something like this:
from conan import ConanFile
class PkgConan(ConanFile):
name = "pkg"
version = "2.0"
# ....
# Exact version
def build_requirements(self):
self.tool_requires("cmake/3.24.2")
# Or even version ranges
def build_requirements(self):
self.tool_requires("cmake/[>=3.20.0]")
Given this situation, it could make sense to want to use your already installed CMake version, so it’s enough to declare
it as a system_tools
in your profile (default
one or any other in use):
...
[system_tools]
cmake/3.24.2
Whenever you want to create the package, you’ll see that build requirement is already satisfied because of the system tool declaration:
$ conan create . -pr myprofile --build=missing
...
-------- Computing dependency graph --------
Graph root
virtual
Requirements
pkg/2.0#3488ec5c2829b44387152a6c4b013767 - Cache
Build requirements
cmake/3.24.2 - System tool
-------- Computing necessary packages --------
-------- Computing necessary packages --------
pkg/2.0: Forced build from source
Requirements
pkg/2.0#3488ec5c2829b44387152a6c4b013767:20496b332552131b67fb99bf425f95f64d0d0818 - Build
Build requirements
cmake/3.24.2 - System tool
Notice that if the system_tools
declared does not make a strict match with the tool_requires
one (version or
version range), then Conan will try to bring them remotely or locally as usual. Given the previous example, changing the
profile as follows:
...
[system_tools]
cmake/3.20.0
The result will be different when calling the conan create, because Conan will download remotely and build from source if necessary:
$ conan create . -pr myprofile --build=missing
...
-------- Computing dependency graph --------
Graph root
virtual
Requirements
pkg/2.0#3488ec5c2829b44387152a6c4b013767 - Cache
Build requirements
cmake/3.24.2#e35bc44b3fcbcd661e0af0dc5b5b1ad4 - Downloaded (conancenter)
-------- Computing necessary packages --------
-------- Computing necessary packages --------
pkg/2.0: Forced build from source
Requirements
pkg/2.0#3488ec5c2829b44387152a6c4b013767:20496b332552131b67fb99bf425f95f64d0d0818 - Build
Build requirements
cmake/3.24.2#e35bc44b3fcbcd661e0af0dc5b5b1ad4:d0599452a426a161e02a297c6e0c5070f99b4909 - Build
[buildenv]¶
List of environment variables that will be injected to the environment every time the ConanFile
run(cmd, env="conanbuild")
method is invoked (build time context is automatically run by VirtualBuildEnv).
Besides that, it is able to apply some additional operators to each variable declared when you’re composing profiles or even local variables:
+=
==append
: appends values at the end of the existing value.=+
==prepend
: puts values at the beginning of the existing value.=!
==unset
: gets rid of any variable value.
Another essential point to mention is the possibility of defining variables as PATH ones by simply putting (path)
as
the prefix of the variable. It is useful to automatically get the append/prepend of the PATH in different systems
(Windows uses ;
as separation, and UNIX :
).
[buildenv]
# Define a variable "MyVar1"
MyVar1=My Value; other
# Append another value to "MyVar1"
MyVar1+=MyValue12
# Define a PATH variable "MyPath1"
MyPath1=(path)/some/path11
# Prepend another PATH to "MyPath1"
MyPath1=+(path)/other path/path12
# Unset the variable "MyPath1"
MyPath1=!
Then, the result of applying this profile is:
MyVar1
:My Value; other MyValue12
MyPath1
:- Unix:
/other path/path12:/some/path11
- Windows:
/other path/path12;/some/path11
- Unix:
mypkg*:PATH
:None
[runenv]¶
List of environment variables that will be injected to the environment every time the ConanFile
run(cmd, env="conanrun")
method is invoked (runtime context is automatically run by VirtualRunEnv).
All the operators/patterns explained for [buildenv] applies to this one in the same way:
[runenv]
MyVar1=My Value; other
MyVar1+=MyValue12
MyPath1=(path)/some/path11
MyPath1=+(path)/other path/path12
MyPath1=!
[conf]¶
Note
It’s recommended to have previously read the global.conf section.
List of user/tools configurations:
[conf]
tools.build:verbosity=verbose
tools.microsoft.msbuild:max_cpu_count=2
tools.microsoft.msbuild:vs_version = 16
tools.build:jobs=10
# User conf variable
user.confvar:something=False
Recall some hints about configuration scope and naming:
core.xxx
configuration can only be defined inglobal.conf
file, but not in profilestools.yyy
anduser.zzz
can be defined inglobal.conf
and they will affect both the “build” and the “host” context. But configurations defined in a profile[conf]
will only affect the respective “build” or “host” context of the profile, not both.
They can also be used in global.conf, but profiles values will have priority over globally defined ones in global.conf, so let’s see an example that is a bit more complex, trying different configurations coming from the global.conf and another profile myprofile:
# Defining several lists
user.myconf.build:ldflags=["--flag1 value1"]
user.myconf.build:cflags=["--flag1 value1"]
[settings]
...
[conf]
# Appending values into the existing list
user.myconf.build:ldflags+=["--flag2 value2"]
# Unsetting the existing value (it'd be like we define it as an empty value)
user.myconf.build:cflags=!
# Prepending values into the existing list
user.myconf.build:ldflags=+["--prefix prefix-value"]
Running, for instance, conan install . -pr myprofile, the configuration output will be something like:
...
Configuration:
[settings]
[options]
[tool_requires]
[conf]
user.myconf.build:cflags=!
user.myconf.build:ldflags=['--prefix prefix-value', '--flag1 value1', '--flag2 value2']
...
Profile rendering¶
The profiles are rendered as jinja2 templates by default. When Conan loads a profile, it immediately parses and renders the template, which must result in a standard text profile.
Some of the capabilities of the profile templates are:
Using the platform information, like obtaining the current OS, is possible because the Python
platform
module is added to the render context:profile_vars¶[settings] os = {{ {"Darwin": "Macos"}.get(platform.system(), platform.system()) }}
Reading environment variables can be done because the Python
os
module is added to the render context:profile_vars¶[settings] build_type = {{ os.getenv("MY_BUILD_TYPE") }}
Defining your own variables and using them in the profile:
profile_vars¶{% set os = "FreeBSD" %} {% set clang = "my/path/to/clang" %} [settings] os = {{ os }} [conf] tools.build:compiler_executables={'c': '{{ clang }}', 'cpp': '{{ clang + '++' }}' }
Joining and defining paths, including referencing the current profile directory. For example, defining a toolchain whose file is located besides the profile can be done. Besides the
os
Python module, the variableprofile_dir
pointing to the current profile folder is added to the context.profile_vars¶[conf] tools.cmake.cmaketoolchain:toolchain_file = {{ os.path.join(profile_dir, "toolchain.cmake") }}
Getting settings from a filename, including referencing the current profile name. For example, defining a generic profile which is configured according to its file name. The variable
profile_name
pointing to the current profile file name is added to the context.Linux-x86_64-gcc-12¶{% set os, arch, compiler, compiler_version = profile_name.split('-') %} [settings] os={{ os }} arch={{ arch }} compiler={{ compiler }} compiler.version={{ compiler_version }}
Including or importing other files from
profiles
folder:profile_vars¶{% set a = "Debug" %}
myprofile¶{% import "profile_vars" as vars %} [settings] build_type = {{ vars.a }}
Any other feature supported by jinja2 is possible: for loops, if-else, etc. This would be useful to define custom per-package settings or options for multiple packages in a large dependency graph.
Profile Rendering with ``detect_api``
Warning
Stability Guarantees: The detect_api, similar to conan profile detect
, does not
offer strong stability guarantees.
Usage Recommendations: The detect_api is not a regular API meant for creating new commands or similar functionalities. While auto-detection can be convenient, it’s not the recommended approach for all scenarios. This API is internal to Conan and is only exposed for profile and global.conf rendering. It’s advised to use it judiciously.
Conan also injects detect_api
to the jinja rendering context. With it, it’s
possible to use Conan’s auto-detection capabilities directly within Jinja profile
templates. This provides a way to dynamically determine certain settings based on the
environment.
detect_api
can be invoked within the Jinja template of a profile. For instance, to
detect the operating system and architecture, you can use:
[settings]
os={{detect_api.detect_os()}}
arch={{detect_api.detect_arch()}}
Similarly, for more advanced detections like determining the compiler, its version, and the associated runtime, you can use:
{% set compiler, version = detect_api.detect_compiler() %}
{% set runtime, _ = detect_api.default_msvc_runtime(compiler) %}
[settings]
compiler={{compiler}}
compiler.version={{detect_api.default_compiler_version(compiler, version)}}
compiler.runtime={{runtime}}
compiler.cppstd={{detect_api.default_cppstd(compiler, version)}}
detect_api reference:
- `detect_os()`: returns operating system as a string (e.g., “Windows”, “Macos”).
- `detect_arch()`: returns system architecture as a string (e.g., “x86_64”, “armv8”).
- `detect_libcxx(compiler, version)`: returns C++ standard library as a string (e.g., “libstdc++”, “libc++”).
- `default_msvc_runtime(compiler)`: returns tuple with runtime (e.g., “dynamic”) and its version (e.g., “v143”).
- `default_cppstd(compiler, compiler_version)`: returns default C++ standard as a string (e.g., “gnu14”).
- `detect_compiler()`: returns tuple with compiler name (e.g., “gcc”) and its version.
- `default_msvc_ide_version(version)`: returns MSVC IDE version as a string (e.g., “17”).
- `default_compiler_version(compiler, version)`: returns the default version that
- Conan uses in profiles, typically dropping some of the minor or patch digits, that do not affect binary compatibility.
Profile patterns¶
Profiles also support patterns definition, so you can override some settings, configuration variables, etc. for some specific packages:
[settings]
# Only for zlib
zlib*:compiler=clang
zlib*:compiler.version=3.5
zlib*:compiler.libcxx=libstdc++11
# For the all the dependency tree
compiler=gcc
compiler.version=4.9
compiler.libcxx=libstdc++11
[options]
# shared=True option only for zlib package
zlib*:shared=True
[buildenv]
# For the all the dependency tree
*:MYVAR=my_var
[conf]
# Only for zlib
zlib*:tools.build:compiler_executables={'c': '/usr/bin/clang', 'cpp': '/usr/bin/clang++'}
Your build tool will locate clang compiler only for the zlib package and gcc (default one) for the rest of your dependency tree.
Important
Putting only zlib:
is not going to work, you have to always put a pattern-like expression, e.g., zlib*:
, zlib/1.*:
, etc.
They accept patterns too, like -s *@myuser/*
, which means that packages that have the username “myuser” will use
clang 3.5 as compiler, and gcc otherwise:
[settings]
*@myuser/*:compiler=clang
*@myuser/*:compiler.version=3.5
*@myuser/*:compiler.libcxx=libstdc++11
compiler=gcc
compiler.version=4.9
compiler.libcxx=libstdc++11
Also & can be specified as the package name. It will apply only to the consumer conanfile (.py or .txt). This is a special case because the consumer conanfile might not declare a name so it would be impossible to reference it.
[settings]
&:compiler=gcc
&:compiler.version=4.9
&:compiler.libcxx=libstdc++11
Profile includes¶
You can include other profile files using the include()
statement. The path can be relative
to the current profile, absolute, or a profile name from the default profile location in the local cache.
The include()
statement has to be at the top of the profile file:
[settings]
compiler=gcc
compiler.version=4.9
compiler.libcxx=libstdc++11
include(gcc_49)
[settings]
zlib*:compiler=clang
zlib*:compiler.version=3.5
zlib*:compiler.libcxx=libstdc++11
The final result of using myprofile is:
[settings]
compiler=gcc
compiler.libcxx=libstdc++11
compiler.version=4.9
zlib*:compiler=clang
zlib*:compiler.libcxx=libstdc++11
zlib*:compiler.version=3.5
See also