1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-14 02:08:27 +08:00

Help: Restructure build type docs and clarify case sensitivity

Fixes: #22591
This commit is contained in:
Craig Scott
2021-09-21 22:22:59 +10:00
parent 253f31f5ef
commit b8d10c27d1
3 changed files with 140 additions and 68 deletions

View File

@@ -21,9 +21,9 @@ Binary Targets
Executables and libraries are defined using the :command:`add_executable`
and :command:`add_library` commands. The resulting binary files have
appropriate :prop_tgt:`PREFIX`, :prop_tgt:`SUFFIX` and extensions for the platform targeted.
Dependencies between binary targets are expressed using the
:command:`target_link_libraries` command:
appropriate :prop_tgt:`PREFIX`, :prop_tgt:`SUFFIX` and extensions for the
platform targeted. Dependencies between binary targets are expressed using
the :command:`target_link_libraries` command:
.. code-block:: cmake
@@ -530,38 +530,6 @@ the calculated "compatible" value of a property may be read with the
In this case, the ``exe1`` source files will be compiled with
``-DCONTAINER_SIZE=200``.
Configuration determined build specifications may be conveniently set using
the ``CONFIG`` generator expression.
.. code-block:: cmake
target_compile_definitions(exe1 PRIVATE
$<$<CONFIG:Debug>:DEBUG_BUILD>
)
The ``CONFIG`` parameter is compared case-insensitively with the configuration
being built. In the presence of :prop_tgt:`IMPORTED` targets, the content of
:prop_tgt:`MAP_IMPORTED_CONFIG_DEBUG <MAP_IMPORTED_CONFIG_<CONFIG>>` is also
accounted for by this expression.
Some buildsystems generated by :manual:`cmake(1)` have a predetermined
build-configuration set in the :variable:`CMAKE_BUILD_TYPE` variable. The
buildsystem for the IDEs such as Visual Studio and Xcode are generated
independent of the build-configuration, and the actual build configuration
is not known until build-time. Therefore, code such as
.. code-block:: cmake
string(TOLOWER ${CMAKE_BUILD_TYPE} _type)
if (_type STREQUAL debug)
target_compile_definitions(exe1 PRIVATE DEBUG_BUILD)
endif()
may appear to work for :ref:`Makefile Generators` and :generator:`Ninja`
generators, but is not portable to IDE generators. Additionally,
the :prop_tgt:`IMPORTED` configuration-mappings are not accounted for
with code like this, so it should be avoided.
The unary ``TARGET_PROPERTY`` generator expression and the ``TARGET_POLICY``
generator expression are evaluated with the consuming target context. This
means that a usage requirement specification may be evaluated differently based
@@ -840,6 +808,121 @@ target at a time. The commands :command:`add_compile_definitions`,
a similar function, but operate at directory scope instead of target
scope for convenience.
.. _`Build Configurations`:
Build Configurations
====================
Configurations determine specifications for a certain type of build, such
as ``Release`` or ``Debug``. The way this is specified depends on the type
of :manual:`generator <cmake-generators(7)>` being used. For single
configuration generators like :ref:`Makefile Generators` and
:generator:`Ninja`, the configuration is specified at configure time by the
:variable:`CMAKE_BUILD_TYPE` variable. For multi-configuration generators
like :ref:`Visual Studio <Visual Studio Generators>`, :generator:`Xcode`, and
:generator:`Ninja Multi-Config`, the configuration is chosen by the user at
build time and :variable:`CMAKE_BUILD_TYPE` is ignored. In the
multi-configuration case, the set of *available* configurations is specified
at configure time by the :variable:`CMAKE_CONFIGURATION_TYPES` variable,
but the actual configuration used cannot be known until the build stage.
This difference is often misunderstood, leading to problematic code like the
following:
.. code-block:: cmake
# WARNING: This is wrong for multi-config generators because they don't use
# and typically don't even set CMAKE_BUILD_TYPE
string(TOLOWER ${CMAKE_BUILD_TYPE} build_type)
if (build_type STREQUAL debug)
target_compile_definitions(exe1 PRIVATE DEBUG_BUILD)
endif()
:manual:`Generator expressions <cmake-generator-expressions(7)>` should be
used instead to handle configuration-specific logic correctly, regardless of
the generator used. For example:
.. code-block:: cmake
# Works correctly for both single and multi-config generators
target_compile_definitions(exe1 PRIVATE
$<$<CONFIG:Debug>:DEBUG_BUILD>
)
In the presence of :prop_tgt:`IMPORTED` targets, the content of
:prop_tgt:`MAP_IMPORTED_CONFIG_DEBUG <MAP_IMPORTED_CONFIG_<CONFIG>>` is also
accounted for by the above ``$<CONFIG:Debug>`` expression.
Case Sensitivity
----------------
:variable:`CMAKE_BUILD_TYPE` and :variable:`CMAKE_CONFIGURATION_TYPES` are
just like other variables in that any string comparisons made with their
values will be case-sensitive. The ``$<CONFIG>`` generator expression also
preserves the casing of the configuration as set by the user or CMake defaults.
For example:
.. code-block:: cmake
# NOTE: Don't use these patterns, they are for illustration purposes only.
set(CMAKE_BUILD_TYPE Debug)
if(CMAKE_BUILD_TYPE STREQUAL DEBUG)
# ... will never get here, "Debug" != "DEBUG"
endif()
add_custom_target(print_config ALL
# Prints "Config is Debug" in this single-config case
COMMAND ${CMAKE_COMMAND} -E echo "Config is $<CONFIG>"
VERBATIM
)
set(CMAKE_CONFIGURATION_TYPES Debug Release)
if(DEBUG IN_LIST CMAKE_CONFIGURATION_TYPES)
# ... will never get here, "Debug" != "DEBUG"
endif()
In contrast, CMake treats the configuration type case-insensitively when
using it internally in places that modify behavior based on the configuration.
For example, the ``$<CONFIG:Debug>`` generator expression will evaluate to 1
for a configuration of not only ``Debug``, but also ``DEBUG``, ``debug`` or
even ``DeBuG``. Therefore, you can specify configuration types in
:variable:`CMAKE_BUILD_TYPE` and :variable:`CMAKE_CONFIGURATION_TYPES` with
any mixture of upper and lowercase, although there are strong conventions
(see the next section). If you must test the value in string comparisons,
always convert the value to upper or lowercase first and adjust the test
accordingly.
Default And Custom Configurations
---------------------------------
By default, CMake defines a number of standard configurations:
* ``Debug``
* ``Release``
* ``RelWithDebInfo``
* ``MinSizeRel``
In multi-config generators, the :variable:`CMAKE_CONFIGURATION_TYPES` variable
will be populated with (potentially a subset of) the above list by default,
unless overridden by the project or user. The actual configuration used is
selected by the user at build time.
For single-config generators, the configuration is specified with the
:variable:`CMAKE_BUILD_TYPE` variable at configure time and cannot be changed
at build time. The default value will often be none of the above standard
configurations and will instead be an empty string. A common misunderstanding
is that this is the same as ``Debug``, but that is not the case. Users should
always explicitly specify the build type instead to avoid this common problem.
The above standard configuration types provide reasonable behavior on most
platforms, but they can be extended to provide other types. Each configuration
defines a set of compiler and linker flag variables for the language in use.
These variables follow the convention :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>`,
where ``<CONFIG>`` is always the uppercase configuration name. When defining
a custom configuration type, make sure these variables are set appropriately,
typically as cache variables.
Pseudo Targets
==============

View File

@@ -1,34 +1,21 @@
CMAKE_BUILD_TYPE
----------------
Specifies the build type on single-configuration generators.
This statically specifies what build type (configuration) will be
built in this build tree. Possible values are empty, ``Debug``, ``Release``,
``RelWithDebInfo``, ``MinSizeRel``, ... This variable is only meaningful to
single-configuration generators (such as :ref:`Makefile Generators` and
:generator:`Ninja`) i.e. those which choose a single configuration when CMake
runs to generate a build tree as opposed to multi-configuration generators
which offer selection of the build configuration within the generated build
environment. There are many per-config properties and variables
(usually following clean ``SOME_VAR_<CONFIG>`` order conventions), such as
``CMAKE_C_FLAGS_<CONFIG>``, specified as uppercase:
``CMAKE_C_FLAGS_[DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL|...]``. For example,
in a build tree configured to build type ``Debug``, CMake will see to
having :variable:`CMAKE_C_FLAGS_DEBUG <CMAKE_<LANG>_FLAGS_DEBUG>` settings get
added to the :variable:`CMAKE_C_FLAGS <CMAKE_<LANG>_FLAGS>` settings. See
also :variable:`CMAKE_CONFIGURATION_TYPES`.
Note that configuration names are case-insensitive. The value of this
variable will be the same as it is specified when invoking CMake.
For instance, if ``-DCMAKE_BUILD_TYPE=ReLeAsE`` is specified, then the
value of ``CMAKE_BUILD_TYPE`` will be ``ReLeAsE``.
Specifies the build type on single-configuration generators (e.g.
:ref:`Makefile Generators` or :generator:`Ninja`). Typical values include
``Debug``, ``Release``, ``RelWithDebInfo`` and ``MinSizeRel``, but custom
build types can also be defined.
This variable is initialized by the first :command:`project` or
:command:`enable_language` command called in a project when a new build
tree is first created. If the :envvar:`CMAKE_BUILD_TYPE` environment
variable is set, its value is used. Otherwise, a toolchain-specific
default is chosen when a language is enabled.
default is chosen when a language is enabled. The default value is often
an empty string, but this is usually not desirable and one of the other
standard build types is usually more appropriate.
See :variable:`CMAKE_CONFIGURATION_TYPES` for specifying the configuration
with multi-config generators.
Depending on the situation, the value of this variable may be treated
case-sensitively or case-insensitively. See :ref:`Build Configurations`
for discussion of this and other related topics.
For multi-config generators, see :variable:`CMAKE_CONFIGURATION_TYPES`.

View File

@@ -1,12 +1,11 @@
CMAKE_CONFIGURATION_TYPES
-------------------------
Specifies the available build types on multi-config generators.
This specifies what build types (configurations) will be available
such as ``Debug``, ``Release``, ``RelWithDebInfo`` etc. This has reasonable
defaults on most platforms, but can be extended to provide other build
types.
Specifies the available build types (configurations) on multi-config
generators (e.g. :ref:`Visual Studio <Visual Studio Generators>`,
:generator:`Xcode`, or :generator:`Ninja Multi-Config`). Typical values
include ``Debug``, ``Release``, ``RelWithDebInfo`` and ``MinSizeRel``,
but custom build types can also be defined.
This variable is initialized by the first :command:`project` or
:command:`enable_language` command called in a project when a new build
@@ -14,5 +13,8 @@ tree is first created. If the :envvar:`CMAKE_CONFIGURATION_TYPES`
environment variable is set, its value is used. Otherwise, the default
value is generator-specific.
See :variable:`CMAKE_BUILD_TYPE` for specifying the configuration with
single-config generators.
Depending on the situation, the values in this variable may be treated
case-sensitively or case-insensitively. See :ref:`Build Configurations`
for discussion of this and other related topics.
For single-config generators, see :variable:`CMAKE_BUILD_TYPE`.