# 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 or shared. Sets the value of CMAKE_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 the cmake.configureSettings in settings.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:

1. Properties from all active options are merged. For env and settings, the objects themselves are merged. The merge order is unspecified, so conflicting properties in options will result in unspecified behavior.
2. All settings from the chosen options are passed as -D arguments to the CMake process.
3. The buildType is used for CMAKE_BUILD_TYPE, the --config flag for the build (For multi-conf generators), and for the CTest --config flag.
4. If linkage is true, BUILD_SHARED_LIBS is set to ON. If linkage is false, BUILD_SHARED_LIBS is set to OFF. If not specified, BUILD_SHARED_LIBS will not be set on the CMake command line.
5. 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
buildType: Asan
tsan:
short: Tsan
buildType: Tsan

default: static
choices:
static:
short: Static
long: Create static libraries
shared:
short: Shared
long: Create shared libraries/DLLs

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.