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

[tool_requires]
tool1/0.1@user/channel
*: tool4/0.1@user/channel

[buildenv]
VAR1=value

[runenv]
EnvironmentVar1=My Value

[conf]
tools.build:jobs=2

[replace_requires]
zlib/1.2.12: zlib/[*]

[replace_tool_requires]
7zip/*: 7zip/system

[platform_requires]
dlib/1.3.22

[platform_tool_requires]
cmake/3.24.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:

Creating the Conan 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.

Creating another profile: myprofile
$ 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:

Using the default profile
$ conan create .
Using a myprofile profile
$ conan create . -pr=myprofile

Using profiles

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

Profile sections

These are the available sections in profiles:

[settings]

List of settings available from settings.yml:

myprofile
[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:

myprofile
[options]
mypkg/*:my_pkg_option=True
*:shared=True

[tool_requires]

List of tool_requires required by your recipe or its dependencies:

myprofile
[tool_requires]
cmake/3.25.2

See also

Read more about tool requires in this section: Using build tools as Conan packages.

[system_tools] (DEPRECATED)

Note

This section is deprecated and has been replaced by [platform_requires] and [platform_tool_requires] sections.

[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 :).

myprofile
[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

  • mypkg*:PATH: None

Warning

Note that [buildenv] and [runenv] environment variables definition keeps user blank spaces in values. MYVAR = MyValue will produce a " MyValue" value, which will be different than MYVAR=MyValue that will produce "MyValue". avoid using extra spaces around = in profiles, use the syntax shown above.

[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:

myprofile
[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:

myprofile
[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 in global.conf file, but not in profiles

  • tools.yyy and user.zzz can be defined in global.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:

global.conf
# Defining several lists
user.myconf.build:ldflags=["--flag1 value1"]
user.myconf.build:cflags=["--flag1 value1"]
myprofile
[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']
...

[replace_requires]

Warning

This feature is experimental and subject to breaking changes. See the Conan stability section for more information.

This section allows the user to redefine requires of recipes. This can be useful when a package can be changed by a similar one like zlib and zlibng. It is also useful to solve conflicts, or to replace some dependencies by system alternatives wrapped in another Conan package recipe.

References listed under this section work as a literal replacement of requires in recipes, and is done as the very first step before any other processing of recipe requirements, without processing them or checking for conflicts.

As an example, we could define zlibng as a replacement for the typical zlib

myprofile
[replace_requires]
zlib/*: zlibng/*

Using the * pattern for the zlibng reference means that zlib will be replaced by the exact same version of zlibng.

Other examples are:

myprofile
[replace_requires]
dep/*: dep/1.1               # To override dep/[>=1.0 <2] in recipes to a specific version dep/1.1)
dep/*: dep/*@system          # To override a dep/1.3 in recipes to dep/1.3@system
dep/*: dep/[>=1 <2]          # To override every dep requirement in recipes to a specific version range
dep/*@*/*: dep/*@system/*    # To override "dep/1.3@comp/stable" in recipes to the same version with other user but same channel
dep/1.1: dep/1.1@system      # To replace exact reference in recipes by the same one in the system
dep/1.1@*: dep/1.1@*/stable  # To replace dep/[>=1.0 <2]@comp version range in recipes by 1.1 version in stable chanel

Note

Best practices

  • Please make rational use of this feature. It is not a versioning mechanism and is not intended to replace actual requires in recipes.

  • The usage of this feature is intended for temporarily solving conflicts or replacing a specific dependency by a system one in some cross-build scenarios.

[replace_tool_requires]

Warning

This feature is experimental and subject to breaking changes. See the Conan stability section for more information.

Same usage as the replace_requires section but in this case for tool_requires.

