CMake
The CMake class helps us to invoke cmake command with the generator, flags and definitions, reflecting the specified Conan settings.
There are two ways to invoke your cmake tools:
Using the helper attributes
cmake.command_line
andcmake.build_config
:
from conans import ConanFile, CMake
class ExampleConan(ConanFile):
...
def build(self):
cmake = CMake(self)
self.run('cmake "%s" %s' % (self.source_folder, cmake.command_line))
self.run('cmake --build . %s' % cmake.build_config)
self.run('cmake --build . --target install')
Using the helper methods:
from conans import ConanFile, CMake
class ExampleConan(ConanFile):
...
def build(self):
cmake = CMake(self)
# same as cmake.configure(source_folder=self.source_folder, build_folder=self.build_folder)
cmake.configure()
cmake.build()
cmake.test() # Build the "RUN_TESTS" or "test" target
# Build the "install" target, defining CMAKE_INSTALL_PREFIX to self.package_folder
cmake.install()
Constructor
class CMake(object):
def __init__(self, conanfile, generator=None, cmake_system_name=True,
parallel=True, build_type=None, toolset=None, make_program=None,
set_cmake_flags=False)
- Parameters:
conanfile (Required): Conanfile object. Usually
self
in a conanfile.pygenerator (Optional, Defaulted to
None
): Specify a custom generator instead of autodetect it. e.j: “MinGW Makefiles”cmake_system_name (Optional, Defaulted to
True
): Specify a custom value forCMAKE_SYSTEM_NAME
instead of autodetect it.parallel (Optional, Defaulted to
True
): IfTrue
, will append the -jN attribute for parallel building being N the cpu_count().build_type (Optional, Defaulted to
None
): Force the build type to be declared inCMAKE_BUILD_TYPE
. If you set this parameter the build type not will be taken from the settings.toolset (Optional, Defaulted to
None
): Specify a toolset for Visual Studio.make_program (Optional, Defaulted to
None
): Indicate path tomake
.set_cmake_flags (Optional, Defaulted to
None
): Whether or not to set CMake flags likeCMAKE_CXX_FLAGS
,CMAKE_C_FLAGS
, etc.
Attributes
verbose
Defaulted to: False
Set it to True
or False
to automatically set the definition CMAKE_VERBOSE_MAKEFILE
.
from conans import ConanFile, CMake
class ExampleConan(ConanFile):
...
def build(self):
cmake = CMake(self)
cmake.verbose = True
cmake.configure()
cmake.build()
command_line (read only)
Generator, conan definitions and flags that reflects the specified Conan settings.
-G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release ... -DCONAN_C_FLAGS=-m64 -Wno-dev
build_config (read only)
Value for --config
option for Multi-configuration IDEs.
--config Release
definitions
The CMake helper will automatically append some definitions based on your settings:
Variable |
Description |
---|---|
CMAKE_BUILD_TYPE |
Debug or Release (from self.settings.build_type) |
CMAKE_OSX_ARCHITECTURES |
“i386” if architecture is x86 in an OSX system |
BUILD_SHARED_LIBS |
Only If your conanfile has a “shared” option |
CONAN_COMPILER |
Conan internal variable to check compiler |
CMAKE_SYSTEM_NAME |
If detected cross building it’s set to self.settings.os |
CMAKE_SYSTEM_VERSION |
If detected cross building it’s set to the self.settings.os_version |
CMAKE_ANDROID_ARCH_ABI |
If detected cross building to Android |
CONAN_LIBCXX |
from self.settings.compiler.libcxx |
CONAN_CMAKE_SYSTEM_PROCESSOR |
Definition only set if same environment variable is declared by user |
CONAN_CMAKE_FIND_ROOT_PATH |
Definition only set if same environment variable is declared by user |
CONAN_CMAKE_FIND_ROOT_PATH_MODE_PROGRAM |
Definition only set if same environment variable is declared by user |
CONAN_CMAKE_FIND_ROOT_PATH_MODE_LIBRARY |
Definition only set if same environment variable is declared by user |
CONAN_CMAKE_FIND_ROOT_PATH_MODE_INCLUDE |
Definition only set if same environment variable is declared by user |
CONAN_CMAKE_POSITION_INDEPENDENT_CODE |
When |
CONAN_SHARED_LINKER_FLAGS |
-m32 and -m64 based on your architecture |
CONAN_C_FLAGS |
-m32 and -m64 based on your architecture and /MP for MSVS |
CONAN_CXX_FLAGS |
-m32 and -m64 based on your architecture and /MP for MSVS |
CONAN_LINK_RUNTIME |
Runtime from self.settings.compiler.runtime for MSVS |
CONAN_CMAKE_CXX_STANDARD |
From setting |
CONAN_CMAKE_CXX_EXTENSIONS |
From setting |
CONAN_STD_CXX_FLAG |
From setting |
CMAKE_EXPORT_NO_PACKAGE_REGISTRY |
By default, disable the package registry |
But you can change the automatic definitions after the CMake()
object creation using the definitions
property:
from conans import ConanFile, CMake
class ExampleConan(ConanFile):
...
def build(self):
cmake = CMake(self)
cmake.definitions["CMAKE_SYSTEM_NAME"] = "Generic"
cmake.configure()
cmake.build()
cmake.install() # Build --target=install
Methods
configure()
def configure(self, args=None, defs=None, source_folder=None, build_folder=None,
cache_build_folder=None, pkg_config_paths=None)
Configures CMake project with the given parameters.
- Parameters:
args (Optional, Defaulted to
None
): A list of additional arguments to be passed to thecmake
command. Each argument will be escaped according to the current shell. No extra arguments will be added ifargs=None
definitions (Optional, Defaulted to
None
): A dict that will be converted to a list of CMake command line variable definitions of the form-DKEY=VALUE
. Each value will be escaped according to the current shell and can be eitherstr
,bool
or of numeric typesource_folder: CMake’s source directory where
CMakeLists.txt
is located. The default value is theself.source_folder
. Relative paths are allowed and will be relative toself.source_folder
.build_folder: CMake’s output directory. The default value is the
self.build_folder
ifNone
is specified. TheCMake
object will storebuild_folder
internally for subsequent calls tobuild()
.cache_build_folder (Optional, Defaulted to
None
): Use the given subfolder as build folder when building the package in the local cache. This argument doesn’t have effect when the package is being built in user folder with conan build but overrides build_folder when working in the local cache. See self.in_local_cache.pkg_config_paths (Optional, Defaulted to
None
): Specify folders (in a list) of relative paths to the install folder or absolute ones where to find*.pc
files (by using the env varPKG_CONFIG_PATH
). IfNone
is specified but the conanfile is using thepkg_config
generator, theself.install_folder
will be added to thePKG_CONFIG_PATH
in order to locate the pc files of the requirements of the conanfile.
build()
def build(self, args=None, build_dir=None, target=None)
Builds CMake project with the given parameters.
- Parameters:
args (Optional, Defaulted to
None
): A list of additional arguments to be passed to thecmake
command. Each argument will be escaped according to the current shell. No extra arguments will be added ifargs=None
build_dir (Optional, Defaulted to
None
): CMake’s output directory. IfNone
is specified thebuild_dir
fromconfigure()
will be used.target (Optional, Defaulted to
None
): Specifies the target to execute. The default all target will be built ifNone
is specified."install"
can be used to relocate files to aid packaging.
test()
def test(args=None, build_dir=None, target=None)
Build CMake test target (could be RUN_TESTS in multi-config projects or test
in single-config projects), which usually means building and running unit tests
- Parameters:
args (Optional, Defaulted to
None
): A list of additional arguments to be passed to thecmake
command. Each argument will be escaped according to the current shell. No extra arguments will be added ifargs=None
.build_dir (Optional, Defaulted to
None
): CMake’s output directory. IfNone
is specified thebuild_folder
fromconfigure()
will be used.target (Optional, default to
None
). Alternative target name for running the tests. If not defined RUN_TESTS ortest
will be used
install()
def install(args=None, build_dir=None)
Installs CMake project with the given parameters.
- Parameters:
args (Optional, Defaulted to
None
): A list of additional arguments to be passed to thecmake
command. Each argument will be escaped according to the current shell. No extra arguments will be added ifargs=None
.build_dir (Optional, Defaulted to
None
): CMake’s output directory. IfNone
is specified thebuild_folder
fromconfigure()
will be used.
patch_config_paths() [EXPERIMENTAL]
def patch_config_paths()
This method changes references to the absolute path of the installed package in exported CMake config files to the appropriate Conan variable. This makes most CMake config files portable.
For example, if a package foo installs a file called fooConfig.cmake to be used by cmake’s find_package()
method, normally this file
will contain absolute paths to the installed package folder, for example it will contain a line such as:
SET(Foo_INSTALL_DIR /home/developer/.conan/data/Foo/1.0.0/...)
This will cause cmake’s find_package()
method to fail when someone else installs the package via Conan. This function will replace such
paths to:
SET(Foo_INSTALL_DIR ${CONAN_FOO_ROOT})
Which is a variable that is set by conanbuildinfo.cmake, so that find_package()
now correctly works on this Conan package.
If the install()
method of the CMake object in the conanfile is used, this function should be called after that invocation. For
example:
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
cmake.install()
cmake.patch_config_paths()
Environment variables
There are some environment variables that will also affect the CMake()
helper class. Check them in the
CMAKE RELATED VARIABLES section.
Example
The following example of conanfile.py
shows you how to manage a project with conan and CMake.
from conans import ConanFile, CMake
class SomePackage(ConanFile):
name = "SomePackage"
version = "1.0.0"
settings = "os", "compiler", "build_type", "arch"
generators = "cmake"
def configure_cmake(self):
cmake = CMake(self)
cmake.configure()
# put definitions here so that they are re-used in cmake between
# build() and package()
cmake.definitions["SOME_DEFINITION_NAME"] = "On"
return cmake
def build(self):
cmake = self.configure_cmake()
cmake.build()
# run unit tests after the build
cmake.test()
# run custom make command
self.run("make -j3 check)
def package(self):
cmake = self.configure_cmake()
cmake.install()