diff options
-rw-r--r-- | Help/manual/cmake-buildsystem.7.rst | 153 | ||||
-rw-r--r-- | Help/variable/CMAKE_BUILD_TYPE.rst | 37 | ||||
-rw-r--r-- | Help/variable/CMAKE_CONFIGURATION_TYPES.rst | 18 |
3 files changed, 140 insertions, 68 deletions
diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst index 70083833d7..2f430705e4 100644 --- a/Help/manual/cmake-buildsystem.7.rst +++ b/Help/manual/cmake-buildsystem.7.rst @@ -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 ============== diff --git a/Help/variable/CMAKE_BUILD_TYPE.rst b/Help/variable/CMAKE_BUILD_TYPE.rst index 9ad1481e4b..bb95436ad3 100644 --- a/Help/variable/CMAKE_BUILD_TYPE.rst +++ b/Help/variable/CMAKE_BUILD_TYPE.rst @@ -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. + +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. -See :variable:`CMAKE_CONFIGURATION_TYPES` for specifying the configuration -with multi-config generators. +For multi-config generators, see :variable:`CMAKE_CONFIGURATION_TYPES`. diff --git a/Help/variable/CMAKE_CONFIGURATION_TYPES.rst b/Help/variable/CMAKE_CONFIGURATION_TYPES.rst index 5298a72530..75ff8a12a7 100644 --- a/Help/variable/CMAKE_CONFIGURATION_TYPES.rst +++ b/Help/variable/CMAKE_CONFIGURATION_TYPES.rst @@ -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`. |