myprofile
[replace_tool_requires]
cmake/*: cmake/3.25.2

In this case, whatever version of cmake declared in recipes, will be replaced by the reference cmake/3.25.2.

[platform_requires]

Warning

This feature is experimental and subject to breaking changes. See the Conan stability section for more information.

This section allows the user to redefine requires of recipes replacing them with platform-provided dependencies, this means that Conan will not try to download the reference or look for it in the cache and will assume that it is installed in your system and ready to be used.

For example, if the zlib 1.2.11 library is already installed in your system or it is part of your build toolchain and you would like Conan to use it, you could specify so as:

myprofile
[platform_requires]
zlib/1.2.11

[platform_tool_requires]

Warning

This feature is experimental and subject to breaking changes. See the Conan stability section for more information.

Same usage as the platform_requires section but in this case for tool_requires such as cmake, meson

As an example, let’s say 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).

And you have in your recipe (or the transitive dependencies) declared a tool_requires, i.e., something like this:

conanfile.py
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 platform_tool_requires in your profile:

myprofile
...

[platform_tool_requires]
cmake/3.24.2

Whenever you want to create the package, you’ll see that build requirement is already satisfied because of the platform 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 - Platform

-------- 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 - Platform

Note that if the platform_tool_requires 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.

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 variable profile_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, compiler_exe = detect_api.detect_default_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)}}
compiler.libcxx={{detect_api.detect_libcxx(compiler, version, compiler_exe)}}

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_libc(ldd="/usr/bin/ldd"): experimental returns a tuple with the name (e.g., “gnu”, “musl”) and version (e.g., “2.39”, “1.2.4”) of the C library.

  • detect_libcxx(compiler, version, compiler_exe=None): 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_default_compiler(): returns tuple with compiler name (e.g., “gcc”), its version and the executable path.

  • detect_msvc_update(version): returns the MSVC update version as a string (e.g., “12” for VS 17.12.1). Note that in Conan profiles, the compiler.update setting accepts values from 0 to 10. To convert the result from detect_msvc_update into the format required by profiles, you can do something like this:

    Example:

    ...
    [settings]
    compiler=msvc
    compiler=194 # for msvc toolset starting in 14.40 (VS 17.10)
    # If we are using VS 17.12 we convert 12 to 2 so it's 194 with update 2
    compiler.update = "{{ (detect_api.detect_msvc_update(version) | int) % 10 }}"
    ...
    
  • 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.

  • detect_gcc_compiler(compiler_exe="gcc"): Return the tuple (‘gcc’, version, executable) for gcc

  • detect_intel_compiler(compiler_exe="icx"): Return the tuple (‘intel-cc’, version, executable) for intel-cc

  • detect_suncc_compiler(compiler_exe="cc"): Return the tuple (‘sun-cc’, version, executable) for sun-cc

  • detect_clang_compiler(compiler_exe="clang"): Return the tuple (‘clang’|’apple-clang’, version, executable) for clang or apple-clang.

  • detect_msvc_compiler(): Detect the compiler (‘msvc’, version, None) default version of the latest VS IDE installed

  • detect_cl_compiler(compiler_exe="cl"): Detect the compiler (‘msvc’, version, executable) for the cl.exe compiler

  • detect_sdk_version(sdk): Detect the Apple SDK version (None for non Apple platforms), for the given sdk. Equivalent to xcrun -sdk {sdk} --show-sdk-version

Profile patterns

Profiles (and everywhere where a setting or option is defined) also support patterns definition, so you can override some settings, configuration variables, etc. for some specific packages:

zlib_clang_profile
[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 deprecated behaviour and won’t work, you have to always put a pattern-like expression, e.g., zlib*:, 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:

myprofile
[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.

myprofile
[settings]
&:compiler=gcc
&:compiler.version=4.9
&:compiler.libcxx=libstdc++11

Partial matches are also supported, so you can define a pattern like zlib* to match all the zlib like libraries, so it will match everything starting with zlib, like zlib, zlibng, zlib/1.2.8@user/channel, etc.

myprofile
[settings]
zlib*:compiler=clang
zlib*:compiler.version=3.5
zlib*: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:

gcc_49
[settings]
compiler=gcc
compiler.version=4.9
compiler.libcxx=libstdc++11
myprofile
include(gcc_49)

[settings]
zlib/*:compiler=clang
zlib/*:compiler.version=3.5
zlib/*:compiler.libcxx=libstdc++11

The final result of using myprofile is:

myprofile (virtual result)
[settings]
compiler=gcc
compiler.libcxx=libstdc++11
compiler.version=4.9
zlib/*:compiler=clang
zlib/*:compiler.libcxx=libstdc++11
zlib/*:compiler.version=3.5