CMake Variants¶
CMake Tools introduces the concept of CMake Variants, a way to group together
and combine a common set of build options and give them a useful name. The main
interface for creating and building variants is cmake-variants.json
, or
cmake-variants.yaml
.
The idea of “variants” are separate from the concept of toolchains/toolsets, which are handled via Kits.
By default, if no variants file is present, CMake Tools will load four variants, each corresponding to a default CMake build type: Release, Debug, MinSizeRel, and RelWithDebInfo. Selecting one of these variants will configure and build with that build type.
Note
CMake Tools does not presently respect CMAKE_CONFIGURATION_TYPES
. Only
the default four will be present. A custom variant file is required to load
these build types.
For smaller or simple projects, providing a custom cmake-variants.yaml
is
unnecessary, and the default CMake build types will work just fine. Large
projects with more complex configuration options may want to specify
additional build variants.
The variants file can be placed in the root of the project directory, or in the
.vscode
subdirectory for the project.
Note
CMake Tools provides a YAML validation schema, which is only checked in the editor when using the YAML Support by Red Hat extension.
You can use either cmake-variants.json
or cmake-variants.yaml
. Both
will have the same end result.
The examples in this page will use the YAML format, but everything can be done in the JSON format as well.
What does it look like?¶
A simple two-setting cmake-variants.yaml
might look like this:
This file defines two variant settings: buildType and useOpenGL. They
each have two options defined by the choices
key. A combination of the
options from a set of settings forms a variant.
In total, the number of possible variants is defined by the cartesian product of the possible choices. Two settings each with two options creates four variants. When we ask to change the build type, CMake Tools will present each possible combination in a quickpick:
When a cmake-variants.json
or cmake-variants.yaml
file is present, the
options defined therein will replace the default set of variants CMake Tools
would otherwise present. This allows a project owner to define their own set of
common build configurations that can be distributed downstream.
The Variant Schema¶
The root of the variants must be an object, where each key represents a
tweakable variant option. In the example above, we expose a buildType
option
for what kind of CMAKE_BUILD_TYPE
we want. We also expose a useOpenGL
that controls the ENABLE_OPENGL
CMake option.
Variant Settings¶
Each setting in the variant is an object with only the following keys:
default
A string to set as the default choice for the variant option. The string here must correspond to an option from
choices
.description
An optional string to describe what the option controls. CMake Tools ignores this string.
choices
A mapping of possible options for the setting. A variant setting can have an arbitrary number of possible options. See the section below on options.
Variant Options¶
Variant options appear under the choices
key for a variant setting. Each is
required to have an unique name, but the name itself is unimportant to CMake
Tools.
A choice may specify any of the following options (the only requirement is the
short
):
short
A short human-readable string to describe the option.
long
(Optional)A lengthier human-readable string to describe the option.
buildType
(Optional)An optional string to set for
CMAKE_BUILD_TYPE
when the option is active.linkage
(Optional)Either
static
orshared
. Sets the value ofCMAKE_BUILD_SHARED_LIBS
. This value is optional.settings
(Optional)A map of arbitrary CMake cache options to pass via the CMake command line with
-D
. Similar to thecmake.configureSettings
insettings.json
.env
(Optional)A map of key-value string pairs specifying additional environment variables to set during CMake configure (not build). These environment variables take precedence over environment variables from
settings.json
, the currently set kit, and environment variables set by the system.
The above options are only valid under entries in the choices
map.
How Variants Are Applied¶
A variant is a specific combination of one option from each of the defined settings. When CMake Tools executes the configure step, it will use the values from the currently active variant to determine the values to pass to the CMake process:
Properties from all active options are merged. For
env
andsettings
, the objects themselves are merged. The merge order is unspecified, so conflicting properties in options will result in unspecified behavior.All
settings
from the chosen options are passed as-D
arguments to the CMake process.The
buildType
is used forCMAKE_BUILD_TYPE
, the--config
flag for the build (For multi-conf generators), and for the CTest--config
flag.If
linkage
istrue
,BUILD_SHARED_LIBS
is set toON
. Iflinkage
isfalse
,BUILD_SHARED_LIBS
is set toOFF
. If not specified,BUILD_SHARED_LIBS
will not be set on the CMake command line.The environment variables from
env
are set for the CMake process.
A Big Example¶
Suppose the following variants file:
buildType:
default: debug
choices:
debug:
short: Debug
long: Emit debug information
buildType: Debug
release:
short: Release
long: Optimize generated code
buildType: Release
asan:
short: Asan
long: Instrument with Address Sanitizer
buildType: Asan
tsan:
short: Tsan
long: Instrument with Thread Sanitizer
buildType: Tsan
linkage:
default: static
choices:
static:
short: Static
long: Create static libraries
linkage: static
shared:
short: Shared
long: Create shared libraries/DLLs
linkage: shared
engine:
default: ogl
choices:
ogl:
short: OpenGL
long: OpenGL rendering
settings:
ENGINE: OpenGL
d3d:
short: Direct3D
long: Direct3D rendering
settings:
ENGINE: Direct3D
vulkan:
short: Vulkan
long: Vulkan rendering
setting:
ENGINE: Vulkan
software:
short: Software
long: Software rendering
setting:
ENGINE: Software
network:
default: boost
choices:
boost:
short: Boost.Asio
long: Use Boost.Asio for networking
setting:
NETWORK: Boost
asio:
short: Asio
long: Use standalone-Asio for networking
setting:
NETWORK: Asio
net-ts:
short: NetTS
long: Use the C++ Networking TS for networking
setting:
NETWORK: net-ts
CMake Tools will present the cartesian product of all options, meaning the above will produce 4 × 2 × 4 × 3 = ninety-six different variants:
Of course this is quite a lot of possible variants, but such is the way with some complex software. CMake Tools will readily any helpfully show all combinations, and persist the selection between sessions.