Просмотр исходного кода

Merge topic 'doc-build-config'

b8d10c27d1 Help: Restructure build type docs and clarify case sensitivity

Acked-by: Kitware Robot <[email protected]>
Acked-by: Ben Boeckel <[email protected]>
Merge-request: !6516
Craig Scott 4 лет назад
Родитель
Сommit
b1745dcbca

+ 118 - 35
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
 ==============
 

+ 12 - 25
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`.

+ 10 - 8
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`.