diff options
author | Craig Scott <craig.scott@crascit.com> | 2021-09-22 12:19:49 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2021-09-22 12:20:08 (GMT) |
commit | b1745dcbca6f70e7fd3d78d75dc1aa851e5d0a47 (patch) | |
tree | 65fff02e67bfd3b4aafdd05b94ae211edd9b0338 /Help/manual | |
parent | 60caed1bd646a7efbf045d55e80286c0cf28c685 (diff) | |
parent | b8d10c27d12bc1c43056956abfb8b341f50c1124 (diff) | |
download | CMake-b1745dcbca6f70e7fd3d78d75dc1aa851e5d0a47.zip CMake-b1745dcbca6f70e7fd3d78d75dc1aa851e5d0a47.tar.gz CMake-b1745dcbca6f70e7fd3d78d75dc1aa851e5d0a47.tar.bz2 |
Merge topic 'doc-build-config'
b8d10c27d1 Help: Restructure build type docs and clarify case sensitivity
Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Ben Boeckel <ben.boeckel@kitware.com>
Merge-request: !6516
Diffstat (limited to 'Help/manual')
-rw-r--r-- | Help/manual/cmake-buildsystem.7.rst | 153 |
1 files changed, 118 insertions, 35 deletions
diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst index 7008383..2f43070 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 ============== |