New upstream version 3.27.0~rc4

ci/unstable
Timo Röhling 1 year ago
parent e6386a5b13
commit 6de3bd6333

@ -15,6 +15,7 @@ misc-*,\
-misc-no-recursion,\ -misc-no-recursion,\
-misc-non-private-member-variables-in-classes,\ -misc-non-private-member-variables-in-classes,\
-misc-static-assert,\ -misc-static-assert,\
-misc-use-anonymous-namespace,\
modernize-*,\ modernize-*,\
-modernize-avoid-c-arrays,\ -modernize-avoid-c-arrays,\
-modernize-macro-to-enum,\ -modernize-macro-to-enum,\

@ -372,7 +372,7 @@ optional argument topic will be appended to the argument list."
(interactive "s") (interactive "s")
(let* ((bufname (if buffer buffer (concat "*CMake" type (if topic "-") topic "*"))) (let* ((bufname (if buffer buffer (concat "*CMake" type (if topic "-") topic "*")))
(buffer (if (get-buffer bufname) (get-buffer bufname) (generate-new-buffer bufname))) (buffer (if (get-buffer bufname) (get-buffer bufname) (generate-new-buffer bufname)))
(command (concat cmake-mode-cmake-executable " " type " " topic)) (command (concat cmake-mode-cmake-executable " " type " " (if topic (shell-quote-argument topic) topic)))
;; Turn of resizing of mini-windows for shell-command. ;; Turn of resizing of mini-windows for shell-command.
(resize-mini-windows nil) (resize-mini-windows nil)
) )
@ -391,7 +391,7 @@ optional argument topic will be appended to the argument list."
(interactive "s") (interactive "s")
(let* ((bufname (if buffer buffer (concat "*CMake" type (if topic "-") topic "*"))) (let* ((bufname (if buffer buffer (concat "*CMake" type (if topic "-") topic "*")))
(buffer (if (get-buffer bufname) (get-buffer bufname) (generate-new-buffer bufname))) (buffer (if (get-buffer bufname) (get-buffer bufname) (generate-new-buffer bufname)))
(command (concat cmake-mode-cmake-executable " " type " " topic)) (command (concat cmake-mode-cmake-executable " " type " " (if topic (shell-quote-argument topic) topic)))
;; Turn of resizing of mini-windows for shell-command. ;; Turn of resizing of mini-windows for shell-command.
(resize-mini-windows nil) (resize-mini-windows nil)
) )

@ -73,6 +73,7 @@ syn keyword cmakeProperty contained
\ AUTOGEN_ORIGIN_DEPENDS \ AUTOGEN_ORIGIN_DEPENDS
\ AUTOGEN_PARALLEL \ AUTOGEN_PARALLEL
\ AUTOGEN_SOURCE_GROUP \ AUTOGEN_SOURCE_GROUP
\ AUTOGEN_USE_SYSTEM_INCLUDE
\ AUTOGEN_TARGETS_FOLDER \ AUTOGEN_TARGETS_FOLDER
\ AUTOGEN_TARGET_DEPENDS \ AUTOGEN_TARGET_DEPENDS
\ AUTOMOC \ AUTOMOC
@ -128,7 +129,10 @@ syn keyword cmakeProperty contained
\ CPACK_WIX_ACL \ CPACK_WIX_ACL
\ CROSSCOMPILING_EMULATOR \ CROSSCOMPILING_EMULATOR
\ CUDA_ARCHITECTURES \ CUDA_ARCHITECTURES
\ CUDA_CUBIN_COMPILATION
\ CUDA_EXTENSIONS \ CUDA_EXTENSIONS
\ CUDA_FATBIN_COMPILATION
\ CUDA_OPTIX_COMPILATION
\ CUDA_PTX_COMPILATION \ CUDA_PTX_COMPILATION
\ CUDA_RESOLVE_DEVICE_SYMBOLS \ CUDA_RESOLVE_DEVICE_SYMBOLS
\ CUDA_RUNTIME_LIBRARY \ CUDA_RUNTIME_LIBRARY
@ -217,6 +221,7 @@ syn keyword cmakeProperty contained
\ INSTALL_RPATH \ INSTALL_RPATH
\ INSTALL_RPATH_USE_LINK_PATH \ INSTALL_RPATH_USE_LINK_PATH
\ INTERFACE_AUTOUIC_OPTIONS \ INTERFACE_AUTOUIC_OPTIONS
\ INTERFACE_AUTOMOC_MACRO_NAMES
\ INTERFACE_COMPILE_DEFINITIONS \ INTERFACE_COMPILE_DEFINITIONS
\ INTERFACE_COMPILE_FEATURES \ INTERFACE_COMPILE_FEATURES
\ INTERFACE_COMPILE_OPTIONS \ INTERFACE_COMPILE_OPTIONS
@ -320,6 +325,7 @@ syn keyword cmakeProperty contained
\ SKIP_AUTORCC \ SKIP_AUTORCC
\ SKIP_AUTOUIC \ SKIP_AUTOUIC
\ SKIP_BUILD_RPATH \ SKIP_BUILD_RPATH
\ SKIP_LINTING
\ SKIP_PRECOMPILE_HEADERS \ SKIP_PRECOMPILE_HEADERS
\ SKIP_REGULAR_EXPRESSION \ SKIP_REGULAR_EXPRESSION
\ SKIP_RETURN_CODE \ SKIP_RETURN_CODE
@ -459,6 +465,7 @@ syn keyword cmakeVariable contained
\ BUILD_SHARED_LIBS \ BUILD_SHARED_LIBS
\ CACHE \ CACHE
\ CMAKE_ABSOLUTE_DESTINATION_FILES \ CMAKE_ABSOLUTE_DESTINATION_FILES
\ CMAKE_ADD_CUSTOM_COMMAND_DEPENDS_EXPLICIT_ONLY
\ CMAKE_AIX_EXPORT_ALL_SYMBOLS \ CMAKE_AIX_EXPORT_ALL_SYMBOLS
\ CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS \ CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS
\ CMAKE_ANDROID_API \ CMAKE_ANDROID_API
@ -678,6 +685,7 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_VISIBILITY_PRESET \ CMAKE_ASM_VISIBILITY_PRESET
\ CMAKE_AUTOGEN_ORIGIN_DEPENDS \ CMAKE_AUTOGEN_ORIGIN_DEPENDS
\ CMAKE_AUTOGEN_PARALLEL \ CMAKE_AUTOGEN_PARALLEL
\ CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE
\ CMAKE_AUTOGEN_VERBOSE \ CMAKE_AUTOGEN_VERBOSE
\ CMAKE_AUTOMOC \ CMAKE_AUTOMOC
\ CMAKE_AUTOMOC_COMPILER_PREDEFINES \ CMAKE_AUTOMOC_COMPILER_PREDEFINES
@ -686,11 +694,14 @@ syn keyword cmakeVariable contained
\ CMAKE_AUTOMOC_MOC_OPTIONS \ CMAKE_AUTOMOC_MOC_OPTIONS
\ CMAKE_AUTOMOC_PATH_PREFIX \ CMAKE_AUTOMOC_PATH_PREFIX
\ CMAKE_AUTOMOC_RELAXED_MODE \ CMAKE_AUTOMOC_RELAXED_MODE
\ CMAKE_AUTOMOC_EXECUTABLE
\ CMAKE_AUTORCC \ CMAKE_AUTORCC
\ CMAKE_AUTORCC_OPTIONS \ CMAKE_AUTORCC_OPTIONS
\ CMAKE_AUTORCC_EXECUTABLE
\ CMAKE_AUTOUIC \ CMAKE_AUTOUIC
\ CMAKE_AUTOUIC_OPTIONS \ CMAKE_AUTOUIC_OPTIONS
\ CMAKE_AUTOUIC_SEARCH_PATHS \ CMAKE_AUTOUIC_SEARCH_PATHS
\ CMAKE_AUTOUIC_EXECUTABLE
\ CMAKE_BACKWARDS_COMPATIBILITY \ CMAKE_BACKWARDS_COMPATIBILITY
\ CMAKE_BINARY_DIR \ CMAKE_BINARY_DIR
\ CMAKE_BUILD_RPATH \ CMAKE_BUILD_RPATH
@ -2095,6 +2106,7 @@ syn keyword cmakeKWadd_custom_command contained
\ COMMENT \ COMMENT
\ CROSSCOMPILING_EMULATOR \ CROSSCOMPILING_EMULATOR
\ DEPENDS \ DEPENDS
\ DEPENDS_EXPLICIT_ONLY
\ DEPFILE \ DEPFILE
\ GENERATED \ GENERATED
\ IMPLICIT_DEPENDS \ IMPLICIT_DEPENDS
@ -2735,6 +2747,7 @@ syn keyword cmakeKWfile contained
\ READ_SYMLINK \ READ_SYMLINK
\ REAL_PATH \ REAL_PATH
\ REGEX \ REGEX
\ RELATIVE
\ RELATIVE_PATH \ RELATIVE_PATH
\ RELEASE \ RELEASE
\ REMOVE \ REMOVE

@ -1,7 +1,7 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details. # file Copyright.txt or https://cmake.org/licensing for details.
cmake_minimum_required(VERSION 3.13...3.24 FATAL_ERROR) cmake_minimum_required(VERSION 3.13...3.25 FATAL_ERROR)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideC.cmake) set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideC.cmake)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideCXX.cmake) set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideCXX.cmake)
@ -131,6 +131,23 @@ if(CMake_BUILD_LTO)
endif() endif()
endif() endif()
# Check whether to build support for the debugger mode.
if(NOT CMake_TEST_EXTERNAL_CMAKE)
if(NOT DEFINED CMake_ENABLE_DEBUGGER)
# The debugger uses cppdap, which does not compile everywhere.
if(CMAKE_SYSTEM_NAME MATCHES "Windows|Darwin|Linux|BSD|DragonFly|CYGWIN|MSYS"
AND NOT (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.16)
AND NOT (CMAKE_CXX_COMPILER_ID STREQUAL "XLClang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16.1)
)
set(CMake_ENABLE_DEBUGGER 1)
else()
set(CMake_ENABLE_DEBUGGER 0)
endif()
endif()
else()
set(CMake_ENABLE_DEBUGGER 0)
endif()
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# a macro to deal with system libraries, implemented as a macro # a macro to deal with system libraries, implemented as a macro
# simply to improve readability of the main script # simply to improve readability of the main script
@ -141,7 +158,7 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
# Allow the user to enable/disable all system utility library options by # Allow the user to enable/disable all system utility library options by
# defining CMAKE_USE_SYSTEM_LIBRARIES or CMAKE_USE_SYSTEM_LIBRARY_${util}. # defining CMAKE_USE_SYSTEM_LIBRARIES or CMAKE_USE_SYSTEM_LIBRARY_${util}.
set(UTILITIES BZIP2 CURL EXPAT FORM JSONCPP LIBARCHIVE LIBLZMA LIBRHASH LIBUV NGHTTP2 ZLIB ZSTD) set(UTILITIES BZIP2 CPPDAP CURL EXPAT FORM JSONCPP LIBARCHIVE LIBLZMA LIBRHASH LIBUV NGHTTP2 ZLIB ZSTD)
foreach(util IN LISTS UTILITIES) foreach(util IN LISTS UTILITIES)
if(NOT DEFINED CMAKE_USE_SYSTEM_LIBRARY_${util} if(NOT DEFINED CMAKE_USE_SYSTEM_LIBRARY_${util}
AND DEFINED CMAKE_USE_SYSTEM_LIBRARIES) AND DEFINED CMAKE_USE_SYSTEM_LIBRARIES)
@ -169,6 +186,9 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
# Optionally use system utility libraries. # Optionally use system utility libraries.
option(CMAKE_USE_SYSTEM_LIBARCHIVE "Use system-installed libarchive" "${CMAKE_USE_SYSTEM_LIBRARY_LIBARCHIVE}") option(CMAKE_USE_SYSTEM_LIBARCHIVE "Use system-installed libarchive" "${CMAKE_USE_SYSTEM_LIBRARY_LIBARCHIVE}")
if(CMake_ENABLE_DEBUGGER)
option(CMAKE_USE_SYSTEM_CPPDAP "Use system-installed cppdap" "${CMAKE_USE_SYSTEM_LIBRARY_CPPDAP}")
endif()
option(CMAKE_USE_SYSTEM_CURL "Use system-installed curl" "${CMAKE_USE_SYSTEM_LIBRARY_CURL}") option(CMAKE_USE_SYSTEM_CURL "Use system-installed curl" "${CMAKE_USE_SYSTEM_LIBRARY_CURL}")
option(CMAKE_USE_SYSTEM_EXPAT "Use system-installed expat" "${CMAKE_USE_SYSTEM_LIBRARY_EXPAT}") option(CMAKE_USE_SYSTEM_EXPAT "Use system-installed expat" "${CMAKE_USE_SYSTEM_LIBRARY_EXPAT}")
CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_ZLIB "Use system-installed zlib" CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_ZLIB "Use system-installed zlib"
@ -182,7 +202,8 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_NGHTTP2 "Use system-installed nghttp2" CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_NGHTTP2 "Use system-installed nghttp2"
"${CMAKE_USE_SYSTEM_LIBRARY_NGHTTP2}" "NOT CMAKE_USE_SYSTEM_CURL" ON) "${CMAKE_USE_SYSTEM_LIBRARY_NGHTTP2}" "NOT CMAKE_USE_SYSTEM_CURL" ON)
option(CMAKE_USE_SYSTEM_FORM "Use system-installed libform" "${CMAKE_USE_SYSTEM_LIBRARY_FORM}") option(CMAKE_USE_SYSTEM_FORM "Use system-installed libform" "${CMAKE_USE_SYSTEM_LIBRARY_FORM}")
option(CMAKE_USE_SYSTEM_JSONCPP "Use system-installed jsoncpp" "${CMAKE_USE_SYSTEM_LIBRARY_JSONCPP}") CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_JSONCPP "Use system-installed jsoncpp"
"${CMAKE_USE_SYSTEM_LIBRARY_JSONCPP}" "NOT CMAKE_USE_SYSTEM_CPPDAP" ON)
option(CMAKE_USE_SYSTEM_LIBRHASH "Use system-installed librhash" "${CMAKE_USE_SYSTEM_LIBRARY_LIBRHASH}") option(CMAKE_USE_SYSTEM_LIBRHASH "Use system-installed librhash" "${CMAKE_USE_SYSTEM_LIBRARY_LIBRHASH}")
option(CMAKE_USE_SYSTEM_LIBUV "Use system-installed libuv" "${CMAKE_USE_SYSTEM_LIBRARY_LIBUV}") option(CMAKE_USE_SYSTEM_LIBUV "Use system-installed libuv" "${CMAKE_USE_SYSTEM_LIBRARY_LIBUV}")

@ -8,7 +8,7 @@ if(WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "Intel")
set(_INTEL_WINDOWS 1) set(_INTEL_WINDOWS 1)
endif() endif()
if(WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "Clang" if(WIN32 AND CMAKE_C_COMPILER_ID MATCHES "^(Clang|IntelLLVM)$"
AND "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") AND "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
set(_CLANG_MSVC_WINDOWS 1) set(_CLANG_MSVC_WINDOWS 1)
endif() endif()
@ -22,18 +22,19 @@ if(MSVC OR _INTEL_WINDOWS OR _CLANG_MSVC_WINDOWS)
else() else()
endif() endif()
if(MSVC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_CXX_LINKER_WRAPPER_FLAG}-stack:10000000")
endif()
# MSVC 14.28 enables C5105, but the Windows SDK 10.0.18362.0 triggers it. # MSVC 14.28 enables C5105, but the Windows SDK 10.0.18362.0 triggers it.
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 19.28) if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 19.28)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -wd5105") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -wd5105")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -wd5105") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -wd5105")
endif() endif()
if(_CLANG_MSVC_WINDOWS AND "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU") # Use a stack size large enough for CMake_DEFAULT_RECURSION_LIMIT.
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Xlinker -stack:20000000") if(MSVC)
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${CMAKE_CXX_LINKER_WRAPPER_FLAG}-stack:10000000")
elseif(MINGW OR MSYS OR CYGWIN)
string(APPEND CMAKE_EXE_LINKER_FLAGS " -Wl,--stack,10000000")
elseif(_CLANG_MSVC_WINDOWS AND "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
string(APPEND CMAKE_EXE_LINKER_FLAGS " -Xlinker -stack:20000000")
endif() endif()
#silence duplicate symbol warnings on AIX #silence duplicate symbol warnings on AIX

@ -132,6 +132,9 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
.. |CMAKE_PREFIX_PATH_XXX_SUBDIR| replace:: .. |CMAKE_PREFIX_PATH_XXX_SUBDIR| replace::
|prefix_XXX_SUBDIR| for each ``<prefix>`` in :variable:`CMAKE_PREFIX_PATH` |prefix_XXX_SUBDIR| for each ``<prefix>`` in :variable:`CMAKE_PREFIX_PATH`
.. |ENV_CMAKE_PREFIX_PATH_XXX_SUBDIR| replace::
|prefix_XXX_SUBDIR| for each ``<prefix>`` in :envvar:`CMAKE_PREFIX_PATH`
.. |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR| replace:: .. |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR| replace::
|prefix_XXX_SUBDIR| for each ``<prefix>/[s]bin`` in ``PATH``, and |prefix_XXX_SUBDIR| for each ``<prefix>/[s]bin`` in ``PATH``, and
|entry_XXX_SUBDIR| for other entries in ``PATH`` |entry_XXX_SUBDIR| for other entries in ``PATH``
@ -140,12 +143,32 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
|prefix_XXX_SUBDIR| for each ``<prefix>`` in |prefix_XXX_SUBDIR| for each ``<prefix>`` in
:variable:`CMAKE_SYSTEM_PREFIX_PATH` :variable:`CMAKE_SYSTEM_PREFIX_PATH`
1. .. versionadded:: 3.12 1. If called from within a find module or any other script loaded by a call to
If called from within a find module or any other script loaded by a call to
:command:`find_package(<PackageName>)`, search prefixes unique to the :command:`find_package(<PackageName>)`, search prefixes unique to the
current package being found. Specifically, look in the current package being found. See policy :policy:`CMP0074`.
:variable:`<PackageName>_ROOT` CMake variable and the
:envvar:`<PackageName>_ROOT` environment variable. .. versionadded:: 3.12
Specifically, search paths specified by the following variables, in order:
a. :variable:`<PackageName>_ROOT` CMake variable,
where ``<PackageName>`` is the case-preserved package name.
b. :variable:`<PACKAGENAME>_ROOT` CMake variable,
where ``<PACKAGENAME>`` is the upper-cased package name.
See policy :policy:`CMP0144`.
.. versionadded:: 3.27
c. :envvar:`<PackageName>_ROOT` environment variable,
where ``<PackageName>`` is the case-preserved package name.
d. :envvar:`<PACKAGENAME>_ROOT` environment variable,
where ``<PACKAGENAME>`` is the upper-cased package name.
See policy :policy:`CMP0144`.
.. versionadded:: 3.27
The package root variables are maintained as a stack, so if called from The package root variables are maintained as a stack, so if called from
nested find modules or config packages, root paths from the parent's find nested find modules or config packages, root paths from the parent's find
module or config package will be searched after paths from the current module or config package will be searched after paths from the current
@ -154,7 +177,6 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
``<ParentPackage>_ROOT``, ``ENV{<ParentPackage>_ROOT}``, etc. ``<ParentPackage>_ROOT``, ``ENV{<ParentPackage>_ROOT}``, etc.
This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``. the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
See policy :policy:`CMP0074`.
* |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX| * |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX|
@ -175,9 +197,9 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
This can be skipped if ``NO_CMAKE_ENVIRONMENT_PATH`` is passed or This can be skipped if ``NO_CMAKE_ENVIRONMENT_PATH`` is passed or
by setting the :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH` to ``FALSE``. by setting the :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH` to ``FALSE``.
* |CMAKE_PREFIX_PATH_XXX| * |ENV_CMAKE_PREFIX_PATH_XXX|
* |CMAKE_XXX_PATH| * |ENV_CMAKE_XXX_PATH|
* |CMAKE_XXX_MAC_PATH| * |ENV_CMAKE_XXX_MAC_PATH|
4. Search the paths specified by the ``HINTS`` option. 4. Search the paths specified by the ``HINTS`` option.
These should be paths computed by system introspection, such as a These should be paths computed by system introspection, such as a

@ -0,0 +1,9 @@
.. note::
When evaluating :ref:`Variable References` of the form ``${VAR}``, CMake
first searches for a normal variable with that name. If no such normal
variable exists, CMake will then search for a cache entry with that name.
Because of this, **unsetting a normal variable can expose a cache variable
that was previously hidden**. To force a variable reference of the form
``${VAR}`` to return an empty string, use ``set(<variable> "")``, which
clears the normal variable but leaves it defined.

@ -11,6 +11,11 @@ Adds options to the :prop_dir:`COMPILE_OPTIONS` directory property.
These options are used when compiling targets from the current These options are used when compiling targets from the current
directory and below. directory and below.
.. note::
These options are not used when linking.
See the :command:`add_link_options` command for that.
Arguments Arguments
^^^^^^^^^ ^^^^^^^^^
@ -48,5 +53,15 @@ See Also
* The command :command:`target_compile_options` adds target-specific options. * The command :command:`target_compile_options` adds target-specific options.
* This command adds compile options for all languages.
Use the :genex:`COMPILE_LANGUAGE` generator expression to specify
per-language compile options.
* The source file property :prop_sf:`COMPILE_OPTIONS` adds options to one * The source file property :prop_sf:`COMPILE_OPTIONS` adds options to one
source file. source file.
* :command:`add_link_options` adds options for linking.
* :variable:`CMAKE_<LANG>_FLAGS` and :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>`
add language-wide flags passed to all invocations of the compiler.
This includes invocations that drive compiling and those that drive linking.

@ -25,7 +25,8 @@ The first signature is for adding a custom command to produce an output:
[DEPFILE depfile] [DEPFILE depfile]
[JOB_POOL job_pool] [JOB_POOL job_pool]
[VERBATIM] [APPEND] [USES_TERMINAL] [VERBATIM] [APPEND] [USES_TERMINAL]
[COMMAND_EXPAND_LISTS]) [COMMAND_EXPAND_LISTS]
[DEPENDS_EXPLICIT_ONLY])
This defines a command to generate specified ``OUTPUT`` file(s). This defines a command to generate specified ``OUTPUT`` file(s).
A target created in the same directory (``CMakeLists.txt`` file) A target created in the same directory (``CMakeLists.txt`` file)
@ -357,6 +358,24 @@ The options are:
:ref:`Makefile Generators`, :ref:`Visual Studio Generators`, :ref:`Makefile Generators`, :ref:`Visual Studio Generators`,
and the :generator:`Xcode` generator. and the :generator:`Xcode` generator.
``DEPENDS_EXPLICIT_ONLY``
.. versionadded:: 3.27
Indicate that the command's ``DEPENDS`` argument represents all files
required by the command and implicit dependencies are not required.
Without this option, if any target uses the output of the custom command,
CMake will consider that target's dependencies as implicit dependencies for
the custom command in case this custom command requires files implicitly
created by those targets.
This option can be enabled on all custom commands by setting
:variable:`CMAKE_ADD_CUSTOM_COMMAND_DEPENDS_EXPLICIT_ONLY` to ``ON``.
Only the :ref:`Ninja Generators` actually use this information to remove
unnecessary implicit dependencies.
Examples: Generating Files Examples: Generating Files
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -459,7 +478,7 @@ target is already built, the command will not execute.
[BYPRODUCTS [files...]] [BYPRODUCTS [files...]]
[WORKING_DIRECTORY dir] [WORKING_DIRECTORY dir]
[COMMENT comment] [COMMENT comment]
[VERBATIM] [USES_TERMINAL] [VERBATIM]
[COMMAND_EXPAND_LISTS]) [COMMAND_EXPAND_LISTS])
This defines a new command that will be associated with building the This defines a new command that will be associated with building the
@ -470,9 +489,12 @@ When the command will happen is determined by which
of the following is specified: of the following is specified:
``PRE_BUILD`` ``PRE_BUILD``
On :ref:`Visual Studio Generators`, run before any other rules are This option has unique behavior for the :ref:`Visual Studio Generators`.
executed within the target. When using one of the Visual Studio generators, the command will run before
On other generators, run just before ``PRE_LINK`` commands. any other rules are executed within the target. With all other generators,
this option behaves the same as ``PRE_LINK`` instead. Because of this,
it is recommended to avoid using ``PRE_BUILD`` except when it is known that
a Visual Studio generator is being used.
``PRE_LINK`` ``PRE_LINK``
Run after sources have been compiled but before linking the binary Run after sources have been compiled but before linking the binary
or running the librarian or archiver tool of a static library. or running the librarian or archiver tool of a static library.

@ -38,3 +38,7 @@ See Also
* :command:`link_libraries` * :command:`link_libraries`
* :command:`target_link_libraries` * :command:`target_link_libraries`
* :command:`target_link_options` * :command:`target_link_options`
* :variable:`CMAKE_<LANG>_FLAGS` and :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>`
add language-wide flags passed to all invocations of the compiler.
This includes invocations that drive compiling and those that drive linking.

@ -12,13 +12,24 @@ Add a test to the project to be run by :manual:`ctest(1)`.
Adds a test called ``<name>``. The test name may contain arbitrary Adds a test called ``<name>``. The test name may contain arbitrary
characters, expressed as a :ref:`Quoted Argument` or :ref:`Bracket Argument` characters, expressed as a :ref:`Quoted Argument` or :ref:`Bracket Argument`
if necessary. See policy :policy:`CMP0110`. The options are: if necessary. See policy :policy:`CMP0110`.
CMake only generates tests if the :command:`enable_testing` command has been
invoked. The :module:`CTest` module invokes ``enable_testing`` automatically
unless ``BUILD_TESTING`` is set to ``OFF``.
Tests added with the ``add_test(NAME)`` signature support using
:manual:`generator expressions <cmake-generator-expressions(7)>`
in test properties set by :command:`set_property(TEST)` or
:command:`set_tests_properties`. Test properties may only be set in the
directory the test is created in.
``add_test`` options are:
``COMMAND`` ``COMMAND``
Specify the test command-line. If ``<command>`` specifies an Specify the test command-line. If ``<command>`` specifies an executable
executable target (created by :command:`add_executable`) it will target created by :command:`add_executable`, it will automatically be
automatically be replaced by the location of the executable created replaced by the location of the executable created at build time.
at build time.
The command may be specified using The command may be specified using
:manual:`generator expressions <cmake-generator-expressions(7)>`. :manual:`generator expressions <cmake-generator-expressions(7)>`.
@ -27,38 +38,29 @@ if necessary. See policy :policy:`CMP0110`. The options are:
Restrict execution of the test only to the named configurations. Restrict execution of the test only to the named configurations.
``WORKING_DIRECTORY`` ``WORKING_DIRECTORY``
Set the :prop_test:`WORKING_DIRECTORY` test property to Set the test property :prop_test:`WORKING_DIRECTORY` in which to execute the
specify the working directory in which to execute the test. test. If not specified, the test will be run in
If not specified the test will be run with the current working :variable:`CMAKE_CURRENT_BINARY_DIR`. The working directory may be specified
directory set to the build directory corresponding to the using :manual:`generator expressions <cmake-generator-expressions(7)>`.
current source directory.
The working directory may be specified using
:manual:`generator expressions <cmake-generator-expressions(7)>`.
``COMMAND_EXPAND_LISTS`` ``COMMAND_EXPAND_LISTS``
.. versionadded:: 3.16 .. versionadded:: 3.16
Lists in ``COMMAND`` arguments will be expanded, including those Lists in ``COMMAND`` arguments will be expanded, including those created with
created with
:manual:`generator expressions <cmake-generator-expressions(7)>`. :manual:`generator expressions <cmake-generator-expressions(7)>`.
The given test command is expected to exit with code ``0`` to pass and If the test command exits with code ``0`` the test passes. Non-zero exit code
non-zero to fail, or vice-versa if the :prop_test:`WILL_FAIL` test is a "failed" test. The test property :prop_test:`WILL_FAIL` inverts this
property is set. Any output written to stdout or stderr will be logic. Note that system-level test failures such as segmentation faults or
captured by :manual:`ctest(1)` but does not affect the pass/fail status heap errors will still fail the test even if ``WILL_FALL`` is true. Output
unless the :prop_test:`PASS_REGULAR_EXPRESSION`, written to stdout or stderr is captured by :manual:`ctest(1)` and only
:prop_test:`FAIL_REGULAR_EXPRESSION` or affects the pass/fail status via the :prop_test:`PASS_REGULAR_EXPRESSION`,
:prop_test:`SKIP_REGULAR_EXPRESSION` test property is used. :prop_test:`FAIL_REGULAR_EXPRESSION`, or :prop_test:`SKIP_REGULAR_EXPRESSION`
test properties.
.. versionadded:: 3.16 .. versionadded:: 3.16
Added :prop_test:`SKIP_REGULAR_EXPRESSION` property. Added :prop_test:`SKIP_REGULAR_EXPRESSION` property.
Tests added with the ``add_test(NAME)`` signature support using
:manual:`generator expressions <cmake-generator-expressions(7)>`
in test properties set by :command:`set_property(TEST)` or
:command:`set_tests_properties`.
Example usage: Example usage:
.. code-block:: cmake .. code-block:: cmake
@ -71,16 +73,9 @@ This creates a test ``mytest`` whose command runs a ``testDriver`` tool
passing the configuration name and the full path to the executable passing the configuration name and the full path to the executable
file produced by target ``myexe``. file produced by target ``myexe``.
.. note::
CMake will generate tests only if the :command:`enable_testing`
command has been invoked. The :module:`CTest` module invokes the
command automatically unless the ``BUILD_TESTING`` option is turned
``OFF``.
--------------------------------------------------------------------- ---------------------------------------------------------------------
This command also supports a simpler, but less flexible, signature: The command syntax above is recommended over the older, less flexible form:
.. code-block:: cmake .. code-block:: cmake

@ -0,0 +1,78 @@
cmake_file_api
--------------
.. versionadded:: 3.27
Enables interacting with the :manual:`CMake file API <cmake-file-api(7)>`.
.. signature::
cmake_file_api(QUERY ...)
The ``QUERY`` subcommand adds a file API query for the current CMake
invocation.
.. code-block:: cmake
cmake_file_api(
QUERY
API_VERSION <version>
[CODEMODEL <versions>...]
[CACHE <versions>...]
[CMAKEFILES <versions>...]
[TOOLCHAINS <versions>...]
)
The ``API_VERSION`` must always be given. Currently, the only supported
value for ``<version>`` is 1. See :ref:`file-api v1` for details of the
reply content and location.
Each of the optional keywords ``CODEMODEL``, ``CACHE``, ``CMAKEFILES`` and
``TOOLCHAINS`` correspond to one of the object kinds that can be requested
by the project. The ``configureLog`` object kind cannot be set with this
command, since it must be set before CMake starts reading the top level
``CMakeLists.txt`` file.
For each of the optional keywords, the ``<versions>`` list must contain one
or more version values of the form ``major`` or ``major.minor``, where
``major`` and ``minor`` are integers. Projects should list the versions they
accept in their preferred order, as only the first supported value from the
list will be selected. The command will ignore versions with a ``major``
version higher than any major version it supports for that object kind.
It will raise an error if it encounters an invalid version number, or if none
of the requested versions is supported.
For each type of object kind requested, a query equivalent to a shared,
stateless query will be added internally. No query file will be created in
the file system. The reply *will* be written to the file system at
generation time.
It is not an error to add a query for the same thing more than once, whether
from query files or from multiple calls to ``cmake_file_api(QUERY)``.
The final set of queries will be a merged combination of all queries
specified on disk and queries submitted by the project.
Example
^^^^^^^
A project may want to use replies from the file API at build time to implement
some form of verification task. Instead of relying on something outside of
CMake to create a query file, the project can use ``cmake_file_api(QUERY)``
to request the required information for the current run. It can then create
a custom command to run at build time, knowing that the requested information
should always be available.
.. code-block:: cmake
cmake_file_api(
QUERY
API_VERSION 1
CODEMODEL 2.3
TOOLCHAINS 1
)
add_custom_target(verify_project
COMMAND ${CMAKE_COMMAND}
-D BUILD_DIR=${CMAKE_BINARY_DIR}
-D CONFIG=$<CONFIG>
-P ${CMAKE_CURRENT_SOURCE_DIR}/verify_project.cmake
)

@ -27,27 +27,24 @@ those created via the :command:`macro` or :command:`function` commands.
Calling Commands Calling Commands
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
.. _CALL: .. signature::
.. code-block:: cmake
cmake_language(CALL <command> [<arg>...]) cmake_language(CALL <command> [<arg>...])
Calls the named ``<command>`` with the given arguments (if any). Calls the named ``<command>`` with the given arguments (if any).
For example, the code: For example, the code:
.. code-block:: cmake .. code-block:: cmake
set(message_command "message") set(message_command "message")
cmake_language(CALL ${message_command} STATUS "Hello World!") cmake_language(CALL ${message_command} STATUS "Hello World!")
is equivalent to is equivalent to
.. code-block:: cmake .. code-block:: cmake
message(STATUS "Hello World!") message(STATUS "Hello World!")
.. note:: .. note::
To ensure consistency of the code, the following commands are not allowed: To ensure consistency of the code, the following commands are not allowed:
* ``if`` / ``elseif`` / ``else`` / ``endif`` * ``if`` / ``elseif`` / ``else`` / ``endif``
@ -60,17 +57,15 @@ is equivalent to
Evaluating Code Evaluating Code
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
.. _EVAL: .. signature::
.. code-block:: cmake
cmake_language(EVAL CODE <code>...) cmake_language(EVAL CODE <code>...)
:target: EVAL
Evaluates the ``<code>...`` as CMake code. Evaluates the ``<code>...`` as CMake code.
For example, the code: For example, the code:
.. code-block:: cmake .. code-block:: cmake
set(A TRUE) set(A TRUE)
set(B TRUE) set(B TRUE)
@ -85,9 +80,9 @@ For example, the code:
endif()" endif()"
) )
is equivalent to is equivalent to
.. code-block:: cmake .. code-block:: cmake
set(A TRUE) set(A TRUE)
set(B TRUE) set(B TRUE)
@ -109,22 +104,19 @@ Deferring Calls
.. versionadded:: 3.19 .. versionadded:: 3.19
.. _DEFER: .. signature::
.. code-block:: cmake
cmake_language(DEFER <options>... CALL <command> [<arg>...]) cmake_language(DEFER <options>... CALL <command> [<arg>...])
Schedules a call to the named ``<command>`` with the given arguments (if any) Schedules a call to the named ``<command>`` with the given arguments (if any)
to occur at a later time. By default, deferred calls are executed as if to occur at a later time. By default, deferred calls are executed as if
written at the end of the current directory's ``CMakeLists.txt`` file, written at the end of the current directory's ``CMakeLists.txt`` file,
except that they run even after a :command:`return` call. Variable except that they run even after a :command:`return` call. Variable
references in arguments are evaluated at the time the deferred call is references in arguments are evaluated at the time the deferred call is
executed. executed.
The options are: The options are:
``DIRECTORY <dir>`` ``DIRECTORY <dir>``
Schedule the call for the end of the given directory instead of the Schedule the call for the end of the given directory instead of the
current directory. The ``<dir>`` may reference either a source current directory. The ``<dir>`` may reference either a source
directory or its corresponding binary directory. Relative paths are directory or its corresponding binary directory. Relative paths are
@ -135,55 +127,55 @@ The options are:
the given directory must not yet be finished processing. This means the given directory must not yet be finished processing. This means
it can be the current directory or one of its ancestors. it can be the current directory or one of its ancestors.
``ID <id>`` ``ID <id>``
Specify an identification for the deferred call. Specify an identification for the deferred call.
The ``<id>`` may not be empty and may not begin with a capital letter ``A-Z``. The ``<id>`` may not be empty and may not begin with a capital letter ``A-Z``.
The ``<id>`` may begin with an underscore (``_``) only if it was generated The ``<id>`` may begin with an underscore (``_``) only if it was generated
automatically by an earlier call that used ``ID_VAR`` to get the id. automatically by an earlier call that used ``ID_VAR`` to get the id.
``ID_VAR <var>`` ``ID_VAR <var>``
Specify a variable in which to store the identification for the Specify a variable in which to store the identification for the
deferred call. If ``ID <id>`` is not given, a new identification deferred call. If ``ID <id>`` is not given, a new identification
will be generated and the generated id will start with an underscore (``_``). will be generated and the generated id will start with an underscore (``_``).
The currently scheduled list of deferred calls may be retrieved: The currently scheduled list of deferred calls may be retrieved:
.. code-block:: cmake .. code-block:: cmake
cmake_language(DEFER [DIRECTORY <dir>] GET_CALL_IDS <var>) cmake_language(DEFER [DIRECTORY <dir>] GET_CALL_IDS <var>)
This will store in ``<var>`` a :ref:`semicolon-separated list <CMake Language This will store in ``<var>`` a :ref:`semicolon-separated list <CMake Language
Lists>` of deferred call ids. The ids are for the directory scope in which Lists>` of deferred call ids. The ids are for the directory scope in which
the calls have been deferred to (i.e. where they will be executed), which can the calls have been deferred to (i.e. where they will be executed), which can
be different to the scope in which they were created. The ``DIRECTORY`` be different to the scope in which they were created. The ``DIRECTORY``
option can be used to specify the scope for which to retrieve the call ids. option can be used to specify the scope for which to retrieve the call ids.
If that option is not given, the call ids for the current directory scope will If that option is not given, the call ids for the current directory scope
be returned. will be returned.
Details of a specific call may be retrieved from its id: Details of a specific call may be retrieved from its id:
.. code-block:: cmake .. code-block:: cmake
cmake_language(DEFER [DIRECTORY <dir>] GET_CALL <id> <var>) cmake_language(DEFER [DIRECTORY <dir>] GET_CALL <id> <var>)
This will store in ``<var>`` a :ref:`semicolon-separated list <CMake Language This will store in ``<var>`` a :ref:`semicolon-separated list <CMake Language
Lists>` in which the first element is the name of the command to be Lists>` in which the first element is the name of the command to be
called, and the remaining elements are its unevaluated arguments (any called, and the remaining elements are its unevaluated arguments (any
contained ``;`` characters are included literally and cannot be distinguished contained ``;`` characters are included literally and cannot be distinguished
from multiple arguments). If multiple calls are scheduled with the same id, from multiple arguments). If multiple calls are scheduled with the same id,
this retrieves the first one. If no call is scheduled with the given id in this retrieves the first one. If no call is scheduled with the given id in
the specified ``DIRECTORY`` scope (or the current directory scope if no the specified ``DIRECTORY`` scope (or the current directory scope if no
``DIRECTORY`` option is given), this stores an empty string in the variable. ``DIRECTORY`` option is given), this stores an empty string in the variable.
Deferred calls may be canceled by their id: Deferred calls may be canceled by their id:
.. code-block:: cmake .. code-block:: cmake
cmake_language(DEFER [DIRECTORY <dir>] CANCEL_CALL <id>...) cmake_language(DEFER [DIRECTORY <dir>] CANCEL_CALL <id>...)
This cancels all deferred calls matching any of the given ids in the specified This cancels all deferred calls matching any of the given ids in the specified
``DIRECTORY`` scope (or the current directory scope if no ``DIRECTORY`` option ``DIRECTORY`` scope (or the current directory scope if no ``DIRECTORY`` option
is given). Unknown ids are silently ignored. is given). Unknown ids are silently ignored.
Deferred Call Examples Deferred Call Examples
"""""""""""""""""""""" """"""""""""""""""""""
@ -229,8 +221,6 @@ also prints::
Deferred Message 1 Deferred Message 1
Deferred Message 2 Deferred Message 2
.. _SET_DEPENDENCY_PROVIDER:
.. _dependency_providers: .. _dependency_providers:
Dependency Providers Dependency Providers
@ -241,47 +231,46 @@ Dependency Providers
.. note:: A high-level introduction to this feature can be found in the .. note:: A high-level introduction to this feature can be found in the
:ref:`Using Dependencies Guide <dependency_providers_overview>`. :ref:`Using Dependencies Guide <dependency_providers_overview>`.
.. code-block:: cmake .. signature::
cmake_language(SET_DEPENDENCY_PROVIDER <command> cmake_language(SET_DEPENDENCY_PROVIDER <command>
SUPPORTED_METHODS <methods>...) SUPPORTED_METHODS <methods>...)
When a call is made to :command:`find_package` or When a call is made to :command:`find_package` or
:command:`FetchContent_MakeAvailable`, the call may be forwarded to a :command:`FetchContent_MakeAvailable`, the call may be forwarded to a
dependency provider which then has the opportunity to fulfill the request. dependency provider which then has the opportunity to fulfill the request.
If the request is for one of the ``<methods>`` specified when the provider If the request is for one of the ``<methods>`` specified when the provider
was set, CMake calls the provider's ``<command>`` with a set of was set, CMake calls the provider's ``<command>`` with a set of
method-specific arguments. If the provider does not fulfill the request, method-specific arguments. If the provider does not fulfill the request,
or if the provider doesn't support the request's method, or no provider or if the provider doesn't support the request's method, or no provider
is set, the built-in :command:`find_package` or is set, the built-in :command:`find_package` or
:command:`FetchContent_MakeAvailable` implementation is used to fulfill :command:`FetchContent_MakeAvailable` implementation is used to fulfill
the request in the usual way. the request in the usual way.
One or more of the following values can be specified for the ``<methods>`` One or more of the following values can be specified for the ``<methods>``
when setting the provider: when setting the provider:
``FIND_PACKAGE`` ``FIND_PACKAGE``
The provider command accepts :command:`find_package` requests. The provider command accepts :command:`find_package` requests.
``FETCHCONTENT_MAKEAVAILABLE_SERIAL`` ``FETCHCONTENT_MAKEAVAILABLE_SERIAL``
The provider command accepts :command:`FetchContent_MakeAvailable` The provider command accepts :command:`FetchContent_MakeAvailable`
requests. It expects each dependency to be fed to the provider command requests. It expects each dependency to be fed to the provider command
one at a time, not the whole list in one go. one at a time, not the whole list in one go.
Only one provider can be set at any point in time. If a provider is already Only one provider can be set at any point in time. If a provider is already
set when ``cmake_language(SET_DEPENDENCY_PROVIDER)`` is called, the new set when ``cmake_language(SET_DEPENDENCY_PROVIDER)`` is called, the new
provider replaces the previously set one. The specified ``<command>`` must provider replaces the previously set one. The specified ``<command>`` must
already exist when ``cmake_language(SET_DEPENDENCY_PROVIDER)`` is called. already exist when ``cmake_language(SET_DEPENDENCY_PROVIDER)`` is called.
As a special case, providing an empty string for the ``<command>`` and no As a special case, providing an empty string for the ``<command>`` and no
``<methods>`` will discard any previously set provider. ``<methods>`` will discard any previously set provider.
The dependency provider can only be set while processing one of the files The dependency provider can only be set while processing one of the files
specified by the :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` variable. specified by the :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` variable.
Thus, dependency providers can only be set as part of the first call to Thus, dependency providers can only be set as part of the first call to
:command:`project`. Calling ``cmake_language(SET_DEPENDENCY_PROVIDER)`` :command:`project`. Calling ``cmake_language(SET_DEPENDENCY_PROVIDER)``
outside of that context will result in an error. outside of that context will result in an error.
.. note:: .. note::
The choice of dependency provider should always be under the user's control. The choice of dependency provider should always be under the user's control.
As a convenience, a project may choose to provide a file that users can As a convenience, a project may choose to provide a file that users can
list in their :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` variable, but list in their :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` variable, but
@ -499,23 +488,21 @@ Getting current message log level
.. versionadded:: 3.25 .. versionadded:: 3.25
.. _GET_MESSAGE_LOG_LEVEL:
.. _query_message_log_level: .. _query_message_log_level:
.. code-block:: cmake .. signature::
cmake_language(GET_MESSAGE_LOG_LEVEL <output_variable>) cmake_language(GET_MESSAGE_LOG_LEVEL <output_variable>)
Writes the current :command:`message` logging level Writes the current :command:`message` logging level
into the given ``<output_variable>``. into the given ``<output_variable>``.
See :command:`message` for the possible logging levels. See :command:`message` for the possible logging levels.
The current message logging level can be set either using the The current message logging level can be set either using the
:option:`--log-level <cmake --log-level>` :option:`--log-level <cmake --log-level>`
command line option of the :manual:`cmake(1)` program or using command line option of the :manual:`cmake(1)` program or using
the :variable:`CMAKE_MESSAGE_LOG_LEVEL` variable. the :variable:`CMAKE_MESSAGE_LOG_LEVEL` variable.
If both the command line option and the variable are set, the command line If both the command line option and the variable are set, the command line
option takes precedence. If neither are set, the default logging level option takes precedence. If neither are set, the default logging level
is returned. is returned.

@ -12,10 +12,10 @@ Copy a file to another location and modify its contents.
[NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ]) [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
Copies an ``<input>`` file to an ``<output>`` file and substitutes Copies an ``<input>`` file to an ``<output>`` file and substitutes
variable values referenced as ``@VAR@`` or ``${VAR}`` in the input variable values referenced as ``@VAR@``, ``${VAR}``, ``$CACHE{VAR}`` or
file content. Each variable reference will be replaced with the ``$ENV{VAR}`` in the input file content. Each variable reference will be
current value of the variable, or the empty string if the variable replaced with the current value of the variable, or the empty string if
is not defined. Furthermore, input lines of the form the variable is not defined. Furthermore, input lines of the form
.. code-block:: c .. code-block:: c

@ -13,10 +13,6 @@ variables that are created by the project command.
.. include:: SUPPORTED_LANGUAGES.txt .. include:: SUPPORTED_LANGUAGES.txt
By default ``C`` and ``CXX`` are enabled if no language options are given.
Specify language ``NONE``, or use the ``LANGUAGES`` keyword and list no languages,
to skip enabling any languages.
This command must be called in file scope, not in a function call. This command must be called in file scope, not in a function call.
Furthermore, it must be called in the highest directory common to all Furthermore, it must be called in the highest directory common to all
targets using the named language directly for compiling sources or targets using the named language directly for compiling sources or

File diff suppressed because it is too large Load Diff

@ -19,6 +19,13 @@ find_file
.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_INCLUDE_PATH` .. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_INCLUDE_PATH`
.. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH` .. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH`
.. |ENV_CMAKE_PREFIX_PATH_XXX| replace::
``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set,
and |ENV_CMAKE_PREFIX_PATH_XXX_SUBDIR|
.. |ENV_CMAKE_XXX_PATH| replace:: :envvar:`CMAKE_INCLUDE_PATH`
.. |ENV_CMAKE_XXX_MAC_PATH| replace:: :envvar:`CMAKE_FRAMEWORK_PATH`
.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: The directories in ``INCLUDE`` .. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: The directories in ``INCLUDE``
and ``PATH``. and ``PATH``.
.. |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| replace:: On Windows hosts: .. |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| replace:: On Windows hosts:

@ -19,6 +19,12 @@ find_library
.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_LIBRARY_PATH` .. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_LIBRARY_PATH`
.. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH` .. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH`
.. |ENV_CMAKE_PREFIX_PATH_XXX| replace::
``<prefix>/lib/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set,
and |ENV_CMAKE_PREFIX_PATH_XXX_SUBDIR|
.. |ENV_CMAKE_XXX_PATH| replace:: :envvar:`CMAKE_LIBRARY_PATH`
.. |ENV_CMAKE_XXX_MAC_PATH| replace:: :envvar:`CMAKE_FRAMEWORK_PATH`
.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: The directories in ``LIB`` .. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: The directories in ``LIB``
and ``PATH``. and ``PATH``.
.. |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| replace:: On Windows hosts: .. |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| replace:: On Windows hosts:

@ -367,17 +367,37 @@ The set of installation prefixes is constructed using the following
steps. If ``NO_DEFAULT_PATH`` is specified all ``NO_*`` options are steps. If ``NO_DEFAULT_PATH`` is specified all ``NO_*`` options are
enabled. enabled.
1. .. versionadded:: 3.12 1. Search prefixes unique to the current ``<PackageName>`` being found.
Search paths specified in the :variable:`<PackageName>_ROOT` CMake See policy :policy:`CMP0074`.
variable and the :envvar:`<PackageName>_ROOT` environment variable,
where ``<PackageName>`` is the package to be found .. versionadded:: 3.12
(the case-preserved first argument to ``find_package``).
Specifically, search prefixes specified by the following variables,
in order:
a. :variable:`<PackageName>_ROOT` CMake variable,
where ``<PackageName>`` is the case-preserved package name.
b. :variable:`<PACKAGENAME>_ROOT` CMake variable,
where ``<PACKAGENAME>`` is the upper-cased package name.
See policy :policy:`CMP0144`.
.. versionadded:: 3.27
c. :envvar:`<PackageName>_ROOT` environment variable,
where ``<PackageName>`` is the case-preserved package name.
d. :envvar:`<PACKAGENAME>_ROOT` environment variable,
where ``<PACKAGENAME>`` is the upper-cased package name.
See policy :policy:`CMP0144`.
.. versionadded:: 3.27
The package root variables are maintained as a stack so if The package root variables are maintained as a stack so if
called from within a find module, root paths from the parent's find called from within a find module, root paths from the parent's find
module will also be searched after paths for the current package. module will also be searched after paths for the current package.
This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``. the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
See policy :policy:`CMP0074`.
2. Search paths specified in cmake-specific cache variables. These 2. Search paths specified in cmake-specific cache variables. These
are intended to be used on the command line with a :option:`-DVAR=VALUE <cmake -D>`. are intended to be used on the command line with a :option:`-DVAR=VALUE <cmake -D>`.
@ -398,8 +418,8 @@ enabled.
* ``<PackageName>_DIR`` * ``<PackageName>_DIR``
* :envvar:`CMAKE_PREFIX_PATH` * :envvar:`CMAKE_PREFIX_PATH`
* ``CMAKE_FRAMEWORK_PATH`` * :envvar:`CMAKE_FRAMEWORK_PATH`
* ``CMAKE_APPBUNDLE_PATH`` * :envvar:`CMAKE_APPBUNDLE_PATH`
4. Search paths specified by the ``HINTS`` option. These should be paths 4. Search paths specified by the ``HINTS`` option. These should be paths
computed by system introspection, such as a hint provided by the computed by system introspection, such as a hint provided by the

@ -19,6 +19,12 @@ find_path
.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_INCLUDE_PATH` .. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_INCLUDE_PATH`
.. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH` .. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH`
.. |ENV_CMAKE_PREFIX_PATH_XXX| replace::
``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set,
and |ENV_CMAKE_PREFIX_PATH_XXX_SUBDIR|
.. |ENV_CMAKE_XXX_PATH| replace:: :envvar:`CMAKE_INCLUDE_PATH`
.. |ENV_CMAKE_XXX_MAC_PATH| replace:: :envvar:`CMAKE_FRAMEWORK_PATH`
.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: The directories in ``INCLUDE`` .. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: The directories in ``INCLUDE``
and ``PATH``. and ``PATH``.
.. |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| replace:: On Windows hosts: .. |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| replace:: On Windows hosts:

@ -17,6 +17,11 @@ find_program
.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_PROGRAM_PATH` .. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_PROGRAM_PATH`
.. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_APPBUNDLE_PATH` .. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_APPBUNDLE_PATH`
.. |ENV_CMAKE_PREFIX_PATH_XXX| replace::
|ENV_CMAKE_PREFIX_PATH_XXX_SUBDIR|
.. |ENV_CMAKE_XXX_PATH| replace:: :envvar:`CMAKE_PROGRAM_PATH`
.. |ENV_CMAKE_XXX_MAC_PATH| replace:: :envvar:`CMAKE_APPBUNDLE_PATH`
.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: The directories in ``PATH`` itself. .. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: The directories in ``PATH`` itself.
.. |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| replace:: On Windows hosts no extra search paths are included .. |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| replace:: On Windows hosts no extra search paths are included

@ -4,9 +4,9 @@ get_filename_component
Get a specific component of a full filename. Get a specific component of a full filename.
.. versionchanged:: 3.20 .. versionchanged:: 3.20
This command has been superseded by :command:`cmake_path` command, except This command has been superseded by the :command:`cmake_path` command, except
``REALPATH`` now offered by :ref:`file(REAL_PATH)<REAL_PATH>` command and for ``REALPATH``, which is now offered by :command:`file(REAL_PATH)`, and
``PROGRAM`` now available in :command:`separate_arguments(PROGRAM)` command. ``PROGRAM``, now available in :command:`separate_arguments(PROGRAM)`.
.. versionchanged:: 3.24 .. versionchanged:: 3.24
The undocumented feature offering the capability to query the ``Windows`` The undocumented feature offering the capability to query the ``Windows``

@ -39,7 +39,7 @@ the ``if``, ``elseif`` and :command:`while` clauses.
Compound conditions are evaluated in the following order of precedence: Compound conditions are evaluated in the following order of precedence:
1. Parentheses. 1. `Parentheses`_.
2. Unary tests such as `EXISTS`_, `COMMAND`_, and `DEFINED`_. 2. Unary tests such as `EXISTS`_, `COMMAND`_, and `DEFINED`_.
@ -57,7 +57,9 @@ Compound conditions are evaluated in the following order of precedence:
Basic Expressions Basic Expressions
""""""""""""""""" """""""""""""""""
``if(<constant>)`` .. signature:: if(<constant>)
:target: constant
True if the constant is ``1``, ``ON``, ``YES``, ``TRUE``, ``Y``, True if the constant is ``1``, ``ON``, ``YES``, ``TRUE``, ``Y``,
or a non-zero number (including floating point numbers). or a non-zero number (including floating point numbers).
False if the constant is ``0``, ``OFF``, False if the constant is ``0``, ``OFF``,
@ -67,7 +69,9 @@ Basic Expressions
constants, it is treated as a variable or string (see `Variable Expansion`_ constants, it is treated as a variable or string (see `Variable Expansion`_
further below) and one of the following two forms applies. further below) and one of the following two forms applies.
``if(<variable>)`` .. signature:: if(<variable>)
:target: variable
True if given a variable that is defined to a value that is not a false True if given a variable that is defined to a value that is not a false
constant. False otherwise, including if the variable is undefined. constant. False otherwise, including if the variable is undefined.
Note that macro arguments are not variables. Note that macro arguments are not variables.
@ -75,7 +79,9 @@ Basic Expressions
cannot be tested this way, e.g. ``if(ENV{some_var})`` will always evaluate cannot be tested this way, e.g. ``if(ENV{some_var})`` will always evaluate
to false. to false.
``if(<string>)`` .. signature:: if(<string>)
:target: string
A quoted string always evaluates to false unless: A quoted string always evaluates to false unless:
* The string's value is one of the true constants, or * The string's value is one of the true constants, or
@ -86,22 +92,23 @@ Basic Expressions
Logic Operators Logic Operators
""""""""""""""" """""""""""""""
.. _NOT: .. signature:: if(NOT <condition>)
``if(NOT <condition>)``
True if the condition is not true. True if the condition is not true.
.. _AND: .. signature:: if(<cond1> AND <cond2>)
:target: AND
``if(<cond1> AND <cond2>)``
True if both conditions would be considered true individually. True if both conditions would be considered true individually.
.. _OR: .. signature:: if(<cond1> OR <cond2>)
:target: OR
``if(<cond1> OR <cond2>)``
True if either condition would be considered true individually. True if either condition would be considered true individually.
``if((condition) AND (condition OR (condition)))`` .. signature:: if((condition) AND (condition OR (condition)))
:target: parentheses
The conditions inside the parenthesis are evaluated first and then The conditions inside the parenthesis are evaluated first and then
the remaining condition is evaluated as in the other examples. the remaining condition is evaluated as in the other examples.
Where there are nested parenthesis the innermost are evaluated as part Where there are nested parenthesis the innermost are evaluated as part
@ -110,29 +117,31 @@ Logic Operators
Existence Checks Existence Checks
"""""""""""""""" """"""""""""""""
.. _COMMAND: .. signature:: if(COMMAND <command-name>)
``if(COMMAND command-name)``
True if the given name is a command, macro or function that can be True if the given name is a command, macro or function that can be
invoked. invoked.
``if(POLICY policy-id)`` .. signature:: if(POLICY <policy-id>)
True if the given name is an existing policy (of the form ``CMP<NNNN>``). True if the given name is an existing policy (of the form ``CMP<NNNN>``).
``if(TARGET target-name)`` .. signature:: if(TARGET <target-name>)
True if the given name is an existing logical target name created True if the given name is an existing logical target name created
by a call to the :command:`add_executable`, :command:`add_library`, by a call to the :command:`add_executable`, :command:`add_library`,
or :command:`add_custom_target` command that has already been invoked or :command:`add_custom_target` command that has already been invoked
(in any directory). (in any directory).
``if(TEST test-name)`` .. signature:: if(TEST <test-name>)
.. versionadded:: 3.3 .. versionadded:: 3.3
True if the given name is an existing test name created by the True if the given name is an existing test name created by the
:command:`add_test` command. :command:`add_test` command.
.. _DEFINED: .. signature:: if(DEFINED <name>|CACHE{<name>}|ENV{<name>})
``if(DEFINED <name>|CACHE{<name>}|ENV{<name>})``
True if a variable, cache variable or environment variable True if a variable, cache variable or environment variable
with given ``<name>`` is defined. The value of the variable with given ``<name>`` is defined. The value of the variable
does not matter. Note the following caveats: does not matter. Note the following caveats:
@ -149,16 +158,18 @@ Existence Checks
.. versionadded:: 3.14 .. versionadded:: 3.14
Added support for ``CACHE{<name>}`` variables. Added support for ``CACHE{<name>}`` variables.
``if(<variable|string> IN_LIST <variable>)`` .. signature:: if(<variable|string> IN_LIST <variable>)
:target: IN_LIST
.. versionadded:: 3.3 .. versionadded:: 3.3
True if the given element is contained in the named list variable. True if the given element is contained in the named list variable.
File Operations File Operations
""""""""""""""" """""""""""""""
.. _EXISTS: .. signature:: if(EXISTS <path-to-file-or-directory>)
``if(EXISTS path-to-file-or-directory)``
True if the named file or directory exists. Behavior is well-defined True if the named file or directory exists. Behavior is well-defined
only for explicit full paths (a leading ``~/`` is not expanded as only for explicit full paths (a leading ``~/`` is not expanded as
a home directory and is considered a relative path). a home directory and is considered a relative path).
@ -167,7 +178,9 @@ File Operations
False if the given path is an empty string. False if the given path is an empty string.
``if(file1 IS_NEWER_THAN file2)`` .. signature:: if(<file1> IS_NEWER_THAN <file2>)
:target: IS_NEWER_THAN
True if ``file1`` is newer than ``file2`` or if one of the two files doesn't True if ``file1`` is newer than ``file2`` or if one of the two files doesn't
exist. Behavior is well-defined only for full paths. If the file exist. Behavior is well-defined only for full paths. If the file
time stamps are exactly the same, an ``IS_NEWER_THAN`` comparison returns time stamps are exactly the same, an ``IS_NEWER_THAN`` comparison returns
@ -175,17 +188,20 @@ File Operations
of a tie. This includes the case of passing the same file name for of a tie. This includes the case of passing the same file name for
both file1 and file2. both file1 and file2.
``if(IS_DIRECTORY path)`` .. signature:: if(IS_DIRECTORY <path>)
True if ``path`` is a directory. Behavior is well-defined only True if ``path`` is a directory. Behavior is well-defined only
for full paths. for full paths.
False if the given path is an empty string. False if the given path is an empty string.
``if(IS_SYMLINK file-name)`` .. signature:: if(IS_SYMLINK <path>)
True if the given name is a symbolic link. Behavior is well-defined
True if the given path is a symbolic link. Behavior is well-defined
only for full paths. only for full paths.
``if(IS_ABSOLUTE path)`` .. signature:: if(IS_ABSOLUTE <path>)
True if the given path is an absolute path. Note the following special True if the given path is an absolute path. Note the following special
cases: cases:
@ -200,119 +216,125 @@ File Operations
Comparisons Comparisons
""""""""""" """""""""""
.. _MATCHES: .. signature:: if(<variable|string> MATCHES <regex>)
:target: MATCHES
``if(<variable|string> MATCHES regex)``
True if the given string or variable's value matches the given regular True if the given string or variable's value matches the given regular
expression. See :ref:`Regex Specification` for regex format. expression. See :ref:`Regex Specification` for regex format.
.. versionadded:: 3.9 .. versionadded:: 3.9
``()`` groups are captured in :variable:`CMAKE_MATCH_<n>` variables. ``()`` groups are captured in :variable:`CMAKE_MATCH_<n>` variables.
.. _LESS: .. signature:: if(<variable|string> LESS <variable|string>)
:target: LESS
``if(<variable|string> LESS <variable|string>)``
True if the given string or variable's value is a valid number and less True if the given string or variable's value is a valid number and less
than that on the right. than that on the right.
.. _GREATER: .. signature:: if(<variable|string> GREATER <variable|string>)
:target: GREATER
``if(<variable|string> GREATER <variable|string>)``
True if the given string or variable's value is a valid number and greater True if the given string or variable's value is a valid number and greater
than that on the right. than that on the right.
.. _EQUAL: .. signature:: if(<variable|string> EQUAL <variable|string>)
:target: EQUAL
``if(<variable|string> EQUAL <variable|string>)``
True if the given string or variable's value is a valid number and equal True if the given string or variable's value is a valid number and equal
to that on the right. to that on the right.
.. _LESS_EQUAL: .. signature:: if(<variable|string> LESS_EQUAL <variable|string>)
:target: LESS_EQUAL
``if(<variable|string> LESS_EQUAL <variable|string>)``
.. versionadded:: 3.7 .. versionadded:: 3.7
True if the given string or variable's value is a valid number and less True if the given string or variable's value is a valid number and less
than or equal to that on the right. than or equal to that on the right.
.. _GREATER_EQUAL: .. signature:: if(<variable|string> GREATER_EQUAL <variable|string>)
:target: GREATER_EQUAL
``if(<variable|string> GREATER_EQUAL <variable|string>)``
.. versionadded:: 3.7 .. versionadded:: 3.7
True if the given string or variable's value is a valid number and greater True if the given string or variable's value is a valid number and greater
than or equal to that on the right. than or equal to that on the right.
.. _STRLESS: .. signature:: if(<variable|string> STRLESS <variable|string>)
:target: STRLESS
``if(<variable|string> STRLESS <variable|string>)``
True if the given string or variable's value is lexicographically less True if the given string or variable's value is lexicographically less
than the string or variable on the right. than the string or variable on the right.
.. _STRGREATER: .. signature:: if(<variable|string> STRGREATER <variable|string>)
:target: STRGREATER
``if(<variable|string> STRGREATER <variable|string>)``
True if the given string or variable's value is lexicographically greater True if the given string or variable's value is lexicographically greater
than the string or variable on the right. than the string or variable on the right.
.. _STREQUAL: .. signature:: if(<variable|string> STREQUAL <variable|string>)
:target: STREQUAL
``if(<variable|string> STREQUAL <variable|string>)``
True if the given string or variable's value is lexicographically equal True if the given string or variable's value is lexicographically equal
to the string or variable on the right. to the string or variable on the right.
.. _STRLESS_EQUAL: .. signature:: if(<variable|string> STRLESS_EQUAL <variable|string>)
:target: STRLESS_EQUAL
``if(<variable|string> STRLESS_EQUAL <variable|string>)``
.. versionadded:: 3.7 .. versionadded:: 3.7
True if the given string or variable's value is lexicographically less True if the given string or variable's value is lexicographically less
than or equal to the string or variable on the right. than or equal to the string or variable on the right.
.. _STRGREATER_EQUAL: .. signature:: if(<variable|string> STRGREATER_EQUAL <variable|string>)
:target: STRGREATER_EQUAL
``if(<variable|string> STRGREATER_EQUAL <variable|string>)``
.. versionadded:: 3.7 .. versionadded:: 3.7
True if the given string or variable's value is lexicographically greater True if the given string or variable's value is lexicographically greater
than or equal to the string or variable on the right. than or equal to the string or variable on the right.
Version Comparisons Version Comparisons
""""""""""""""""""" """""""""""""""""""
.. _VERSION_LESS: .. signature:: if(<variable|string> VERSION_LESS <variable|string>)
:target: VERSION_LESS
``if(<variable|string> VERSION_LESS <variable|string>)``
Component-wise integer version number comparison (version format is Component-wise integer version number comparison (version format is
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero). ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
Any non-integer version component or non-integer trailing part of a version Any non-integer version component or non-integer trailing part of a version
component effectively truncates the string at that point. component effectively truncates the string at that point.
.. _VERSION_GREATER: .. signature:: if(<variable|string> VERSION_GREATER <variable|string>)
:target: VERSION_GREATER
``if(<variable|string> VERSION_GREATER <variable|string>)``
Component-wise integer version number comparison (version format is Component-wise integer version number comparison (version format is
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero). ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
Any non-integer version component or non-integer trailing part of a version Any non-integer version component or non-integer trailing part of a version
component effectively truncates the string at that point. component effectively truncates the string at that point.
.. _VERSION_EQUAL: .. signature:: if(<variable|string> VERSION_EQUAL <variable|string>)
:target: VERSION_EQUAL
``if(<variable|string> VERSION_EQUAL <variable|string>)``
Component-wise integer version number comparison (version format is Component-wise integer version number comparison (version format is
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero). ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
Any non-integer version component or non-integer trailing part of a version Any non-integer version component or non-integer trailing part of a version
component effectively truncates the string at that point. component effectively truncates the string at that point.
.. _VERSION_LESS_EQUAL: .. signature:: if(<variable|string> VERSION_LESS_EQUAL <variable|string>)
:target: VERSION_LESS_EQUAL
``if(<variable|string> VERSION_LESS_EQUAL <variable|string>)``
.. versionadded:: 3.7 .. versionadded:: 3.7
Component-wise integer version number comparison (version format is Component-wise integer version number comparison (version format is
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero). ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
Any non-integer version component or non-integer trailing part of a version Any non-integer version component or non-integer trailing part of a version
component effectively truncates the string at that point. component effectively truncates the string at that point.
.. _VERSION_GREATER_EQUAL: .. signature:: if(<variable|string> VERSION_GREATER_EQUAL <variable|string>)
:target: VERSION_GREATER_EQUAL
``if(<variable|string> VERSION_GREATER_EQUAL <variable|string>)``
.. versionadded:: 3.7 .. versionadded:: 3.7
Component-wise integer version number comparison (version format is Component-wise integer version number comparison (version format is
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero). ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
Any non-integer version component or non-integer trailing part of a version Any non-integer version component or non-integer trailing part of a version
@ -321,9 +343,9 @@ Version Comparisons
Path Comparisons Path Comparisons
"""""""""""""""" """"""""""""""""
.. _PATH_EQUAL: .. signature:: if(<variable|string> PATH_EQUAL <variable|string>)
:target: PATH_EQUAL
``if(<variable|string> PATH_EQUAL <variable|string>)``
.. versionadded:: 3.24 .. versionadded:: 3.24
Compares the two paths component-by-component. Only if every component of Compares the two paths component-by-component. Only if every component of
@ -386,35 +408,35 @@ constant.
Automatic evaluation applies in the other cases whenever the Automatic evaluation applies in the other cases whenever the
above-documented condition syntax accepts ``<variable|string>``: above-documented condition syntax accepts ``<variable|string>``:
* The left hand argument to ``MATCHES`` is first checked to see if it is * The left hand argument to `MATCHES`_ is first checked to see if it is
a defined variable, if so the variable's value is used, otherwise the a defined variable. If so, the variable's value is used, otherwise the
original value is used. original value is used.
* If the left hand argument to ``MATCHES`` is missing it returns false * If the left hand argument to `MATCHES`_ is missing it returns false
without error without error
* Both left and right hand arguments to ``LESS``, ``GREATER``, ``EQUAL``, * Both left and right hand arguments to `LESS`_, `GREATER`_, `EQUAL`_,
``LESS_EQUAL``, and ``GREATER_EQUAL``, are independently tested to see if `LESS_EQUAL`_, and `GREATER_EQUAL`_, are independently tested to see if
they are defined variables, if so their defined values are used otherwise they are defined variables. If so, their defined values are used otherwise
the original value is used. the original value is used.
* Both left and right hand arguments to ``STRLESS``, ``STRGREATER``, * Both left and right hand arguments to `STRLESS`_, `STRGREATER`_,
``STREQUAL``, ``STRLESS_EQUAL``, and ``STRGREATER_EQUAL`` are independently `STREQUAL`_, `STRLESS_EQUAL`_, and `STRGREATER_EQUAL`_ are independently
tested to see if they are defined variables, if so their defined values are tested to see if they are defined variables. If so, their defined values are
used otherwise the original value is used. used otherwise the original value is used.
* Both left and right hand arguments to ``VERSION_LESS``, * Both left and right hand arguments to `VERSION_LESS`_,
``VERSION_GREATER``, ``VERSION_EQUAL``, ``VERSION_LESS_EQUAL``, and `VERSION_GREATER`_, `VERSION_EQUAL`_, `VERSION_LESS_EQUAL`_, and
``VERSION_GREATER_EQUAL`` are independently tested to see if they are defined `VERSION_GREATER_EQUAL`_ are independently tested to see if they are defined
variables, if so their defined values are used otherwise the original value variables. If so, their defined values are used otherwise the original value
is used. is used.
* The right hand argument to ``NOT`` is tested to see if it is a boolean * The right hand argument to `NOT`_ is tested to see if it is a boolean
constant, if so the value is used, otherwise it is assumed to be a constant. If so, the value is used, otherwise it is assumed to be a
variable and it is dereferenced. variable and it is dereferenced.
* The left and right hand arguments to ``AND`` and ``OR`` are independently * The left and right hand arguments to `AND`_ and `OR`_ are independently
tested to see if they are boolean constants, if so they are used as tested to see if they are boolean constants. If so, they are used as
such, otherwise they are assumed to be variables and are dereferenced. such, otherwise they are assumed to be variables and are dereferenced.
.. versionchanged:: 3.1 .. versionchanged:: 3.1

@ -25,7 +25,7 @@ prepending, independent of the default.
If the ``SYSTEM`` option is given, the compiler will be told the If the ``SYSTEM`` option is given, the compiler will be told the
directories are meant as system include directories on some platforms. directories are meant as system include directories on some platforms.
Signalling this setting might achieve effects such as the compiler Signaling this setting might achieve effects such as the compiler
skipping warnings, or these fixed-install system files not being skipping warnings, or these fixed-install system files not being
considered in dependency calculations - see compiler docs. considered in dependency calculations - see compiler docs.

@ -158,6 +158,9 @@ that may be installed:
``.lib``, in contrast to the ``.dll`` libraries that go to ``RUNTIME``); ``.lib``, in contrast to the ``.dll`` libraries that go to ``RUNTIME``);
* On AIX, the *linker import file* created for executables with * On AIX, the *linker import file* created for executables with
:prop_tgt:`ENABLE_EXPORTS` enabled. :prop_tgt:`ENABLE_EXPORTS` enabled.
* On macOS, the *linker import file* created for shared libraries with
:prop_tgt:`ENABLE_EXPORTS` enabled (except when marked as ``FRAMEWORK``,
see below).
``LIBRARY`` ``LIBRARY``
Target artifacts of this kind include: Target artifacts of this kind include:
@ -308,6 +311,11 @@ the following additional arguments:
value of ``COMPONENT``. It is an error to use this parameter outside of a value of ``COMPONENT``. It is an error to use this parameter outside of a
``LIBRARY`` block. ``LIBRARY`` block.
.. versionchanged:: 3.27
This parameter is also usable for an ``ARCHIVE`` block to manage
the linker import file created, on macOS, for shared libraries with
:prop_tgt:`ENABLE_EXPORTS` enabled.
Consider the following example: Consider the following example:
.. code-block:: cmake .. code-block:: cmake
@ -342,6 +350,11 @@ the following additional arguments:
option installs nothing. It is an error to use this parameter outside of a option installs nothing. It is an error to use this parameter outside of a
``LIBRARY`` block. ``LIBRARY`` block.
.. versionchanged:: 3.27
This parameter is also usable for an ``ARCHIVE`` block to manage
the linker import file created, on macOS, for shared libraries with
:prop_tgt:`ENABLE_EXPORTS` enabled.
When ``NAMELINK_ONLY`` is given, either ``NAMELINK_COMPONENT`` or When ``NAMELINK_ONLY`` is given, either ``NAMELINK_COMPONENT`` or
``COMPONENT`` may be used to specify the installation component of the ``COMPONENT`` may be used to specify the installation component of the
namelink, but ``COMPONENT`` should generally be preferred. namelink, but ``COMPONENT`` should generally be preferred.
@ -355,6 +368,11 @@ the following additional arguments:
installs the library. It is an error to use this parameter outside of a installs the library. It is an error to use this parameter outside of a
``LIBRARY`` block. ``LIBRARY`` block.
.. versionchanged:: 3.27
This parameter is also usable for an ``ARCHIVE`` block to manage
the linker import file created, on macOS, for shared libraries with
:prop_tgt:`ENABLE_EXPORTS` enabled.
If ``NAMELINK_SKIP`` is specified, ``NAMELINK_COMPONENT`` has no effect. It If ``NAMELINK_SKIP`` is specified, ``NAMELINK_COMPONENT`` has no effect. It
is not recommended to use ``NAMELINK_SKIP`` in conjunction with is not recommended to use ``NAMELINK_SKIP`` in conjunction with
``NAMELINK_COMPONENT``. ``NAMELINK_COMPONENT``.

@ -1,7 +1,7 @@
list list
---- ----
List operations. Operations on :ref:`semicolon-separated lists <CMake Language Lists>`.
Synopsis Synopsis
^^^^^^^^ ^^^^^^^^
@ -36,23 +36,29 @@ Synopsis
Introduction Introduction
^^^^^^^^^^^^ ^^^^^^^^^^^^
The list subcommands ``APPEND``, ``INSERT``, ``FILTER``, ``PREPEND``, The list subcommands :cref:`APPEND`, :cref:`INSERT`, :cref:`FILTER`,
``POP_BACK``, ``POP_FRONT``, ``REMOVE_AT``, ``REMOVE_ITEM``, :cref:`PREPEND`, :cref:`POP_BACK`, :cref:`POP_FRONT`, :cref:`REMOVE_AT`,
``REMOVE_DUPLICATES``, ``REVERSE`` and ``SORT`` may create :cref:`REMOVE_ITEM`, :cref:`REMOVE_DUPLICATES`, :cref:`REVERSE` and
new values for the list within the current CMake variable scope. Similar to :cref:`SORT` may create new values for the list within the current CMake
the :command:`set` command, the LIST command creates new variable values in variable scope. Similar to the :command:`set` command, the ``list`` command
the current scope, even if the list itself is actually defined in a parent creates new variable values in the current scope, even if the list itself is
scope. To propagate the results of these operations upwards, use actually defined in a parent scope. To propagate the results of these
:command:`set` with ``PARENT_SCOPE``, :command:`set` with operations upwards, use :command:`set` with ``PARENT_SCOPE``,
``CACHE INTERNAL``, or some other means of value propagation. :command:`set` with ``CACHE INTERNAL``, or some other means of value
propagation.
.. note:: .. note::
A list in cmake is a ``;`` separated group of strings. To create a A list in cmake is a ``;`` separated group of strings. To create a
list the set command can be used. For example, ``set(var a b c d e)`` list, the :command:`set` command can be used. For example,
creates a list with ``a;b;c;d;e``, and ``set(var "a b c d e")`` creates a ``set(var a b c d e)`` creates a list with ``a;b;c;d;e``, and
string or a list with one item in it. (Note macro arguments are not ``set(var "a b c d e")`` creates a string or a list with one item in it.
variables, and therefore cannot be used in LIST commands.) (Note that macro arguments are not variables, and therefore cannot be used
in ``LIST`` commands.)
Individual elements may not contain an unequal number of ``[`` and ``]``
characters, and may not end in a backslash (``\``).
See :ref:`semicolon-separated lists <CMake Language Lists>` for details.
.. note:: .. note::
@ -66,76 +72,54 @@ scope. To propagate the results of these operations upwards, use
Reading Reading
^^^^^^^ ^^^^^^^
.. _LENGTH: .. signature::
.. code-block:: cmake
list(LENGTH <list> <output variable>) list(LENGTH <list> <output variable>)
Returns the list's length. Returns the list's length.
.. _GET:
.. code-block:: cmake
.. signature::
list(GET <list> <element index> [<element index> ...] <output variable>) list(GET <list> <element index> [<element index> ...] <output variable>)
Returns the list of elements specified by indices from the list. Returns the list of elements specified by indices from the list.
.. _JOIN:
.. code-block:: cmake
list(JOIN <list> <glue> <output variable>) .. signature:: list(JOIN <list> <glue> <output variable>)
.. versionadded:: 3.12 .. versionadded:: 3.12
Returns a string joining all list's elements using the glue string. Returns a string joining all list's elements using the glue string.
To join multiple strings, which are not part of a list, use ``JOIN`` operator To join multiple strings, which are not part of a list,
from :command:`string` command. use :command:`string(JOIN)`.
.. _SUBLIST:
.. code-block:: cmake
.. signature::
list(SUBLIST <list> <begin> <length> <output variable>) list(SUBLIST <list> <begin> <length> <output variable>)
.. versionadded:: 3.12 .. versionadded:: 3.12
Returns a sublist of the given list. Returns a sublist of the given list.
If ``<length>`` is 0, an empty list will be returned. If ``<length>`` is 0, an empty list will be returned.
If ``<length>`` is -1 or the list is smaller than ``<begin>+<length>`` then If ``<length>`` is -1 or the list is smaller than ``<begin>+<length>`` then
the remaining elements of the list starting at ``<begin>`` will be returned. the remaining elements of the list starting at ``<begin>`` will be returned.
Search Search
^^^^^^ ^^^^^^
.. _FIND: .. signature::
.. code-block:: cmake
list(FIND <list> <value> <output variable>) list(FIND <list> <value> <output variable>)
Returns the index of the element specified in the list or -1 Returns the index of the element specified in the list
if it wasn't found. or ``-1`` if it wasn't found.
Modification Modification
^^^^^^^^^^^^ ^^^^^^^^^^^^
.. _APPEND: .. signature::
.. code-block:: cmake
list(APPEND <list> [<element> ...]) list(APPEND <list> [<element> ...])
Appends elements to the list. If no variable named ``<list>`` exists in the Appends elements to the list. If no variable named ``<list>`` exists in the
current scope its value is treated as empty and the elements are appended to current scope its value is treated as empty and the elements are appended to
that empty list. that empty list.
.. _FILTER:
.. code-block:: cmake
.. signature::
list(FILTER <list> <INCLUDE|EXCLUDE> REGEX <regular_expression>) list(FILTER <list> <INCLUDE|EXCLUDE> REGEX <regular_expression>)
.. versionadded:: 3.6 .. versionadded:: 3.6
@ -146,163 +130,144 @@ In ``REGEX`` mode, items will be matched against the given regular expression.
For more information on regular expressions look under For more information on regular expressions look under
:ref:`string(REGEX) <Regex Specification>`. :ref:`string(REGEX) <Regex Specification>`.
.. _INSERT: .. signature::
.. code-block:: cmake
list(INSERT <list> <element_index> <element> [<element> ...]) list(INSERT <list> <element_index> <element> [<element> ...])
Inserts elements to the list to the specified index. It is an Inserts elements to the list to the specified index. It is an
error to specify an out-of-range index. Valid indexes are 0 to `N` error to specify an out-of-range index. Valid indexes are 0 to `N`
where `N` is the length of the list, inclusive. An empty list where `N` is the length of the list, inclusive. An empty list
has length 0. If no variable named ``<list>`` exists in the has length 0. If no variable named ``<list>`` exists in the
current scope its value is treated as empty and the elements are current scope its value is treated as empty and the elements are
inserted in that empty list. inserted in that empty list.
.. _POP_BACK:
.. code-block:: cmake
.. signature::
list(POP_BACK <list> [<out-var>...]) list(POP_BACK <list> [<out-var>...])
.. versionadded:: 3.15 .. versionadded:: 3.15
If no variable name is given, removes exactly one element. Otherwise, If no variable name is given, removes exactly one element. Otherwise,
with `N` variable names provided, assign the last `N` elements' values with `N` variable names provided, assign the last `N` elements' values
to the given variables and then remove the last `N` values from to the given variables and then remove the last `N` values from
``<list>``. ``<list>``.
.. _POP_FRONT:
.. code-block:: cmake
.. signature::
list(POP_FRONT <list> [<out-var>...]) list(POP_FRONT <list> [<out-var>...])
.. versionadded:: 3.15 .. versionadded:: 3.15
If no variable name is given, removes exactly one element. Otherwise,
with `N` variable names provided, assign the first `N` elements' values
to the given variables and then remove the first `N` values from
``<list>``.
.. _PREPEND: If no variable name is given, removes exactly one element. Otherwise,
with `N` variable names provided, assign the first `N` elements' values
.. code-block:: cmake to the given variables and then remove the first `N` values from
``<list>``.
.. signature::
list(PREPEND <list> [<element> ...]) list(PREPEND <list> [<element> ...])
.. versionadded:: 3.15 .. versionadded:: 3.15
Insert elements to the 0th position in the list. If no variable named
``<list>`` exists in the current scope its value is treated as empty and
the elements are prepended to that empty list.
.. _REMOVE_ITEM:
.. code-block:: cmake Insert elements to the 0th position in the list. If no variable named
``<list>`` exists in the current scope its value is treated as empty and
the elements are prepended to that empty list.
.. signature::
list(REMOVE_ITEM <list> <value> [<value> ...]) list(REMOVE_ITEM <list> <value> [<value> ...])
Removes all instances of the given items from the list. Removes all instances of the given items from the list.
.. _REMOVE_AT:
.. code-block:: cmake
.. signature::
list(REMOVE_AT <list> <index> [<index> ...]) list(REMOVE_AT <list> <index> [<index> ...])
Removes items at given indices from the list. Removes items at given indices from the list.
.. _REMOVE_DUPLICATES:
.. code-block:: cmake
.. signature::
list(REMOVE_DUPLICATES <list>) list(REMOVE_DUPLICATES <list>)
Removes duplicated items in the list. The relative order of items is preserved, Removes duplicated items in the list. The relative order of items
but if duplicates are encountered, only the first instance is preserved. is preserved, but if duplicates are encountered,
only the first instance is preserved.
.. _TRANSFORM:
.. code-block:: cmake
.. signature::
list(TRANSFORM <list> <ACTION> [<SELECTOR>] list(TRANSFORM <list> <ACTION> [<SELECTOR>]
[OUTPUT_VARIABLE <output variable>]) [OUTPUT_VARIABLE <output variable>])
.. versionadded:: 3.12 .. versionadded:: 3.12
Transforms the list by applying an action to all or, by specifying a Transforms the list by applying an ``<ACTION>`` to all or, by specifying a
``<SELECTOR>``, to the selected elements of the list, storing the result ``<SELECTOR>``, to the selected elements of the list, storing the result
in-place or in the specified output variable. in-place or in the specified output variable.
.. note:: .. note::
The ``TRANSFORM`` sub-command does not change the number of elements in the The ``TRANSFORM`` sub-command does not change the number of elements in the
list. If a ``<SELECTOR>`` is specified, only some elements will be changed, list. If a ``<SELECTOR>`` is specified, only some elements will be changed,
the other ones will remain the same as before the transformation. the other ones will remain the same as before the transformation.
``<ACTION>`` specifies the action to apply to the elements of the list. ``<ACTION>`` specifies the action to apply to the elements of the list.
The actions have exactly the same semantics as sub-commands of the The actions have exactly the same semantics as sub-commands of the
:command:`string` command. ``<ACTION>`` must be one of the following: :command:`string` command. ``<ACTION>`` must be one of the following:
``APPEND``, ``PREPEND``: Append, prepend specified value to each element of :command:`APPEND <string(APPEND)>`, :command:`PREPEND <string(PREPEND)>`
the list. Append, prepend specified value to each element of the list.
.. code-block:: cmake .. signature::
list(TRANSFORM <list> (APPEND|PREPEND) <value> ...)
list(TRANSFORM <list> <APPEND|PREPEND> <value> ...) :target: TRANSFORM_APPEND
``TOUPPER``, ``TOLOWER``: Convert each element of the list to upper, lower
characters.
.. code-block:: cmake :command:`TOLOWER <string(TOLOWER)>`, :command:`TOUPPER <string(TOUPPER)>`
Convert each element of the list to lower, upper characters.
list(TRANSFORM <list> <TOLOWER|TOUPPER> ...)
``STRIP``: Remove leading and trailing spaces from each element of the .. signature::
list. list(TRANSFORM <list> (TOLOWER|TOUPPER) ...)
:target: TRANSFORM_TOLOWER
.. code-block:: cmake :command:`STRIP <string(STRIP)>`
Remove leading and trailing spaces from each element of the list.
.. signature::
list(TRANSFORM <list> STRIP ...) list(TRANSFORM <list> STRIP ...)
:target: TRANSFORM_STRIP
``GENEX_STRIP``: Strip any :command:`GENEX_STRIP <string(GENEX_STRIP)>`
:manual:`generator expressions <cmake-generator-expressions(7)>` from each Strip any
element of the list. :manual:`generator expressions <cmake-generator-expressions(7)>`
from each element of the list.
.. code-block:: cmake
.. signature::
list(TRANSFORM <list> GENEX_STRIP ...) list(TRANSFORM <list> GENEX_STRIP ...)
:target: TRANSFORM_GENEX_STRIP
``REPLACE``: Match the regular expression as many times as possible and :command:`REPLACE <string(REGEX REPLACE)>`:
substitute the replacement expression for the match for each element Match the regular expression as many times as possible and substitute
of the list the replacement expression for the match for each element of the list
(Same semantic as ``REGEX REPLACE`` from :command:`string` command). (same semantic as :command:`string(REGEX REPLACE)`).
.. code-block:: cmake
.. signature::
list(TRANSFORM <list> REPLACE <regular_expression> list(TRANSFORM <list> REPLACE <regular_expression>
<replace_expression> ...) <replace_expression> ...)
:target: TRANSFORM_REPLACE
``<SELECTOR>`` determines which elements of the list will be transformed. ``<SELECTOR>`` determines which elements of the list will be transformed.
Only one type of selector can be specified at a time. When given, Only one type of selector can be specified at a time.
``<SELECTOR>`` must be one of the following: When given, ``<SELECTOR>`` must be one of the following:
``AT``: Specify a list of indexes. ``AT``
Specify a list of indexes.
.. code-block:: cmake .. code-block:: cmake
list(TRANSFORM <list> <ACTION> AT <index> [<index> ...] ...) list(TRANSFORM <list> <ACTION> AT <index> [<index> ...] ...)
``FOR``: Specify a range with, optionally, an increment used to iterate over ``FOR``
the range. Specify a range with, optionally,
an increment used to iterate over the range.
.. code-block:: cmake .. code-block:: cmake
list(TRANSFORM <list> <ACTION> FOR <start> <stop> [<step>] ...) list(TRANSFORM <list> <ACTION> FOR <start> <stop> [<step>] ...)
``REGEX``: Specify a regular expression. Only elements matching the regular ``REGEX``
expression will be transformed. Specify a regular expression.
Only elements matching the regular expression will be transformed.
.. code-block:: cmake .. code-block:: cmake
@ -312,35 +277,34 @@ expression will be transformed.
Ordering Ordering
^^^^^^^^ ^^^^^^^^
.. _REVERSE: .. signature::
.. code-block:: cmake
list(REVERSE <list>) list(REVERSE <list>)
Reverses the contents of the list in-place. Reverses the contents of the list in-place.
.. _SORT:
.. code-block:: cmake
.. signature::
list(SORT <list> [COMPARE <compare>] [CASE <case>] [ORDER <order>]) list(SORT <list> [COMPARE <compare>] [CASE <case>] [ORDER <order>])
Sorts the list in-place alphabetically. Sorts the list in-place alphabetically.
.. versionadded:: 3.13 .. versionadded:: 3.13
Added the ``COMPARE``, ``CASE``, and ``ORDER`` options. Added the ``COMPARE``, ``CASE``, and ``ORDER`` options.
.. versionadded:: 3.18 .. versionadded:: 3.18
Added the ``COMPARE NATURAL`` option. Added the ``COMPARE NATURAL`` option.
Use the ``COMPARE`` keyword to select the comparison method for sorting. Use the ``COMPARE`` keyword to select the comparison method for sorting.
The ``<compare>`` option should be one of: The ``<compare>`` option should be one of:
``STRING``
Sorts a list of strings alphabetically.
This is the default behavior if the ``COMPARE`` option is not given.
* ``STRING``: Sorts a list of strings alphabetically. This is the ``FILE_BASENAME``
default behavior if the ``COMPARE`` option is not given. Sorts a list of pathnames of files by their basenames.
* ``FILE_BASENAME``: Sorts a list of pathnames of files by their basenames.
* ``NATURAL``: Sorts a list of strings using natural order ``NATURAL``
Sorts a list of strings using natural order
(see ``strverscmp(3)`` manual), i.e. such that contiguous digits (see ``strverscmp(3)`` manual), i.e. such that contiguous digits
are compared as whole numbers. are compared as whole numbers.
For example: the following list `10.0 1.1 2.1 8.0 2.0 3.1` For example: the following list `10.0 1.1 2.1 8.0 2.0 3.1`
@ -348,17 +312,23 @@ The ``<compare>`` option should be one of:
comparison is selected where it will be sorted as comparison is selected where it will be sorted as
`1.1 10.0 2.0 2.1 3.1 8.0` with the ``STRING`` comparison. `1.1 10.0 2.0 2.1 3.1 8.0` with the ``STRING`` comparison.
Use the ``CASE`` keyword to select a case sensitive or case insensitive Use the ``CASE`` keyword to select a case sensitive or case insensitive
sort mode. The ``<case>`` option should be one of: sort mode. The ``<case>`` option should be one of:
``SENSITIVE``
List items are sorted in a case-sensitive manner.
This is the default behavior if the ``CASE`` option is not given.
* ``SENSITIVE``: List items are sorted in a case-sensitive manner. This is ``INSENSITIVE``
the default behavior if the ``CASE`` option is not given. List items are sorted case insensitively. The order of
* ``INSENSITIVE``: List items are sorted case insensitively. The order of
items which differ only by upper/lowercase is not specified. items which differ only by upper/lowercase is not specified.
To control the sort order, the ``ORDER`` keyword can be given. To control the sort order, the ``ORDER`` keyword can be given.
The ``<order>`` option should be one of: The ``<order>`` option should be one of:
``ASCENDING``
Sorts the list in ascending order.
This is the default behavior when the ``ORDER`` option is not given.
* ``ASCENDING``: Sorts the list in ascending order. This is the default ``DESCENDING``
behavior when the ``ORDER`` option is not given. Sorts the list in descending order.
* ``DESCENDING``: Sorts the list in descending order.

@ -9,7 +9,8 @@ Evaluate a mathematical expression.
Evaluates a mathematical ``<expression>`` and sets ``<variable>`` to the Evaluates a mathematical ``<expression>`` and sets ``<variable>`` to the
resulting value. The result of the expression must be representable as a resulting value. The result of the expression must be representable as a
64-bit signed integer. 64-bit signed integer. Floating point inputs are invalid e.g. ``1.1 * 10``.
Non-integer results e.g. ``3 / 2`` are truncated.
The mathematical expression must be given as a string (i.e. enclosed in The mathematical expression must be given as a string (i.e. enclosed in
double quotation marks). An example is ``"5 * (10 + 13)"``. double quotation marks). An example is ``"5 * (10 + 13)"``.

@ -105,6 +105,9 @@ The options are:
.. include:: SUPPORTED_LANGUAGES.txt .. include:: SUPPORTED_LANGUAGES.txt
By default ``C`` and ``CXX`` are enabled if no language options are given.
Specify language ``NONE``, or use the ``LANGUAGES`` keyword and list no languages,
to skip enabling any languages.
The variables set through the ``VERSION``, ``DESCRIPTION`` and ``HOMEPAGE_URL`` The variables set through the ``VERSION``, ``DESCRIPTION`` and ``HOMEPAGE_URL``
options are intended for use as default values in package metadata and documentation. options are intended for use as default values in package metadata and documentation.

@ -69,7 +69,7 @@ be one of the following keywords:
The contents of ``out`` will be: ``/path/to/cc;-c;main.c`` The contents of ``out`` will be: ``/path/to/cc;-c;main.c``
.. _`Parsing C Command-Line Arguments`: https://msdn.microsoft.com/library/a1y7w461.aspx .. _`Parsing C Command-Line Arguments`: https://learn.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments
.. code-block:: cmake .. code-block:: cmake

@ -8,109 +8,119 @@ and cache entries.
Signatures of this command that specify a ``<value>...`` placeholder Signatures of this command that specify a ``<value>...`` placeholder
expect zero or more arguments. Multiple arguments will be joined as expect zero or more arguments. Multiple arguments will be joined as
a :ref:`semicolon-separated list <CMake Language Lists>` to form the actual variable a :ref:`semicolon-separated list <CMake Language Lists>` to form the
value to be set. Zero arguments will cause normal variables to be actual variable value to be set.
unset. See the :command:`unset` command to unset variables explicitly.
Set Normal Variable Set Normal Variable
^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
.. code-block:: cmake .. signature::
set(<variable> <value>... [PARENT_SCOPE]) set(<variable> <value>... [PARENT_SCOPE])
:target: normal
Set or unset ``<variable>`` in the current function or directory scope:
* If at least one ``<value>...`` is given, set the variable to that value.
* If no value is given, unset the variable. This is equivalent to
:command:`unset(<variable>) <unset>`.
Sets the given ``<variable>`` in the current function or directory scope. If the ``PARENT_SCOPE`` option is given the variable will be set in
the scope above the current scope. Each new directory or :command:`function`
command creates a new scope. A scope can also be created with the
:command:`block` command. This command will set the value of a variable into
the parent directory, calling function or encompassing scope (whichever is
applicable to the case at hand). The previous state of the variable's value
stays the same in the current scope (e.g., if it was undefined before, it is
still undefined and if it had a value, it is still that value).
If the ``PARENT_SCOPE`` option is given the variable will be set in The :command:`block(PROPAGATE)` and :command:`return(PROPAGATE)` commands
the scope above the current scope. Each new directory or :command:`function` can be used as an alternate method to the :command:`set(PARENT_SCOPE)`
command creates a new scope. A scope can also be created with the and :command:`unset(PARENT_SCOPE)` commands to update the parent scope.
:command:`block` command. This command will set the value of a variable into
the parent directory, calling function or encompassing scope (whichever is
applicable to the case at hand). The previous state of the variable's value
stays the same in the current scope (e.g., if it was undefined before, it is
still undefined and if it had a value, it is still that value).
The :command:`block(PROPAGATE)` and :command:`return(PROPAGATE)` commands can .. include:: UNSET_NOTE.txt
be used as an alternate method to the :command:`set(PARENT_SCOPE)` and
:command:`unset(PARENT_SCOPE)` commands to update the parent scope.
Set Cache Entry Set Cache Entry
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
.. code-block:: cmake .. signature::
set(<variable> <value>... CACHE <type> <docstring> [FORCE]) set(<variable> <value>... CACHE <type> <docstring> [FORCE])
:target: CACHE
Sets the given cache ``<variable>`` (cache entry). Since cache entries Sets the given cache ``<variable>`` (cache entry). Since cache entries
are meant to provide user-settable values this does not overwrite are meant to provide user-settable values this does not overwrite
existing cache entries by default. Use the ``FORCE`` option to existing cache entries by default. Use the ``FORCE`` option to
overwrite existing entries. overwrite existing entries.
The ``<type>`` must be specified as one of: The ``<type>`` must be specified as one of:
``BOOL`` ``BOOL``
Boolean ``ON/OFF`` value. :manual:`cmake-gui(1)` offers a checkbox. Boolean ``ON/OFF`` value.
:manual:`cmake-gui(1)` offers a checkbox.
``FILEPATH`` ``FILEPATH``
Path to a file on disk. :manual:`cmake-gui(1)` offers a file dialog. Path to a file on disk.
:manual:`cmake-gui(1)` offers a file dialog.
``PATH`` ``PATH``
Path to a directory on disk. :manual:`cmake-gui(1)` offers a file dialog. Path to a directory on disk.
:manual:`cmake-gui(1)` offers a file dialog.
``STRING`` ``STRING``
A line of text. :manual:`cmake-gui(1)` offers a text field or a A line of text.
drop-down selection if the :prop_cache:`STRINGS` cache entry :manual:`cmake-gui(1)` offers a text field or a drop-down selection
property is set. if the :prop_cache:`STRINGS` cache entry property is set.
``INTERNAL`` ``INTERNAL``
A line of text. :manual:`cmake-gui(1)` does not show internal entries. A line of text.
:manual:`cmake-gui(1)` does not show internal entries.
They may be used to store variables persistently across runs. They may be used to store variables persistently across runs.
Use of this type implies ``FORCE``. Use of this type implies ``FORCE``.
The ``<docstring>`` must be specified as a line of text providing The ``<docstring>`` must be specified as a line of text
a quick summary of the option for presentation to :manual:`cmake-gui(1)` providing a quick summary of the option
users. for presentation to :manual:`cmake-gui(1)` users.
If the cache entry does not exist prior to the call or the ``FORCE`` If the cache entry does not exist prior to the call or the ``FORCE``
option is given then the cache entry will be set to the given value. option is given then the cache entry will be set to the given value.
.. note:: .. note::
The content of the cache variable will not be directly accessible if a normal The content of the cache variable will not be directly accessible
variable of the same name already exists (see :ref:`rules of variable if a normal variable of the same name already exists
evaluation <CMake Language Variables>`). If policy :policy:`CMP0126` is set (see :ref:`rules of variable evaluation <CMake Language Variables>`).
to ``OLD``, any normal variable binding in the current scope will be removed. If policy :policy:`CMP0126` is set to ``OLD``, any normal variable
binding in the current scope will be removed.
It is possible for the cache entry to exist prior to the call but It is possible for the cache entry to exist prior to the call but
have no type set if it was created on the :manual:`cmake(1)` command have no type set if it was created on the :manual:`cmake(1)` command
line by a user through the :option:`-D\<var\>=\<value\> <cmake -D>` option without line by a user through the :option:`-D\<var\>=\<value\> <cmake -D>` option
specifying a type. In this case the ``set`` command will add the without specifying a type. In this case the ``set`` command will add the
type. Furthermore, if the ``<type>`` is ``PATH`` or ``FILEPATH`` type. Furthermore, if the ``<type>`` is ``PATH`` or ``FILEPATH``
and the ``<value>`` provided on the command line is a relative path, and the ``<value>`` provided on the command line is a relative path,
then the ``set`` command will treat the path as relative to the then the ``set`` command will treat the path as relative to the
current working directory and convert it to an absolute path. current working directory and convert it to an absolute path.
Set Environment Variable Set Environment Variable
^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: cmake .. signature::
set(ENV{<variable>} [<value>]) set(ENV{<variable>} [<value>])
:target: ENV
Sets an :manual:`Environment Variable <cmake-env-variables(7)>` Sets an :manual:`Environment Variable <cmake-env-variables(7)>`
to the given value. to the given value.
Subsequent calls of ``$ENV{<variable>}`` will return this new value. Subsequent calls of ``$ENV{<variable>}`` will return this new value.
This command affects only the current CMake process, not the process This command affects only the current CMake process, not the process
from which CMake was called, nor the system environment at large, from which CMake was called, nor the system environment at large,
nor the environment of subsequent build or test processes. nor the environment of subsequent build or test processes.
If no argument is given after ``ENV{<variable>}`` or if ``<value>`` is If no argument is given after ``ENV{<variable>}`` or if ``<value>`` is
an empty string, then this command will clear any existing value of the an empty string, then this command will clear any existing value of the
environment variable. environment variable.
Arguments after ``<value>`` are ignored. If extra arguments are found, Arguments after ``<value>`` are ignored. If extra arguments are found,
then an author warning is issued. then an author warning is issued.
See Also See Also
^^^^^^^^ ^^^^^^^^

@ -38,6 +38,8 @@ It must be one of the following:
Scope may name zero or more existing targets. Scope may name zero or more existing targets.
See also the :command:`set_target_properties` command. See also the :command:`set_target_properties` command.
:ref:`Alias Targets` do not support setting target properties.
``SOURCE`` ``SOURCE``
Scope may name zero or more source files. By default, source file properties Scope may name zero or more source files. By default, source file properties
are only visible to targets added in the same directory (``CMakeLists.txt``). are only visible to targets added in the same directory (``CMakeLists.txt``).
@ -82,15 +84,15 @@ It must be one of the following:
to the installation prefix. to the installation prefix.
``TEST`` ``TEST``
Scope may name zero or more existing tests. Scope is limited to the directory the command is called in. It may name zero
See also the :command:`set_tests_properties` command. or more existing tests. See also command :command:`set_tests_properties`.
Test property values may be specified using Test property values may be specified using
:manual:`generator expressions <cmake-generator-expressions(7)>` :manual:`generator expressions <cmake-generator-expressions(7)>`
for tests created by the :command:`add_test(NAME)` signature. for tests created by the :command:`add_test(NAME)` signature.
``CACHE`` ``CACHE``
Scope must name zero or more cache existing entries. Scope must name zero or more existing cache entries.
The required ``PROPERTY`` option is immediately followed by the name of The required ``PROPERTY`` option is immediately followed by the name of
the property to set. Remaining arguments are used to compose the the property to set. Remaining arguments are used to compose the

@ -15,6 +15,8 @@ set next. You can use any prop value pair you want and extract it
later with the :command:`get_property` or :command:`get_target_property` later with the :command:`get_property` or :command:`get_target_property`
command. command.
:ref:`Alias Targets` do not support setting target properties.
See Also See Also
^^^^^^^^ ^^^^^^^^

@ -32,7 +32,7 @@ Synopsis
string(`COMPARE`_ <op> <string1> <string2> <out-var>) string(`COMPARE`_ <op> <string1> <string2> <out-var>)
`Hashing`_ `Hashing`_
string(`\<HASH\> <HASH_>`_ <out-var> <input>) string(`\<HASH\>`_ <out-var> <input>)
`Generation`_ `Generation`_
string(`ASCII`_ <number>... <out-var>) string(`ASCII`_ <number>... <out-var>)
@ -45,16 +45,16 @@ Synopsis
`JSON`_ `JSON`_
string(JSON <out-var> [ERROR_VARIABLE <error-var>] string(JSON <out-var> [ERROR_VARIABLE <error-var>]
{:ref:`GET <JSON_GET>` | :ref:`TYPE <JSON_TYPE>` | :ref:`LENGTH <JSON_LENGTH>` | :ref:`REMOVE <JSON_REMOVE>`} {`GET <JSON GET_>`_ | `TYPE <JSON TYPE_>`_ | `LENGTH <JSON LENGTH_>`_ | `REMOVE <JSON REMOVE_>`_}
<json-string> <member|index> [<member|index> ...]) <json-string> <member|index> [<member|index> ...])
string(JSON <out-var> [ERROR_VARIABLE <error-var>] string(JSON <out-var> [ERROR_VARIABLE <error-var>]
:ref:`MEMBER <JSON_MEMBER>` <json-string> `MEMBER <JSON MEMBER_>`_ <json-string>
[<member|index> ...] <index>) [<member|index> ...] <index>)
string(JSON <out-var> [ERROR_VARIABLE <error-var>] string(JSON <out-var> [ERROR_VARIABLE <error-var>]
:ref:`SET <JSON_SET>` <json-string> `SET <JSON SET_>`_ <json-string>
<member|index> [<member|index> ...] <value>) <member|index> [<member|index> ...] <value>)
string(JSON <out-var> [ERROR_VARIABLE <error-var>] string(JSON <out-var> [ERROR_VARIABLE <error-var>]
:ref:`EQUAL <JSON_EQUAL>` <json-string1> <json-string2>) `EQUAL <JSON EQUAL_>`_ <json-string1> <json-string2>)
Search and Replace Search and Replace
^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^
@ -62,75 +62,60 @@ Search and Replace
Search and Replace With Plain Strings Search and Replace With Plain Strings
""""""""""""""""""""""""""""""""""""" """""""""""""""""""""""""""""""""""""
.. _FIND: .. signature::
.. code-block:: cmake
string(FIND <string> <substring> <output_variable> [REVERSE]) string(FIND <string> <substring> <output_variable> [REVERSE])
Return the position where the given ``<substring>`` was found in Return the position where the given ``<substring>`` was found in
the supplied ``<string>``. If the ``REVERSE`` flag was used, the command will the supplied ``<string>``. If the ``REVERSE`` flag was used, the command
search for the position of the last occurrence of the specified will search for the position of the last occurrence of the specified
``<substring>``. If the ``<substring>`` is not found, a position of -1 is ``<substring>``. If the ``<substring>`` is not found, a position of -1 is
returned. returned.
The ``string(FIND)`` subcommand treats all strings as ASCII-only characters.
The index stored in ``<output_variable>`` will also be counted in bytes,
so strings containing multi-byte characters may lead to unexpected results.
.. _REPLACE:
.. code-block:: cmake The ``string(FIND)`` subcommand treats all strings as ASCII-only characters.
The index stored in ``<output_variable>`` will also be counted in bytes,
so strings containing multi-byte characters may lead to unexpected results.
.. signature::
string(REPLACE <match_string> string(REPLACE <match_string>
<replace_string> <output_variable> <replace_string> <output_variable>
<input> [<input>...]) <input> [<input>...])
Replace all occurrences of ``<match_string>`` in the ``<input>`` Replace all occurrences of ``<match_string>`` in the ``<input>``
with ``<replace_string>`` and store the result in the ``<output_variable>``. with ``<replace_string>`` and store the result in the ``<output_variable>``.
Search and Replace With Regular Expressions Search and Replace With Regular Expressions
""""""""""""""""""""""""""""""""""""""""""" """""""""""""""""""""""""""""""""""""""""""
.. _`REGEX MATCH`: .. signature::
.. code-block:: cmake
string(REGEX MATCH <regular_expression> string(REGEX MATCH <regular_expression>
<output_variable> <input> [<input>...]) <output_variable> <input> [<input>...])
Match the ``<regular_expression>`` once and store the match in the Match the ``<regular_expression>`` once and store the match in the
``<output_variable>``. ``<output_variable>``.
All ``<input>`` arguments are concatenated before matching. All ``<input>`` arguments are concatenated before matching.
Regular expressions are specified in the subsection just below. Regular expressions are specified in the subsection just below.
.. _`REGEX MATCHALL`:
.. code-block:: cmake
.. signature::
string(REGEX MATCHALL <regular_expression> string(REGEX MATCHALL <regular_expression>
<output_variable> <input> [<input>...]) <output_variable> <input> [<input>...])
Match the ``<regular_expression>`` as many times as possible and store the Match the ``<regular_expression>`` as many times as possible and store the
matches in the ``<output_variable>`` as a list. matches in the ``<output_variable>`` as a list.
All ``<input>`` arguments are concatenated before matching. All ``<input>`` arguments are concatenated before matching.
.. _`REGEX REPLACE`:
.. code-block:: cmake
.. signature::
string(REGEX REPLACE <regular_expression> string(REGEX REPLACE <regular_expression>
<replacement_expression> <output_variable> <replacement_expression> <output_variable>
<input> [<input>...]) <input> [<input>...])
Match the ``<regular_expression>`` as many times as possible and substitute Match the ``<regular_expression>`` as many times as possible and substitute
the ``<replacement_expression>`` for the match in the output. the ``<replacement_expression>`` for the match in the output.
All ``<input>`` arguments are concatenated before matching. All ``<input>`` arguments are concatenated before matching.
The ``<replacement_expression>`` may refer to parenthesis-delimited The ``<replacement_expression>`` may refer to parenthesis-delimited
subexpressions of the match using ``\1``, ``\2``, ..., ``\9``. Note that subexpressions of the match using ``\1``, ``\2``, ..., ``\9``. Note that
two backslashes (``\\1``) are required in CMake code to get a backslash two backslashes (``\\1``) are required in CMake code to get a backslash
through argument parsing. through argument parsing.
.. _`Regex Specification`: .. _`Regex Specification`:
@ -201,130 +186,100 @@ newlines, and backslashes (respectively) to pass in a regex. For example:
Manipulation Manipulation
^^^^^^^^^^^^ ^^^^^^^^^^^^
.. _APPEND: .. signature::
.. code-block:: cmake
string(APPEND <string_variable> [<input>...]) string(APPEND <string_variable> [<input>...])
.. versionadded:: 3.4 .. versionadded:: 3.4
Append all the ``<input>`` arguments to the string. Append all the ``<input>`` arguments to the string.
.. _PREPEND:
.. code-block:: cmake
.. signature::
string(PREPEND <string_variable> [<input>...]) string(PREPEND <string_variable> [<input>...])
.. versionadded:: 3.10 .. versionadded:: 3.10
Prepend all the ``<input>`` arguments to the string.
.. _CONCAT:
.. code-block:: cmake Prepend all the ``<input>`` arguments to the string.
.. signature::
string(CONCAT <output_variable> [<input>...]) string(CONCAT <output_variable> [<input>...])
Concatenate all the ``<input>`` arguments together and store Concatenate all the ``<input>`` arguments together and store
the result in the named ``<output_variable>``. the result in the named ``<output_variable>``.
.. _JOIN:
.. code-block:: cmake
.. signature::
string(JOIN <glue> <output_variable> [<input>...]) string(JOIN <glue> <output_variable> [<input>...])
.. versionadded:: 3.12 .. versionadded:: 3.12
Join all the ``<input>`` arguments together using the ``<glue>`` Join all the ``<input>`` arguments together using the ``<glue>``
string and store the result in the named ``<output_variable>``. string and store the result in the named ``<output_variable>``.
To join a list's elements, prefer to use the ``JOIN`` operator To join a list's elements, prefer to use the ``JOIN`` operator
from the :command:`list` command. This allows for the elements to have from the :command:`list` command. This allows for the elements to have
special characters like ``;`` in them. special characters like ``;`` in them.
.. _TOLOWER:
.. code-block:: cmake
.. signature::
string(TOLOWER <string> <output_variable>) string(TOLOWER <string> <output_variable>)
Convert ``<string>`` to lower characters. Convert ``<string>`` to lower characters.
.. _TOUPPER:
.. code-block:: cmake
.. signature::
string(TOUPPER <string> <output_variable>) string(TOUPPER <string> <output_variable>)
Convert ``<string>`` to upper characters. Convert ``<string>`` to upper characters.
.. _LENGTH:
.. code-block:: cmake
.. signature::
string(LENGTH <string> <output_variable>) string(LENGTH <string> <output_variable>)
Store in an ``<output_variable>`` a given string's length in bytes. Store in an ``<output_variable>`` a given string's length in bytes.
Note that this means if ``<string>`` contains multi-byte characters, the Note that this means if ``<string>`` contains multi-byte characters,
result stored in ``<output_variable>`` will *not* be the number of characters. the result stored in ``<output_variable>`` will *not* be
the number of characters.
.. _SUBSTRING:
.. code-block:: cmake
.. signature::
string(SUBSTRING <string> <begin> <length> <output_variable>) string(SUBSTRING <string> <begin> <length> <output_variable>)
Store in an ``<output_variable>`` a substring of a given ``<string>``. If Store in an ``<output_variable>`` a substring of a given ``<string>``. If
``<length>`` is ``-1`` the remainder of the string starting at ``<begin>`` ``<length>`` is ``-1`` the remainder of the string starting at ``<begin>``
will be returned. will be returned.
.. versionchanged:: 3.2 .. versionchanged:: 3.2
If ``<string>`` is shorter than ``<length>`` then the end of the string If ``<string>`` is shorter than ``<length>``
is used instead. Previous versions of CMake reported an error in this case. then the end of the string is used instead.
Previous versions of CMake reported an error in this case.
Both ``<begin>`` and ``<length>`` are counted in bytes, so care must Both ``<begin>`` and ``<length>`` are counted in bytes, so care must
be exercised if ``<string>`` could contain multi-byte characters. be exercised if ``<string>`` could contain multi-byte characters.
.. _STRIP:
.. code-block:: cmake
.. signature::
string(STRIP <string> <output_variable>) string(STRIP <string> <output_variable>)
Store in an ``<output_variable>`` a substring of a given ``<string>`` with Store in an ``<output_variable>`` a substring of a given ``<string>``
leading and trailing spaces removed. with leading and trailing spaces removed.
.. _GENEX_STRIP:
.. code-block:: cmake
.. signature::
string(GENEX_STRIP <string> <output_variable>) string(GENEX_STRIP <string> <output_variable>)
.. versionadded:: 3.1 .. versionadded:: 3.1
Strip any :manual:`generator expressions <cmake-generator-expressions(7)>`
from the input ``<string>`` and store the result in the ``<output_variable>``.
.. _REPEAT: Strip any :manual:`generator expressions <cmake-generator-expressions(7)>`
from the input ``<string>`` and store the result
.. code-block:: cmake in the ``<output_variable>``.
.. signature::
string(REPEAT <string> <count> <output_variable>) string(REPEAT <string> <count> <output_variable>)
.. versionadded:: 3.15 .. versionadded:: 3.15
Produce the output string as the input ``<string>`` repeated ``<count>`` times. Produce the output string as the input ``<string>``
repeated ``<count>`` times.
Comparison Comparison
^^^^^^^^^^ ^^^^^^^^^^
.. _COMPARE: .. _COMPARE:
.. code-block:: cmake .. signature::
string(COMPARE LESS <string1> <string2> <output_variable>) string(COMPARE LESS <string1> <string2> <output_variable>)
string(COMPARE GREATER <string1> <string2> <output_variable>) string(COMPARE GREATER <string1> <string2> <output_variable>)
string(COMPARE EQUAL <string1> <string2> <output_variable>) string(COMPARE EQUAL <string1> <string2> <output_variable>)
@ -332,9 +287,9 @@ Comparison
string(COMPARE LESS_EQUAL <string1> <string2> <output_variable>) string(COMPARE LESS_EQUAL <string1> <string2> <output_variable>)
string(COMPARE GREATER_EQUAL <string1> <string2> <output_variable>) string(COMPARE GREATER_EQUAL <string1> <string2> <output_variable>)
Compare the strings and store true or false in the ``<output_variable>``. Compare the strings and store true or false in the ``<output_variable>``.
.. versionadded:: 3.7 .. versionadded:: 3.7
Added the ``LESS_EQUAL`` and ``GREATER_EQUAL`` options. Added the ``LESS_EQUAL`` and ``GREATER_EQUAL`` options.
.. _`Supported Hash Algorithms`: .. _`Supported Hash Algorithms`:
@ -342,230 +297,207 @@ Compare the strings and store true or false in the ``<output_variable>``.
Hashing Hashing
^^^^^^^ ^^^^^^^
.. _`HASH`: .. signature::
.. code-block:: cmake
string(<HASH> <output_variable> <input>) string(<HASH> <output_variable> <input>)
:target: <HASH>
Compute a cryptographic hash of the ``<input>`` string. Compute a cryptographic hash of the ``<input>`` string.
The supported ``<HASH>`` algorithm names are: The supported ``<HASH>`` algorithm names are:
``MD5`` ``MD5``
Message-Digest Algorithm 5, RFC 1321. Message-Digest Algorithm 5, RFC 1321.
``SHA1`` ``SHA1``
US Secure Hash Algorithm 1, RFC 3174. US Secure Hash Algorithm 1, RFC 3174.
``SHA224`` ``SHA224``
US Secure Hash Algorithms, RFC 4634. US Secure Hash Algorithms, RFC 4634.
``SHA256`` ``SHA256``
US Secure Hash Algorithms, RFC 4634. US Secure Hash Algorithms, RFC 4634.
``SHA384`` ``SHA384``
US Secure Hash Algorithms, RFC 4634. US Secure Hash Algorithms, RFC 4634.
``SHA512`` ``SHA512``
US Secure Hash Algorithms, RFC 4634. US Secure Hash Algorithms, RFC 4634.
``SHA3_224`` ``SHA3_224``
Keccak SHA-3. Keccak SHA-3.
``SHA3_256`` ``SHA3_256``
Keccak SHA-3. Keccak SHA-3.
``SHA3_384`` ``SHA3_384``
Keccak SHA-3. Keccak SHA-3.
``SHA3_512`` ``SHA3_512``
Keccak SHA-3. Keccak SHA-3.
.. versionadded:: 3.8 .. versionadded:: 3.8
Added the ``SHA3_*`` hash algorithms. Added the ``SHA3_*`` hash algorithms.
Generation Generation
^^^^^^^^^^ ^^^^^^^^^^
.. _ASCII: .. signature::
.. code-block:: cmake
string(ASCII <number> [<number> ...] <output_variable>) string(ASCII <number> [<number> ...] <output_variable>)
Convert all numbers into corresponding ASCII characters. Convert all numbers into corresponding ASCII characters.
.. _HEX:
.. code-block:: cmake
.. signature::
string(HEX <string> <output_variable>) string(HEX <string> <output_variable>)
.. versionadded:: 3.18 .. versionadded:: 3.18
Convert each byte in the input ``<string>`` to its hexadecimal representation Convert each byte in the input ``<string>`` to its hexadecimal representation
and store the concatenated hex digits in the ``<output_variable>``. Letters in and store the concatenated hex digits in the ``<output_variable>``.
the output (``a`` through ``f``) are in lowercase. Letters in the output (``a`` through ``f``) are in lowercase.
.. _CONFIGURE:
.. code-block:: cmake
.. signature::
string(CONFIGURE <string> <output_variable> string(CONFIGURE <string> <output_variable>
[@ONLY] [ESCAPE_QUOTES]) [@ONLY] [ESCAPE_QUOTES])
Transform a ``<string>`` like :command:`configure_file` transforms a file. Transform a ``<string>`` like :command:`configure_file` transforms a file.
.. _MAKE_C_IDENTIFIER:
.. code-block:: cmake
.. signature::
string(MAKE_C_IDENTIFIER <string> <output_variable>) string(MAKE_C_IDENTIFIER <string> <output_variable>)
Convert each non-alphanumeric character in the input ``<string>`` to an Convert each non-alphanumeric character in the input ``<string>`` to an
underscore and store the result in the ``<output_variable>``. If the first underscore and store the result in the ``<output_variable>``. If the first
character of the ``<string>`` is a digit, an underscore will also be prepended character of the ``<string>`` is a digit, an underscore will also be
to the result. prepended to the result.
.. _RANDOM:
.. code-block:: cmake
.. signature::
string(RANDOM [LENGTH <length>] [ALPHABET <alphabet>] string(RANDOM [LENGTH <length>] [ALPHABET <alphabet>]
[RANDOM_SEED <seed>] <output_variable>) [RANDOM_SEED <seed>] <output_variable>)
Return a random string of given ``<length>`` consisting of Return a random string of given ``<length>`` consisting of
characters from the given ``<alphabet>``. Default length is 5 characters characters from the given ``<alphabet>``. Default length is 5 characters
and default alphabet is all numbers and upper and lower case letters. and default alphabet is all numbers and upper and lower case letters.
If an integer ``RANDOM_SEED`` is given, its value will be used to seed the If an integer ``RANDOM_SEED`` is given, its value will be used to seed the
random number generator. random number generator.
.. _TIMESTAMP:
.. code-block:: cmake
.. signature::
string(TIMESTAMP <output_variable> [<format_string>] [UTC]) string(TIMESTAMP <output_variable> [<format_string>] [UTC])
Write a string representation of the current date Write a string representation of the current date
and/or time to the ``<output_variable>``. and/or time to the ``<output_variable>``.
If the command is unable to obtain a timestamp, the ``<output_variable>`` If the command is unable to obtain a timestamp, the ``<output_variable>``
will be set to the empty string ``""``. will be set to the empty string ``""``.
The optional ``UTC`` flag requests the current date/time representation to The optional ``UTC`` flag requests the current date/time representation to
be in Coordinated Universal Time (UTC) rather than local time. be in Coordinated Universal Time (UTC) rather than local time.
The optional ``<format_string>`` may contain the following format The optional ``<format_string>`` may contain the following format
specifiers: specifiers:
``%%`` ``%%``
.. versionadded:: 3.8 .. versionadded:: 3.8
A literal percent sign (%). A literal percent sign (%).
``%d`` ``%d``
The day of the current month (01-31). The day of the current month (01-31).
``%H`` ``%H``
The hour on a 24-hour clock (00-23). The hour on a 24-hour clock (00-23).
``%I`` ``%I``
The hour on a 12-hour clock (01-12). The hour on a 12-hour clock (01-12).
``%j`` ``%j``
The day of the current year (001-366). The day of the current year (001-366).
``%m`` ``%m``
The month of the current year (01-12). The month of the current year (01-12).
``%b`` ``%b``
.. versionadded:: 3.7 .. versionadded:: 3.7
Abbreviated month name (e.g. Oct). Abbreviated month name (e.g. Oct).
``%B`` ``%B``
.. versionadded:: 3.10 .. versionadded:: 3.10
Full month name (e.g. October). Full month name (e.g. October).
``%M`` ``%M``
The minute of the current hour (00-59). The minute of the current hour (00-59).
``%s`` ``%s``
.. versionadded:: 3.6 .. versionadded:: 3.6
Seconds since midnight (UTC) 1-Jan-1970 (UNIX time). Seconds since midnight (UTC) 1-Jan-1970 (UNIX time).
``%S`` ``%S``
The second of the current minute. 60 represents a leap second. (00-60) The second of the current minute. 60 represents a leap second. (00-60)
``%f`` ``%f``
.. versionadded:: 3.23 .. versionadded:: 3.23
The microsecond of the current second (000000-999999). The microsecond of the current second (000000-999999).
``%U`` ``%U``
The week number of the current year (00-53). The week number of the current year (00-53).
``%V`` ``%V``
.. versionadded:: 3.22 .. versionadded:: 3.22
The ISO 8601 week number of the current year (01-53). The ISO 8601 week number of the current year (01-53).
``%w`` ``%w``
The day of the current week. 0 is Sunday. (0-6) The day of the current week. 0 is Sunday. (0-6)
``%a`` ``%a``
.. versionadded:: 3.7 .. versionadded:: 3.7
Abbreviated weekday name (e.g. Fri). Abbreviated weekday name (e.g. Fri).
``%A`` ``%A``
.. versionadded:: 3.10 .. versionadded:: 3.10
Full weekday name (e.g. Friday). Full weekday name (e.g. Friday).
``%y`` ``%y``
The last two digits of the current year (00-99). The last two digits of the current year (00-99).
``%Y`` ``%Y``
The current year. The current year.
``%z`` ``%z``
.. versionadded:: 3.26 .. versionadded:: 3.26
The offset of the time zone from UTC, in hours and minutes, The offset of the time zone from UTC, in hours and minutes,
with format ``+hhmm`` or ``-hhmm``. with format ``+hhmm`` or ``-hhmm``.
``%Z`` ``%Z``
.. versionadded:: 3.26 .. versionadded:: 3.26
The time zone name. The time zone name.
Unknown format specifiers will be ignored and copied to the output Unknown format specifiers will be ignored and copied to the output
as-is. as-is.
If no explicit ``<format_string>`` is given, it will default to: If no explicit ``<format_string>`` is given, it will default to:
:: ::
%Y-%m-%dT%H:%M:%S for local time. %Y-%m-%dT%H:%M:%S for local time.
%Y-%m-%dT%H:%M:%SZ for UTC. %Y-%m-%dT%H:%M:%SZ for UTC.
.. versionadded:: 3.8 .. versionadded:: 3.8
If the ``SOURCE_DATE_EPOCH`` environment variable is set, If the ``SOURCE_DATE_EPOCH`` environment variable is set,
its value will be used instead of the current time. its value will be used instead of the current time.
See https://reproducible-builds.org/specs/source-date-epoch/ for details. See https://reproducible-builds.org/specs/source-date-epoch/ for details.
.. _UUID: .. signature::
.. code-block:: cmake
string(UUID <output_variable> NAMESPACE <namespace> NAME <name> string(UUID <output_variable> NAMESPACE <namespace> NAME <name>
TYPE <MD5|SHA1> [UPPER]) TYPE <MD5|SHA1> [UPPER])
.. versionadded:: 3.1 .. versionadded:: 3.1
Create a universally unique identifier (aka GUID) as per RFC4122 Create a universally unique identifier (aka GUID) as per RFC4122
based on the hash of the combined values of ``<namespace>`` based on the hash of the combined values of ``<namespace>``
(which itself has to be a valid UUID) and ``<name>``. (which itself has to be a valid UUID) and ``<name>``.
The hash algorithm can be either ``MD5`` (Version 3 UUID) or The hash algorithm can be either ``MD5`` (Version 3 UUID) or
``SHA1`` (Version 5 UUID). ``SHA1`` (Version 5 UUID).
A UUID has the format ``xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`` A UUID has the format ``xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx``
where each ``x`` represents a lower case hexadecimal character. where each ``x`` represents a lower case hexadecimal character.
Where required, an uppercase representation can be requested Where required, an uppercase representation can be requested
with the optional ``UPPER`` flag. with the optional ``UPPER`` flag.
.. _JSON: .. _JSON:
@ -586,78 +518,75 @@ Functionality for querying a JSON string.
option is not present, a fatal error message is generated. If no error option is not present, a fatal error message is generated. If no error
occurs, the ``<error-variable>`` will be set to ``NOTFOUND``. occurs, the ``<error-variable>`` will be set to ``NOTFOUND``.
.. _JSON_GET: .. signature::
.. code-block:: cmake
string(JSON <out-var> [ERROR_VARIABLE <error-variable>] string(JSON <out-var> [ERROR_VARIABLE <error-variable>]
GET <json-string> <member|index> [<member|index> ...]) GET <json-string> <member|index> [<member|index> ...])
:target: JSON GET
Get an element from ``<json-string>`` at the location given Get an element from ``<json-string>`` at the location given
by the list of ``<member|index>`` arguments. by the list of ``<member|index>`` arguments.
Array and object elements will be returned as a JSON string. Array and object elements will be returned as a JSON string.
Boolean elements will be returned as ``ON`` or ``OFF``. Boolean elements will be returned as ``ON`` or ``OFF``.
Null elements will be returned as an empty string. Null elements will be returned as an empty string.
Number and string types will be returned as strings. Number and string types will be returned as strings.
.. _JSON_TYPE:
.. code-block:: cmake
.. signature::
string(JSON <out-var> [ERROR_VARIABLE <error-variable>] string(JSON <out-var> [ERROR_VARIABLE <error-variable>]
TYPE <json-string> <member|index> [<member|index> ...]) TYPE <json-string> <member|index> [<member|index> ...])
:target: JSON TYPE
Get the type of an element in ``<json-string>`` at the location Get the type of an element in ``<json-string>`` at the location
given by the list of ``<member|index>`` arguments. The ``<out-var>`` given by the list of ``<member|index>`` arguments. The ``<out-var>``
will be set to one of ``NULL``, ``NUMBER``, ``STRING``, ``BOOLEAN``, will be set to one of ``NULL``, ``NUMBER``, ``STRING``, ``BOOLEAN``,
``ARRAY``, or ``OBJECT``. ``ARRAY``, or ``OBJECT``.
.. _JSON_MEMBER:
.. code-block:: cmake
.. signature::
string(JSON <out-var> [ERROR_VARIABLE <error-var>] string(JSON <out-var> [ERROR_VARIABLE <error-var>]
MEMBER <json-string> MEMBER <json-string>
[<member|index> ...] <index>) [<member|index> ...] <index>)
:target: JSON MEMBER
Get the name of the ``<index>``-th member in ``<json-string>`` at the location Get the name of the ``<index>``-th member in ``<json-string>``
given by the list of ``<member|index>`` arguments. at the location given by the list of ``<member|index>`` arguments.
Requires an element of object type. Requires an element of object type.
.. _JSON_LENGTH:
.. code-block:: cmake
.. signature::
string(JSON <out-var> [ERROR_VARIABLE <error-variable>] string(JSON <out-var> [ERROR_VARIABLE <error-variable>]
LENGTH <json-string> [<member|index> ...]) LENGTH <json-string> [<member|index> ...])
:target: JSON LENGTH
Get the length of an element in ``<json-string>`` at the location Get the length of an element in ``<json-string>`` at the location
given by the list of ``<member|index>`` arguments. given by the list of ``<member|index>`` arguments.
Requires an element of array or object type. Requires an element of array or object type.
.. _JSON_REMOVE:
.. code-block:: cmake
.. signature::
string(JSON <out-var> [ERROR_VARIABLE <error-variable>] string(JSON <out-var> [ERROR_VARIABLE <error-variable>]
REMOVE <json-string> <member|index> [<member|index> ...]) REMOVE <json-string> <member|index> [<member|index> ...])
:target: JSON REMOVE
Remove an element from ``<json-string>`` at the location Remove an element from ``<json-string>`` at the location
given by the list of ``<member|index>`` arguments. The JSON string given by the list of ``<member|index>`` arguments. The JSON string
without the removed element will be stored in ``<out-var>``. without the removed element will be stored in ``<out-var>``.
.. _JSON_SET:
.. code-block:: cmake
.. signature::
string(JSON <out-var> [ERROR_VARIABLE <error-variable>] string(JSON <out-var> [ERROR_VARIABLE <error-variable>]
SET <json-string> <member|index> [<member|index> ...] <value>) SET <json-string> <member|index> [<member|index> ...] <value>)
:target: JSON SET
Set an element in ``<json-string>`` at the location Set an element in ``<json-string>`` at the location
given by the list of ``<member|index>`` arguments to ``<value>``. given by the list of ``<member|index>`` arguments to ``<value>``.
The contents of ``<value>`` should be valid JSON. The contents of ``<value>`` should be valid JSON.
If ``<json-string>`` is an array, ``<value>`` can be appended to the end of
.. _JSON_EQUAL: the array by using a number greater or equal to the array length as the
.. code-block:: cmake ``<member|index>`` argument.
.. signature::
string(JSON <out-var> [ERROR_VARIABLE <error-var>] string(JSON <out-var> [ERROR_VARIABLE <error-var>]
EQUAL <json-string1> <json-string2>) EQUAL <json-string1> <json-string2>)
:target: JSON EQUAL
Compare the two JSON objects given by ``<json-string1>`` and ``<json-string2>`` Compare the two JSON objects given by ``<json-string1>``
for equality. The contents of ``<json-string1>`` and ``<json-string2>`` and ``<json-string2>`` for equality. The contents of ``<json-string1>``
should be valid JSON. The ``<out-var>`` will be set to a true value if the and ``<json-string2>`` should be valid JSON. The ``<out-var>``
JSON objects are considered equal, or a false value otherwise. will be set to a true value if the JSON objects are considered equal,
or a false value otherwise.

@ -15,6 +15,11 @@ are used when compiling the given ``<target>``, which must have been
created by a command such as :command:`add_executable` or created by a command such as :command:`add_executable` or
:command:`add_library` and must not be an :ref:`ALIAS target <Alias Targets>`. :command:`add_library` and must not be an :ref:`ALIAS target <Alias Targets>`.
.. note::
These options are not used when linking the target.
See the :command:`target_link_options` command for that.
Arguments Arguments
^^^^^^^^^ ^^^^^^^^^
@ -50,9 +55,17 @@ See Also
* For file-specific settings, there is the source file property :prop_sf:`COMPILE_OPTIONS`. * For file-specific settings, there is the source file property :prop_sf:`COMPILE_OPTIONS`.
* This command adds compile options for all languages in a target.
Use the :genex:`COMPILE_LANGUAGE` generator expression to specify
per-language compile options.
* :command:`target_compile_features` * :command:`target_compile_features`
* :command:`target_link_libraries` * :command:`target_link_libraries`
* :command:`target_link_directories` * :command:`target_link_directories`
* :command:`target_link_options` * :command:`target_link_options`
* :command:`target_precompile_headers` * :command:`target_precompile_headers`
* :command:`target_sources` * :command:`target_sources`
* :variable:`CMAKE_<LANG>_FLAGS` and :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>`
add language-wide flags passed to all invocations of the compiler.
This includes invocations that drive compiling and those that drive linking.

@ -62,3 +62,7 @@ See Also
* :command:`target_link_directories` * :command:`target_link_directories`
* :command:`target_precompile_headers` * :command:`target_precompile_headers`
* :command:`target_sources` * :command:`target_sources`
* :variable:`CMAKE_<LANG>_FLAGS` and :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>`
add language-wide flags passed to all invocations of the compiler.
This includes invocations that drive compiling and those that drive linking.

@ -70,7 +70,7 @@ included by absolute path. For example:
<unordered_map> <unordered_map>
) )
.. |command_name| replace:: ``target_compile_features`` .. |command_name| replace:: ``target_precompile_headers``
.. |more_see_also| replace:: The :genex:`$<COMPILE_LANGUAGE:...>` generator .. |more_see_also| replace:: The :genex:`$<COMPILE_LANGUAGE:...>` generator
expression is particularly useful for specifying a language-specific header expression is particularly useful for specifying a language-specific header
to precompile for only one language (e.g. ``CXX`` and not ``C``). In this to precompile for only one language (e.g. ``CXX`` and not ``C``). In this

@ -91,15 +91,6 @@ files within those directories. The acceptable types include:
using the ``export`` keyword). This file set type may not have an using the ``export`` keyword). This file set type may not have an
``INTERFACE`` scope except on ``IMPORTED`` targets. ``INTERFACE`` scope except on ``IMPORTED`` targets.
``CXX_MODULE_HEADER_UNITS``
.. note ::
Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
C++ header sources which may be imported by other C++ source code. This file
set type may not have an ``INTERFACE`` scope except on ``IMPORTED`` targets.
The optional default file sets are named after their type. The target may not The optional default file sets are named after their type. The target may not
be a custom target or :prop_tgt:`FRAMEWORK` target. be a custom target or :prop_tgt:`FRAMEWORK` target.
@ -177,31 +168,20 @@ For file sets of type ``CXX_MODULES``:
* :prop_tgt:`CXX_MODULE_DIRS` * :prop_tgt:`CXX_MODULE_DIRS`
* :prop_tgt:`CXX_MODULE_DIRS_<NAME>` * :prop_tgt:`CXX_MODULE_DIRS_<NAME>`
For file sets of type ``CXX_MODULE_HEADER_UNITS``:
* :prop_tgt:`CXX_MODULE_HEADER_UNIT_SETS`
* :prop_tgt:`INTERFACE_CXX_MODULE_HEADER_UNIT_SETS`
* :prop_tgt:`CXX_MODULE_HEADER_UNIT_SET`
* :prop_tgt:`CXX_MODULE_HEADER_UNIT_SET_<NAME>`
* :prop_tgt:`CXX_MODULE_HEADER_UNIT_DIRS`
* :prop_tgt:`CXX_MODULE_HEADER_UNIT_DIRS_<NAME>`
Target properties related to include directories are also modified by Target properties related to include directories are also modified by
``target_sources(FILE_SET)`` as follows: ``target_sources(FILE_SET)`` as follows:
:prop_tgt:`INCLUDE_DIRECTORIES` :prop_tgt:`INCLUDE_DIRECTORIES`
If the ``TYPE`` is ``HEADERS`` or ``CXX_MODULE_HEADER_UNITS``, and the scope If the ``TYPE`` is ``HEADERS``, and the scope of the file set is ``PRIVATE``
of the file set is ``PRIVATE`` or ``PUBLIC``, all of the ``BASE_DIRS`` of or ``PUBLIC``, all of the ``BASE_DIRS`` of the file set are wrapped in
the file set are wrapped in :genex:`$<BUILD_INTERFACE>` and appended to this :genex:`$<BUILD_INTERFACE>` and appended to this property.
property.
:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`
If the ``TYPE`` is ``HEADERS`` or ``CXX_MODULE_HEADER_UNITS``, and the scope If the ``TYPE`` is ``HEADERS``, and the scope of the file set is
of the file set is ``INTERFACE`` or ``PUBLIC``, all of the ``BASE_DIRS`` of ``INTERFACE`` or ``PUBLIC``, all of the ``BASE_DIRS`` of the file set are
the file set are wrapped in :genex:`$<BUILD_INTERFACE>` and appended to this wrapped in :genex:`$<BUILD_INTERFACE>` and appended to this property.
property.
See Also See Also
^^^^^^^^ ^^^^^^^^

@ -12,19 +12,14 @@ Unset Normal Variable or Cache Entry
Removes a normal variable from the current scope, causing it Removes a normal variable from the current scope, causing it
to become undefined. If ``CACHE`` is present, then a cache variable to become undefined. If ``CACHE`` is present, then a cache variable
is removed instead of a normal variable. Note that when evaluating is removed instead of a normal variable.
:ref:`Variable References` of the form ``${VAR}``, CMake first searches
for a normal variable with that name. If no such normal variable exists,
CMake will then search for a cache entry with that name. Because of this
unsetting a normal variable can expose a cache variable that was previously
hidden. To force a variable reference of the form ``${VAR}`` to return an
empty string, use ``set(<variable> "")``, which clears the normal variable
but leaves it defined.
If ``PARENT_SCOPE`` is present then the variable is removed from the scope If ``PARENT_SCOPE`` is present then the variable is removed from the scope
above the current scope. See the same option in the :command:`set` command above the current scope. See the same option in the :command:`set` command
for further details. for further details.
.. include:: UNSET_NOTE.txt
Unset Environment Variable Unset Environment Variable
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^

@ -0,0 +1,420 @@
CPack Inno Setup Generator
--------------------------
.. versionadded:: 3.27
Inno Setup is a free installer for Windows programs by Jordan Russell and
Martijn Laan (https://jrsoftware.org/isinfo.php).
This documentation explains Inno Setup generator specific options.
The generator provides a lot of options like components. Unfortunately, not
all features (e.g. component dependencies) are currently supported by
Inno Setup and they're ignored by the generator for now.
CPack requires Inno Setup 6 or greater and only works on Windows.
Variables specific to CPack Inno Setup generator
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You can use the following variables to change the behavior of the CPack
``INNOSETUP`` generator:
General
"""""""
None of the following variables is required to be set for the Inno Setup
generator to work. If a variable is marked as mandatory below but not set,
its default value is taken.
The variables can also contain Inno Setup constants like ``{app}``. Please
refer to the documentation of Inno Setup for more information.
If you're asked to provide the path to any file, you can always give an
absolute path or in most cases the relative path from the top-level directory
where all files being installed by an :command:`install` instruction reside.
CPack tries to escape quotes and other special characters for you. However,
using special characters could cause problems.
The following variable simplifies the usage of Inno Setup in CMake:
.. variable:: CPACK_INNOSETUP_USE_CMAKE_BOOL_FORMAT
Inno Setup only uses ``yes`` or ``no`` as boolean formats meanwhile CMake
uses a lot of alternative formats like ``ON`` or ``OFF``. Having this option
turned on enables an automatic conversion.
Consider the following example:
.. code-block:: cmake
set(CMAKE_INNOSETUP_SETUP_AllowNoIcons OFF)
If this option is turned on, the following line will be created in the output
script: ``AllowNoIcons=no``.
Else, the following erroneous line will be created: ``AllowNoIcons=OFF``
The conversion is enabled in every Inno Setup specific variable.
:Mandatory: Yes
:Default: ``ON``
Setup Specific Variables
""""""""""""""""""""""""
.. variable:: CPACK_INNOSETUP_ARCHITECTURE
One of ``x86``, ``x64``, ``arm64`` or ``ia64``. This variable specifies the
target architecture of the installer. This also affects the Program Files
folder or registry keys being used.
CPack tries to determine the correct value with a try compile (see
:variable:`CMAKE_SIZEOF_VOID_P`), but this option can be manually specified
too (especially when using ``ia64`` or cross-platform compilation).
:Mandatory: Yes
:Default: Either ``x86`` or ``x64`` depending on the results of the try-compile
.. variable:: CPACK_INNOSETUP_INSTALL_ROOT
If you don't want the installer to create the installation directory under
Program Files, you've to specify the installation root here.
The full directory of the installation will be:
``${CPACK_INNOSETUP_INSTALL_ROOT}/${CPACK_PACKAGE_INSTALL_DIRECTORY}``.
:Mandatory: Yes
:Default: ``{autopf}``
.. variable:: CPACK_INNOSETUP_ALLOW_CUSTOM_DIRECTORY
If turned on, the installer allows the user to change the installation
directory providing an extra wizard page.
:Mandatory: Yes
:Default: ``ON``
.. variable:: CPACK_INNOSETUP_PROGRAM_MENU_FOLDER
The initial name of the start menu folder being created.
If this variable is set to ``.``, then no separate folder is created,
application shortcuts will appear in the top-level start menu folder.
:Mandatory: Yes
:Default: The value of :variable:`CPACK_PACKAGE_NAME`
.. variable:: CPACK_INNOSETUP_LANGUAGES
A :ref:`semicolon-separated list <CMake Language Lists>` of languages you want
Inno Setup to include.
Currently available: ``armenian``, ``brazilianPortuguese``, ``bulgarian``,
``catalan``, ``corsican``, ``czech``, ``danish``, ``dutch``, ``english``,
``finnish``, ``french``, ``german``, ``hebrew``, ``icelandic``, ``italian``,
``japanese``, ``norwegian``, ``polish``, ``portuguese``, ``russian``,
``slovak``, ``slovenian``, ``spanish``, ``turkish`` and ``ukrainian``.
This list might differ depending on the version of Inno Setup.
:Mandatory: Yes
:Default: ``english``
.. variable:: CPACK_INNOSETUP_IGNORE_LICENSE_PAGE
If you don't specify a license file using
:variable:`CPACK_RESOURCE_FILE_LICENSE`, CPack uses a file for demonstration
purposes. If you want the installer to ignore license files at all, you can
enable this option.
:Mandatory: Yes
:Default: ``OFF``
.. variable:: CPACK_INNOSETUP_IGNORE_README_PAGE
If you don't specify a readme file using
:variable:`CPACK_RESOURCE_FILE_README`, CPack uses a file for demonstration
purposes. If you want the installer to ignore readme files at all, you can
enable this option. Make sure the option is disabled when using
a custom readme file.
:Mandatory: Yes
:Default: ``ON``
.. variable:: CPACK_INNOSETUP_PASSWORD
Enables password protection and file encryption with the given password.
:Mandatory: No
.. variable:: CPACK_INNOSETUP_USE_MODERN_WIZARD
Enables the modern look and feel provided by Inno Setup. If this option is
turned off, the classic style is used instead. Images and icon files are
also affected.
:Mandatory: Yes
:Default: ``OFF`` because of compatibility reasons
.. variable:: CPACK_INNOSETUP_ICON_FILE
The path to a custom installer ``.ico`` file.
Use :variable:`CPACK_PACKAGE_ICON` to customize the bitmap file being shown
in the wizard.
:Mandatory: No
.. variable:: CPACK_INNOSETUP_SETUP_<directive>
This group allows adapting any of the ``[Setup]`` section directives provided
by Inno Setup where ``directive`` is its name.
Here are some examples:
.. code-block:: cmake
set(CPACK_INNOSETUP_SETUP_WizardSmallImageFile "my_bitmap.bmp")
set(CPACK_INNOSETUP_SETUP_AllowNoIcons OFF) # This requires CPACK_INNOSETUP_USE_CMAKE_BOOL_FORMAT to be on
All of these variables have higher priority than the others.
Consider the following example:
.. code-block:: cmake
set(CPACK_INNOSETUP_SETUP_Password "admin")
set(CPACK_INNOSETUP_PASSWORD "secret")
The password will be ``admin`` at the end because ``CPACK_INNOSETUP_PASSWORD``
has less priority than ``CPACK_INNOSETUP_SETUP_Password``.
:Mandatory: No
File Specific Variables
"""""""""""""""""""""""
Although all files being installed by an :command:`install` instruction are
automatically processed and added to the installer, there are some variables
to customize the installation process.
Before using executables (only ``.exe`` or ``.com``) in shortcuts
(e.g. :variable:`CPACK_CREATE_DESKTOP_LINKS`) or ``[Run]`` entries, you've to
add the raw file name (without path and extension) to
:variable:`CPACK_PACKAGE_EXECUTABLES` and create a start menu shortcut
for them.
If you have two files with the same raw name (e.g. ``a/executable.exe`` and
``b/executable.com``), an entry in the section is created twice. This will
result in undefined behavior and is not recommended.
.. variable:: CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS
This variable should contain a
:ref:`semicolon-separated list <CMake Language Lists>` of pairs ``path``,
``instruction`` and can be used to customize the install command being
automatically created for each file or directory.
CPack creates the following Inno Setup instruction for every file...
.. code-block::
Source: "absolute\path\to\my_file.txt"; DestDir: "{app}"; Flags: ignoreversion
...and the following line for every directory:
.. code-block::
Name: "{app}\my_folder"
You might want to change the destination directory or the flags of
``my_file.txt``. Since we can also provide a relative path, the line you'd
like to have, is the following:
.. code-block::
Source: "my_file.txt"; DestDir: "{userdocs}"; Flags: ignoreversion uninsneveruninstall
You would do this by using ``my_file.txt`` as ``path`` and
``Source: "my_file.txt"; DestDir: "{userdocs}"; Flags: ignoreversion uninsneveruninstall``
as ``instruction``.
You've to take care of the `escaping problem <https://cmake.org/cmake/help/book/mastering-cmake/chapter/Packaging%20With%20CPack.html#adding-custom-cpack-options>`_.
So the CMake command would be:
.. code-block:: cmake
set(CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS "my_file.txt;Source: \\\"my_file.txt\\\"\\; DestDir: \\\"{userdocs}\\\"\\; Flags: ignoreversion uninsneveruninstall")
To improve readability, you should go around the escaping problem by using
:variable:`CPACK_VERBATIM_VARIABLES` or by placing the instruction into a
separate CPack project config file.
If you customize the install instruction of a specific file, you lose the
connection to its component. To go around, manually add
``Components: <component>``. You also need to add its shortcuts and ``[Run]``
entries by yourself in a custom section, since the executable won't be found
anymore by :variable:`CPACK_PACKAGE_EXECUTABLES`.
Here's another example (Note: You've to go around the escaping problem for
the example to work):
.. code-block:: cmake
set(CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS
"component1/my_folder" "Name: \"{userdocs}\\my_folder\"\; Components: component1"
"component2/my_folder2/my_file.txt" "Source: \"component2\\my_folder2\\my_file.txt\"\; DestDir: \"{app}\\my_folder2\\my_file.txt\"\; Flags: ignoreversion uninsneveruninstall\; Components: component2")
:Mandatory: No
.. variable:: CPACK_INNOSETUP_MENU_LINKS
This variable should contain a
:ref:`semicolon-separated list <CMake Language Lists>` of pairs ``link``,
``link name`` and can be used to add shortcuts into the start menu folder
beside those of the executables (see :variable:`CPACK_PACKAGE_EXECUTABLES`).
While ``link name`` is the label, ``link`` can be a URL or a path relative to
the installation directory.
Here's an example:
.. code-block:: cmake
set(CPACK_INNOSETUP_MENU_LINKS
"doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake.html"
"CMake Help" "https://cmake.org" "CMake Web Site")
:Mandatory: No
.. variable:: CPACK_INNOSETUP_CREATE_UNINSTALL_LINK
If this option is turned on, a shortcut to the application's uninstaller is
automatically added to the start menu folder.
:Mandatory: Yes
:Default: ``OFF``
.. variable:: CPACK_INNOSETUP_RUN_EXECUTABLES
A :ref:`semicolon-separated list <CMake Language Lists>` of executables being
specified in :variable:`CPACK_PACKAGE_EXECUTABLES` which the user can run
when the installer finishes.
They're internally added to the ``[Run]`` section.
:Mandatory: No
Components Specific Variables
"""""""""""""""""""""""""""""
The generator supports components and also downloaded components. However,
there are some features of components that aren't supported yet (especially
component dependencies). These variables are ignored for now.
CPack will change a component's name in Inno Setup if it has a parent group
for technical reasons. Consider using ``group\component`` as component name in
Inno Setup scripts if you have the component ``component`` and its parent
group ``group``.
Here are some additional variables for components:
.. variable:: CPACK_INNOSETUP_<compName>_INSTALL_DIRECTORY
If you don't want the component ``compName`` to be installed under ``{app}``,
you've to specify its installation directory here.
:Mandatory: No
.. variable:: CPACK_INNOSETUP_VERIFY_DOWNLOADS
This option only affects downloaded components.
If this option is turned on, the hashes of the downloaded archives are
calculated during compile and
download time. The installer will only proceed if they match.
:Mandatory: Yes
:Default: ``ON``
Compilation and Scripting Specific Variables
""""""""""""""""""""""""""""""""""""""""""""
.. variable:: CPACK_INNOSETUP_EXECUTABLE
The filename of the Inno Setup Script Compiler command.
:Mandatory: Yes
:Default: ``ISCC``
.. variable:: CPACK_INNOSETUP_EXECUTABLE_ARGUMENTS
A :ref:`semicolon-separated list <CMake Language Lists>` of extra
command-line options for the Inno Setup Script Compiler command.
For example: ``/Qp;/Smysigntool=$p``
Take care of the `escaping problem <https://cmake.org/cmake/help/book/mastering-cmake/chapter/Packaging%20With%20CPack.html#adding-custom-cpack-options>`_.
:Mandatory: No
.. variable:: CPACK_INNOSETUP_DEFINE_<macro>
This group allows to add custom define directives as command-line options to
the Inno Setup Preprocessor command. Each entry emulates a
``#define public <macro>`` directive. Its macro is accessible from anywhere
(``public``), so it can also be used in extra script files.
Macro names must not contain any special characters. Refer to the Inno Setup
Preprocessor documentation for the detailed rules.
Consider the following example:
.. code-block:: cmake
# The following line emulates: #define public MyMacro "Hello, World!"
set(CPACK_INNOSETUP_DEFINE_MyMacro "Hello, World!")
At this point, you can use ``MyMacro`` anywhere. For example in the following
extra script:
.. code-block::
AppComments={#emit "'My Macro' has the value: " + MyMacro}
Take care of the `escaping problem <https://cmake.org/cmake/help/book/mastering-cmake/chapter/Packaging%20With%20CPack.html#adding-custom-cpack-options>`_.
:Mandatory: No
.. variable:: CPACK_INNOSETUP_EXTRA_SCRIPTS
A :ref:`semicolon-separated list <CMake Language Lists>` of paths to
additional ``.iss`` script files to be processed.
They're internally included at the top of the output script file using a
``#include`` directive.
You can add any section in your file to extend the installer (e.g. adding
additional tasks or registry keys). Prefer using
:variable:`CPACK_INNOSETUP_SETUP_<directive>` when extending the
``[Setup]`` section.
:Mandatory: No
.. variable:: CPACK_INNOSETUP_CODE_FILES
A :ref:`semicolon-separated list <CMake Language Lists>` of paths to
additional Pascal files to be processed.
This variable is actually the same as
:variable:`CPACK_INNOSETUP_EXTRA_SCRIPTS`, except you don't have to
add ``[Code]`` at the top of your file. Never change the current section in
a code file. This will result in undefined behavior! Treat them as normal
Pascal scripts instead.
Code files are included at the very bottom of the output script.
:Mandatory: No

@ -258,7 +258,7 @@ List of CPack NuGet generator specific variables:
.. _nuget.org: https://www.nuget.org .. _nuget.org: https://www.nuget.org
.. _version specification: https://learn.microsoft.com/en-us/nuget/concepts/package-versioning#version-ranges .. _version specification: https://learn.microsoft.com/en-us/nuget/concepts/package-versioning#version-ranges
.. _SPDX license identifier: https://spdx.github.io/spdx-spec/SPDX-license-list .. _SPDX license identifier: https://spdx.org/licenses
.. _SPDX specification: https://spdx.github.io/spdx-spec/SPDX-license-expressions .. _SPDX specification: https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions
.. NuGet spec docs https://docs.microsoft.com/en-us/nuget/reference/nuspec .. NuGet spec docs https://docs.microsoft.com/en-us/nuget/reference/nuspec

@ -111,7 +111,7 @@ Windows using WiX.
simply provide the name of the culture. If you specify more than one simply provide the name of the culture. If you specify more than one
culture identifier in a comma or semicolon delimited list, the first one culture identifier in a comma or semicolon delimited list, the first one
that is found will be used. You can find a list of supported languages at: that is found will be used. You can find a list of supported languages at:
https://wixtoolset.org//documentation/manual/v3/wixui/wixui_localization.html https://wixtoolset.org/docs/v3/wixui/wixui_localization/
.. variable:: CPACK_WIX_TEMPLATE .. variable:: CPACK_WIX_TEMPLATE
@ -319,7 +319,7 @@ Windows using WiX.
for using WiX extensions. Each declaration should be in the form name=url, where for using WiX extensions. Each declaration should be in the form name=url, where
name is the plain namespace without the usual xmlns: prefix and url is an unquoted name is the plain namespace without the usual xmlns: prefix and url is an unquoted
namespace url. A list of commonly known WiX schemata can be found here: namespace url. A list of commonly known WiX schemata can be found here:
https://wixtoolset.org/documentation/manual/v3/xsd/ https://wixtoolset.org/docs/v3/xsd/
.. variable:: CPACK_WIX_SKIP_WIX_UI_EXTENSION .. variable:: CPACK_WIX_SKIP_WIX_UI_EXTENSION

@ -168,25 +168,44 @@ documentation:
See the `cmake-variables(7)`_ manual See the `cmake-variables(7)`_ manual
and the `set()`_ command. and the `set()`_ command.
Documentation objects in the CMake Domain come from two sources. Documentation objects in the CMake Domain come from two sources:
First, the CMake extension to Sphinx transforms every document named
with the form ``Help/<type>/<file-name>.rst`` to a domain object with 1. The CMake extension to Sphinx transforms every document named
type ``<type>``. The object name is extracted from the document title, with the form ``Help/<type>/<file-name>.rst`` to a domain object with
which is expected to be of the form:: type ``<type>``. The object name is extracted from the document title,
which is expected to be of the form::
<object-name> <object-name>
------------- -------------
and to appear at or near the top of the ``.rst`` file before any other and to appear at or near the top of the ``.rst`` file before any other lines
lines starting in a letter, digit, ``<``, or ``$``. If no such title appears starting in a letter, digit, ``<``, or ``$``. If no such title appears
literally in the ``.rst`` file, the object name is the ``<file-name>``. literally in the ``.rst`` file, the object name is the ``<file-name>``.
If a title does appear, it is expected that ``<file-name>`` is equal If a title does appear, it is expected that ``<file-name>`` is equal
to ``<object-name>`` with any ``<`` and ``>`` characters removed, to ``<object-name>`` with any ``<`` and ``>`` characters removed,
or in the case of a ``$<genex-name>`` or ``$<genex-name:...>``, the or in the case of a ``$<genex-name>`` or ``$<genex-name:...>``, the
``genex-name``. ``genex-name``.
2. `CMake Domain directives`_ may be used in documents to explicitly define
some object types:
* `command directive`_
* `envvar directive`_
* `genex directive`_
* `variable directive`_
Object types for which no directive is available must be defined using
the document transform above.
CMake Domain Directives
-----------------------
The CMake Domain provides the following directives.
``command`` directive
^^^^^^^^^^^^^^^^^^^^^
Second, the CMake Domain provides directives to define objects inside Document a "command" object:
other documents:
.. code-block:: rst .. code-block:: rst
@ -194,20 +213,130 @@ other documents:
This indented block documents <command-name>. This indented block documents <command-name>.
The directive requires a single argument, the command name.
``envvar`` directive
^^^^^^^^^^^^^^^^^^^^
Document an "envvar" object:
.. code-block:: rst
.. envvar:: <envvar-name> .. envvar:: <envvar-name>
This indented block documents <envvar-name>. This indented block documents <envvar-name>.
The directive requires a single argument, the environment variable name.
``genex`` directive
^^^^^^^^^^^^^^^^^^^
Document a "genex" object:
.. code-block:: rst
.. genex:: <genex-name> .. genex:: <genex-name>
This indented block documents <genex-name>. This indented block documents <genex-name>.
The directive requires a single argument, the generator expression name.
The optional ``:target:`` option allows a custom target name to be specified.
Because this will affect the ability to reference the "genex" object using the
``:genex:`` role, this option should be used very sparingly.
``signature`` directive
^^^^^^^^^^^^^^^^^^^^^^^
Document `CMake Command Signatures <Style: CMake Command Signatures_>`_
within a ``Help/command/<command-name>.rst`` document.
.. code-block:: rst
.. signature:: <command-name>(<signature>)
This indented block documents one or more signatures of a CMake command.
The ``signature`` directive requires one argument, the signature summary:
* One or more signatures must immediately follow the ``::``.
The first signature may optionally be placed on the same line.
A blank line following the ``signature`` directive will result in a
documentation generation error: ``1 argument(s) required, 0 supplied``.
* Signatures may be split across multiple lines, but the final ``)`` of each
signature must be the last character on its line.
* Blank lines between signatures are not allowed. (Content after a blank line
is treated as part of the description.)
* Whitespace in signatures is not preserved. To document a complex signature,
abbreviate it in the ``signature`` directive argument and specify the full
signature in a ``code-block`` in the description.
The ``signature`` directive generates a hyperlink target for each signature:
* Default target names are automatically extracted from leading "keyword"
arguments in the signatures, where a keyword is any sequence of
non-space starting with a letter. For example, the signature
``string(REGEX REPLACE <match-regex> ...)`` generates the target
``REGEX REPLACE``, similar to ``.. _`REGEX REPLACE`:``.
* Custom target names may be specified using a ``:target:`` option.
For example:
.. code-block:: rst
.. signature::
cmake_path(GET <path-var> ROOT_NAME <out-var>)
cmake_path(GET <path-var> ROOT_PATH <out-var>)
:target:
GET ROOT_NAME
GET ROOT_PATH
Provide a custom target name for each signature, one per line.
The first target may optionally be placed on the same line as ``:target:``.
* If a target name is already in use earlier in the document, no hyperlink
target will be generated.
* The targets may be referenced from within the same document using
```REF`_`` or ```TEXT <REF_>`_`` syntax. Like reStructuredText section
headers, the targets do not work with Sphinx ``:ref:`` syntax, however
they can be globally referenced using e.g. ``:command:`string(APPEND)```.
Although whitespace in the signature is not preserved, by default, line breaks
are suppressed inside of square- or angle-brackets. This behavior can be
controlled using the ``:break:`` option; note, however, that there is no way
to *force* a line break. The default value is 'smart'. Allowable values are:
``all``
Allow line breaks at any whitespace.
``smart`` (default)
Allow line breaks at whitespace, except between matched square- or
angle-brackets. For example, if a signature contains the text
``<input>... [OUTPUT_VARIABLE <out-var>]``, a line break would be allowed
after ``<input>...`` but not between ``OUTPUT_VARIABLE`` and ``<out-var>``.
``verbatim``
Allow line breaks only where the source document contains a newline.
The directive treats its content as the documentation of the signature(s).
Indent the signature documentation accordingly.
``variable`` directive
^^^^^^^^^^^^^^^^^^^^^^
Document a "variable" object:
.. code-block:: rst
.. variable:: <variable-name> .. variable:: <variable-name>
This indented block documents <variable-name>. This indented block documents <variable-name>.
Object types for which no directive is available must be defined using The directive requires a single argument, the variable name.
the first approach above.
.. _`Sphinx Domain`: http://sphinx-doc.org/domains.html .. _`Sphinx Domain`: http://sphinx-doc.org/domains.html
.. _`cmake(1)`: https://cmake.org/cmake/help/latest/manual/cmake.1.html .. _`cmake(1)`: https://cmake.org/cmake/help/latest/manual/cmake.1.html
@ -266,6 +395,10 @@ object names like ``OUTPUT_NAME_<CONFIG>``. The form ``a <b>``,
with a space preceding ``<``, is still interpreted as a link text with a space preceding ``<``, is still interpreted as a link text
with an explicit target. with an explicit target.
Additionally, the ``cref`` role may be used to create references
to local targets that have literal styling. This is especially
useful for referencing a subcommand in the command's documentation.
.. _`list()`: https://cmake.org/cmake/help/latest/command/list.html .. _`list()`: https://cmake.org/cmake/help/latest/command/list.html
.. _`list(APPEND)`: https://cmake.org/cmake/help/latest/command/list.html .. _`list(APPEND)`: https://cmake.org/cmake/help/latest/command/list.html
.. _`list(APPEND) sub-command`: https://cmake.org/cmake/help/latest/command/list.html .. _`list(APPEND) sub-command`: https://cmake.org/cmake/help/latest/command/list.html
@ -329,11 +462,11 @@ paragraph.
Style: CMake Command Signatures Style: CMake Command Signatures
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Command signatures should be marked up as plain literal blocks, not as A ``Help/command/<command-name>.rst`` document defines one ``command``
cmake ``code-blocks``. object in the `CMake Domain`_, but some commands have multiple signatures.
Use the CMake Domain's `signature directive`_ to document each signature.
Signatures are separated from preceding content by a section header. Separate signatures from preceding content by a section header.
That is, use: For example:
.. code-block:: rst .. code-block:: rst
@ -342,17 +475,23 @@ That is, use:
Normal Libraries Normal Libraries
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
:: .. signature::
add_library(<lib> ...) add_library(<lib> ...)
This signature is used for ... This signature is used for ...
Signatures of commands should wrap optional parts with square brackets, Use the following conventions in command signature documentation:
and should mark list of optional arguments with an ellipsis (``...``).
Elements of the signature which are specified by the user should be * Use an angle-bracket ``<placeholder>`` for arguments to be specified
specified with angle brackets, and may be referred to in prose using by the caller. Refer to them in prose using
``inline-literal`` syntax. `inline literal <Style: Inline Literals_>`_ syntax.
* Wrap optional parts with square brackets.
* Mark repeatable parts with a trailing ellipsis (``...``).
The ``signature`` directive may be used multiple times for different
signatures of the same command.
Style: Boolean Constants Style: Boolean Constants
^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^

@ -18,7 +18,7 @@ C++20 Module APIs
================= =================
Variable: ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API`` Variable: ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
Value: ``2182bf5c-ef0d-489a-91da-49dbc3090d2a`` Value: ``aa1f7df0-828a-4fcd-9afc-2dc80491aca7``
In order to support C++20 modules, there are a number of behaviors that have In order to support C++20 modules, there are a number of behaviors that have
CMake APIs to provide the required features to build and export them from a CMake APIs to provide the required features to build and export them from a
@ -63,12 +63,6 @@ dependencies, set the following variables:
``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API`` ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
Set this to the UUID documented above. Set this to the UUID documented above.
``CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP``
Set this to ``1`` in order to activate this undocumented experimental
infrastructure. This is **intended to make the functionality available
to compiler writers** so they can use it to develop and test their
dependency scanning tool.
Some compilers already have support for module dependency scanning: Some compilers already have support for module dependency scanning:
* MSVC 19.34 and newer (provided with Visual Studio 17.4 and newer) * MSVC 19.34 and newer (provided with Visual Studio 17.4 and newer)
@ -92,7 +86,6 @@ For example, add code like the following to a test project:
.. code-block:: cmake .. code-block:: cmake
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
string(CONCAT CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE string(CONCAT CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE
"<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> <SOURCE>" "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> <SOURCE>"
" -MT <DYNDEP_FILE> -MD -MF <DEP_FILE>" " -MT <DYNDEP_FILE> -MD -MF <DEP_FILE>"

@ -0,0 +1,14 @@
CMAKE_APPBUNDLE_PATH
--------------------
.. include:: ENV_VAR.txt
The ``CMAKE_APPBUNDLE_PATH`` environment variable may be set to a list of
directories to be searched for macOS application bundles
by the :command:`find_program` and :command:`find_package` commands.
This variable may hold a single directory or a list of directories separated
by ``:`` on UNIX or ``;`` on Windows (the same as the ``PATH`` environment
variable convention on those platforms).
See also the :variable:`CMAKE_APPBUNDLE_PATH` CMake variable.

@ -0,0 +1,15 @@
CMAKE_FRAMEWORK_PATH
--------------------
.. include:: ENV_VAR.txt
The ``CMAKE_FRAMEWORK_PATH`` environment variable may be set to a list of
directories to be searched for macOS frameworks by the :command:`find_library`,
:command:`find_package`, :command:`find_path` and :command:`find_file` commands.
This variable may hold a single directory or a list of directories separated
by ``:`` on UNIX or ``;`` on Windows (the same as the ``PATH`` environment
variable convention on those platforms).
See also the :variable:`CMAKE_FRAMEWORK_PATH` CMake variable.

@ -0,0 +1,13 @@
CMAKE_INCLUDE_PATH
------------------
.. include:: ENV_VAR.txt
The ``CMAKE_INCLUDE_PATH`` environment variable may be set to a list of
directories to be searched by the :command:`find_file` and :command:`find_path` commands.
This variable may hold a single directory or a list of directories separated
by ``:`` on UNIX or ``;`` on Windows (the same as the ``PATH`` environment
variable convention on those platforms).
See also the :variable:`CMAKE_INCLUDE_PATH` CMake variable.

@ -0,0 +1,13 @@
CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES_EXCLUDE
----------------------------------------------
.. versionadded:: 3.27
.. include:: ENV_VAR.txt
A :ref:`semicolon-separated list <CMake Language Lists>` of directories
to exclude from the :variable:`CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES`
variable when it is automatically detected from the ``<LANG>`` compiler.
This may be used to work around misconfigured compiler drivers that pass
extraneous implicit link directories to their linker.

@ -0,0 +1,13 @@
CMAKE_LIBRARY_PATH
------------------
.. include:: ENV_VAR.txt
The ``CMAKE_LIBRARY_PATH`` environment variable may be set to a list of
directories to be searched by the :command:`find_library` command.
This variable may hold a single directory or a list of directories separated
by ``:`` on UNIX or ``;`` on Windows (the same as the ``PATH`` environment
variable convention on those platforms).
See also the :variable:`CMAKE_LIBRARY_PATH` CMake variable.

@ -0,0 +1,10 @@
CMAKE_MAXIMUM_RECURSION_DEPTH
-----------------------------
.. versionadded:: 3.27
.. include:: ENV_VAR.txt
Maximum recursion depth for CMake scripts. This environment variable is
used if the :variable:`CMAKE_MAXIMUM_RECURSION_DEPTH` variable is not set.
See that variable's documentation for details.

@ -0,0 +1,13 @@
CMAKE_PROGRAM_PATH
------------------
.. include:: ENV_VAR.txt
The ``CMAKE_PROGRAM_PATH`` environment variable may be set to a list of
directories to be searched by the :command:`find_program` command.
This variable may hold a single directory or a list of directories separated
by ``:`` on UNIX or ``;`` on Windows (the same as the ``PATH`` environment
variable convention on those platforms).
See also the :variable:`CMAKE_PROGRAM_PATH` CMake variable.

@ -17,3 +17,17 @@ by ``:`` on UNIX or ``;`` on Windows (the same as the ``PATH`` environment
variable convention on those platforms). variable convention on those platforms).
See also the :variable:`<PackageName>_ROOT` CMake variable. See also the :variable:`<PackageName>_ROOT` CMake variable.
.. envvar:: <PACKAGENAME>_ROOT
.. versionadded:: 3.27
Calls to :command:`find_package(<PackageName>)` will also search in
prefixes specified by the upper-case ``<PACKAGENAME>_ROOT`` environment
variable. See policy :policy:`CMP0144`.
.. note::
Note that the ``<PackageName>_ROOT`` and ``<PACKAGENAME>_ROOT``
environment variables are distinct only on platforms that have
case-sensitive environments.

@ -1,6 +1,12 @@
CodeBlocks CodeBlocks
---------- ----------
.. deprecated:: 3.27
Support for :ref:`Extra Generators` is deprecated and will be removed from
a future version of CMake. IDEs may use the :manual:`cmake-file-api(7)`
to view CMake-generated project build trees.
Generates CodeBlocks project files. Generates CodeBlocks project files.
Project files for CodeBlocks will be created in the top directory and Project files for CodeBlocks will be created in the top directory and

@ -1,6 +1,12 @@
CodeLite CodeLite
---------- ----------
.. deprecated:: 3.27
Support for :ref:`Extra Generators` is deprecated and will be removed from
a future version of CMake. IDEs may use the :manual:`cmake-file-api(7)`
to view CMake-generated project build trees.
Generates CodeLite project files. Generates CodeLite project files.
Project files for CodeLite will be created in the top directory and Project files for CodeLite will be created in the top directory and

@ -1,6 +1,12 @@
Eclipse CDT4 Eclipse CDT4
------------ ------------
.. deprecated:: 3.27
Support for :ref:`Extra Generators` is deprecated and will be removed from
a future version of CMake. IDEs may use the :manual:`cmake-file-api(7)`
to view CMake-generated project build trees.
Generates Eclipse CDT 4.0 project files. Generates Eclipse CDT 4.0 project files.
Project files for Eclipse will be created in the top directory. In Project files for Eclipse will be created in the top directory. In

@ -1,6 +1,12 @@
Kate Kate
---- ----
.. deprecated:: 3.27
Support for :ref:`Extra Generators` is deprecated and will be removed from
a future version of CMake. IDEs may use the :manual:`cmake-file-api(7)`
to view CMake-generated project build trees.
Generates Kate project files. Generates Kate project files.
A project file for Kate will be created in the top directory in the top level A project file for Kate will be created in the top directory in the top level
@ -22,5 +28,8 @@ This "extra" generator may be specified as:
``Kate - Ninja`` ``Kate - Ninja``
Generate with :generator:`Ninja`. Generate with :generator:`Ninja`.
``Kate - Ninja Multi-Config``
Generate with :generator:`Ninja Multi-Config`.
``Kate - Unix Makefiles`` ``Kate - Unix Makefiles``
Generate with :generator:`Unix Makefiles`. Generate with :generator:`Unix Makefiles`.

@ -1,6 +1,12 @@
Sublime Text 2 Sublime Text 2
-------------- --------------
.. deprecated:: 3.27
Support for :ref:`Extra Generators` is deprecated and will be removed from
a future version of CMake. IDEs may use the :manual:`cmake-file-api(7)`
to view CMake-generated project build trees.
Generates Sublime Text 2 project files. Generates Sublime Text 2 project files.
Project files for Sublime Text 2 will be created in the top directory Project files for Sublime Text 2 will be created in the top directory

@ -1,7 +1,15 @@
Visual Studio 9 2008 Visual Studio 9 2008
-------------------- --------------------
Generates Visual Studio 9 2008 project files. Deprecated. Generates Visual Studio 9 2008 project files.
.. note::
This generator is deprecated and will be removed in a future version
of CMake. It will still be possible to build with VS 9 2008 tools
using the :generator:`Visual Studio 12 2013` generator (or above,
and with VS 10 2010 also installed) with
:variable:`CMAKE_GENERATOR_TOOLSET` set to ``v90``,
or by using the :generator:`NMake Makefiles` generator.
Platform Selection Platform Selection
^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^

@ -145,7 +145,7 @@ The following IDEs support CMake natively:
* `VSCode`_ (via a plugin) * `VSCode`_ (via a plugin)
.. _CLion: https://www.jetbrains.com/clion/ .. _CLion: https://www.jetbrains.com/clion/
.. _KDevelop: https://www.kdevelop.org/ .. _KDevelop: https://kdevelop.org/
.. _QtCreator: https://www.qt.io/product/development-tools .. _QtCreator: https://www.qt.io/product/development-tools
.. _Vim: https://www.vim.org/ .. _Vim: https://www.vim.org/
.. _Visual Studio: https://visualstudio.microsoft.com/ .. _Visual Studio: https://visualstudio.microsoft.com/

@ -285,9 +285,9 @@ command.
:end-before: # include CMakePackageConfigHelpers macro :end-before: # include CMakePackageConfigHelpers macro
This command generates the ``MathFunctionsTargets.cmake`` file and arranges This command generates the ``MathFunctionsTargets.cmake`` file and arranges
to install it to ``lib/cmake``. The file contains code suitable for to install it to ``${CMAKE_INSTALL_LIBDIR}/cmake/MathFunctions``. The file
use by downstreams to import all targets listed in the install command from contains code suitable for use by downstreams to import all targets listed in
the installation tree. the install command from the installation tree.
The ``NAMESPACE`` option will prepend ``MathFunctions::`` to the target names The ``NAMESPACE`` option will prepend ``MathFunctions::`` to the target names
as they are written to the export file. This convention of double-colons as they are written to the export file. This convention of double-colons
@ -317,7 +317,8 @@ were built in its own tree. For example:
.. code-block:: cmake .. code-block:: cmake
:linenos: :linenos:
include(${INSTALL_PREFIX}/lib/cmake/MathFunctionTargets.cmake) include(GNUInstallDirs)
include(${INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/MathFunctions/MathFunctionTargets.cmake)
add_executable(myexe src1.c src2.c ) add_executable(myexe src1.c src2.c )
target_link_libraries(myexe PRIVATE MathFunctions::MathFunctions) target_link_libraries(myexe PRIVATE MathFunctions::MathFunctions)

@ -160,7 +160,7 @@ The last command to call for a basic project is
:name: CMakeLists.txt-add_executable :name: CMakeLists.txt-add_executable
:language: cmake :language: cmake
:start-after: # add the executable :start-after: # add the executable
:end-before: # TODO 9: :end-before: # TODO 3:
.. raw:: html .. raw:: html
@ -240,7 +240,7 @@ the following:
:name: tutorial.cxx-cxx11 :name: tutorial.cxx-cxx11
:language: c++ :language: c++
:start-after: // convert input to double :start-after: // convert input to double
:end-before: // TODO 12: :end-before: // TODO 6:
.. raw:: html .. raw:: html
@ -265,7 +265,7 @@ add the :variable:`CMAKE_CXX_STANDARD` declarations above the call to
:name: CMakeLists.txt-CXX_STANDARD :name: CMakeLists.txt-CXX_STANDARD
:language: cmake :language: cmake
:start-after: # specify the C++ standard :start-after: # specify the C++ standard
:end-before: # TODO 7: :end-before: # configure a header file
.. raw:: html .. raw:: html
@ -375,7 +375,7 @@ specified CMake variables replaced:
:name: CMakeLists.txt-configure_file :name: CMakeLists.txt-configure_file
:language: cmake :language: cmake
:start-after: # to the source code :start-after: # to the source code
:end-before: # TODO 8: :end-before: # TODO 2:
.. raw:: html .. raw:: html
@ -420,7 +420,6 @@ be replaced with the corresponding version numbers from the project in
:caption: TODO 10: TutorialConfig.h.in :caption: TODO 10: TutorialConfig.h.in
:name: TutorialConfig.h.in :name: TutorialConfig.h.in
:language: c++ :language: c++
:end-before: // TODO 13:
.. raw:: html .. raw:: html

@ -27,149 +27,7 @@ expressions are the ``0`` and ``1`` expressions. A ``$<0:...>`` results in the
empty string, and ``<1:...>`` results in the content of ``...``. They can also empty string, and ``<1:...>`` results in the content of ``...``. They can also
be nested. be nested.
Exercise 1 - Setting the C++ Standard with Interface Libraries Exercise 1 - Adding Compiler Warning Flags with Generator Expressions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Before we use :manual:`generator expressions <cmake-generator-expressions(7)>`
let's refactor our existing code to use an ``INTERFACE`` library. We will
use that library in the next step to demonstrate a common use for
:manual:`generator expressions <cmake-generator-expressions(7)>`.
Goal
----
Add an ``INTERFACE`` library target to specify the required C++ standard.
Helpful Resources
-----------------
* :command:`add_library`
* :command:`target_compile_features`
* :command:`target_link_libraries`
Files to Edit
-------------
* ``CMakeLists.txt``
* ``MathFunctions/CMakeLists.txt``
Getting Started
---------------
In this exercise, we will refactor our code to use an ``INTERFACE`` library to
specify the C++ standard.
The starting source code is provided in the ``Step4`` directory. In this
exercise, complete ``TODO 1`` through ``TODO 3``.
Start by editing the top level ``CMakeLists.txt`` file. Construct an
``INTERFACE`` library target called ``tutorial_compiler_flags`` and
specify ``cxx_std_11`` as a target compiler feature.
Modify ``CMakeLists.txt`` and ``MathFunctions/CMakeLists.txt`` so that all
targets have a :command:`target_link_libraries` call to
``tutorial_compiler_flags``.
Build and Run
-------------
Make a new directory called ``Step4_build``, run the :manual:`cmake <cmake(1)>`
executable or the :manual:`cmake-gui <cmake-gui(1)>` to configure the project
and then build it with your chosen build tool or by using ``cmake --build .``
from the build directory.
Here's a refresher of what that looks like from the command line:
.. code-block:: console
mkdir Step4_build
cd Step4_build
cmake ../Step4
cmake --build .
Next, use the newly built ``Tutorial`` and verify that it is working as
expected.
Solution
--------
Let's update our code from the previous step to use interface libraries
to set our C++ requirements.
To start, we need to remove the two :command:`set` calls on the variables
:variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_STANDARD_REQUIRED`.
The specific lines to remove are as follows:
.. literalinclude:: Step4/CMakeLists.txt
:caption: CMakeLists.txt
:name: CMakeLists.txt-CXX_STANDARD-variable-remove
:language: cmake
:start-after: # specify the C++ standard
:end-before: # TODO 5: Create helper variables
Next, we need to create an interface library, ``tutorial_compiler_flags``. And
then use :command:`target_compile_features` to add the compiler feature
``cxx_std_11``.
.. raw:: html
<details><summary>TODO 1: Click to show/hide answer</summary>
.. literalinclude:: Step5/CMakeLists.txt
:caption: TODO 1: CMakeLists.txt
:name: CMakeLists.txt-cxx_std-feature
:language: cmake
:start-after: # specify the C++ standard
:end-before: # add compiler warning flags just
.. raw:: html
</details>
Finally, with our interface library set up, we need to link our
executable ``Target`` and our ``MathFunctions`` library to our new
``tutorial_compiler_flags`` library. Respectively, the code will look like
this:
.. raw:: html
<details><summary>TODO 2: Click to show/hide answer</summary>
.. literalinclude:: Step5/CMakeLists.txt
:caption: TODO 2: CMakeLists.txt
:name: CMakeLists.txt-target_link_libraries-step4
:language: cmake
:start-after: add_executable(Tutorial tutorial.cxx)
:end-before: # add the binary tree to the search path for include file
.. raw:: html
</details>
and this:
.. raw:: html
<details><summary>TODO 3: Click to show/hide answer</summary>
.. literalinclude:: Step5/MathFunctions/CMakeLists.txt
:caption: TODO 3: MathFunctions/CMakeLists.txt
:name: MathFunctions-CMakeLists.txt-target_link_libraries-step4
:language: cmake
:start-after: # link our compiler flags interface library
:end-before: # TODO 1
.. raw:: html
</details>
With this, all of our code still requires C++ 11 to build. Notice
though that with this method, it gives us the ability to be specific about
which targets get specific requirements. In addition, we create a single
source of truth in our interface library.
Exercise 2 - Adding Compiler Warning Flags with Generator Expressions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A common usage of A common usage of
@ -199,8 +57,8 @@ Files to Edit
Getting Started Getting Started
--------------- ---------------
Start with the resulting files from Exercise 1. Complete ``TODO 4`` through Open the file ``Step4/CMakeLists.txt`` and complete ``TODO 1`` through
``TODO 7``. ``TODO 4``.
First, in the top level ``CMakeLists.txt`` file, we need to set the First, in the top level ``CMakeLists.txt`` file, we need to set the
:command:`cmake_minimum_required` to ``3.15``. In this exercise we are going :command:`cmake_minimum_required` to ``3.15``. In this exercise we are going
@ -214,12 +72,16 @@ given a language and a set of compiler ids.
Build and Run Build and Run
------------- -------------
Since we have our build directory already configured from Exercise 1, simply Make a new directory called ``Step4_build``, run the :manual:`cmake <cmake(1)>`
rebuild our code by calling the following: executable or the :manual:`cmake-gui <cmake-gui(1)>` to configure the project
and then build it with your chosen build tool or by using ``cmake --build .``
from the build directory.
.. code-block:: console .. code-block:: console
mkdir Step4_build
cd Step4_build cd Step4_build
cmake ../Step4
cmake --build . cmake --build .
Solution Solution
@ -230,10 +92,10 @@ version ``3.15``:
.. raw:: html .. raw:: html
<details><summary>TODO 4: Click to show/hide answer</summary> <details><summary>TODO 1: Click to show/hide answer</summary>
.. literalinclude:: Step5/CMakeLists.txt .. literalinclude:: Step5/CMakeLists.txt
:caption: TODO 4: CMakeLists.txt :caption: TODO 1: CMakeLists.txt
:name: MathFunctions-CMakeLists.txt-minimum-required-step4 :name: MathFunctions-CMakeLists.txt-minimum-required-step4
:language: cmake :language: cmake
:end-before: # set the project name and version :end-before: # set the project name and version
@ -249,10 +111,10 @@ variables ``gcc_like_cxx`` and ``msvc_cxx`` as follows:
.. raw:: html .. raw:: html
<details><summary>TODO 5: Click to show/hide answer</summary> <details><summary>TODO 2: Click to show/hide answer</summary>
.. literalinclude:: Step5/CMakeLists.txt .. literalinclude:: Step5/CMakeLists.txt
:caption: TODO 5: CMakeLists.txt :caption: TODO 2: CMakeLists.txt
:name: CMakeLists.txt-compile_lang_and_id :name: CMakeLists.txt-compile_lang_and_id
:language: cmake :language: cmake
:start-after: # the BUILD_INTERFACE genex :start-after: # the BUILD_INTERFACE genex
@ -270,10 +132,10 @@ interface library.
.. raw:: html .. raw:: html
<details><summary>TODO 6: Click to show/hide answer</summary> <details><summary>TODO 3: Click to show/hide answer</summary>
.. code-block:: cmake .. code-block:: cmake
:caption: TODO 6: CMakeLists.txt :caption: TODO 3: CMakeLists.txt
:name: CMakeLists.txt-compile_flags :name: CMakeLists.txt-compile_flags
target_compile_options(tutorial_compiler_flags INTERFACE target_compile_options(tutorial_compiler_flags INTERFACE
@ -292,14 +154,14 @@ condition. The resulting full code looks like the following:
.. raw:: html .. raw:: html
<details><summary>TODO 7: Click to show/hide answer</summary> <details><summary>TODO 4: Click to show/hide answer</summary>
.. literalinclude:: Step5/CMakeLists.txt .. literalinclude:: Step5/CMakeLists.txt
:caption: TODO 7: CMakeLists.txt :caption: TODO 4: CMakeLists.txt
:name: CMakeLists.txt-target_compile_options-genex :name: CMakeLists.txt-target_compile_options-genex
:language: cmake :language: cmake
:start-after: set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>") :start-after: set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
:end-before: # should we use our own math functions :end-before: # configure a header file to pass some of the CMake settings
.. raw:: html .. raw:: html

@ -119,7 +119,7 @@ our source code can tell what resources are available. If both ``log`` and
:name: MathFunctions/CMakeLists.txt-target_compile_definitions :name: MathFunctions/CMakeLists.txt-target_compile_definitions
:language: cmake :language: cmake
:start-after: # add compile definitions :start-after: # add compile definitions
:end-before: # install libs :end-before: # state
.. raw:: html .. raw:: html
@ -136,7 +136,8 @@ Since we may be using ``log`` and ``exp``, we need to modify
:caption: TODO 4: MathFunctions/mysqrt.cxx :caption: TODO 4: MathFunctions/mysqrt.cxx
:name: MathFunctions/mysqrt.cxx-include-cmath :name: MathFunctions/mysqrt.cxx-include-cmath
:language: c++ :language: c++
:end-before: #include <iostream> :start-after: #include "mysqrt.h"
:end-before: include <iostream>
.. raw:: html .. raw:: html
@ -155,7 +156,7 @@ compute the square root in the ``mysqrt`` function. The ``mysqrt`` function in
:name: MathFunctions/mysqrt.cxx-ifdef :name: MathFunctions/mysqrt.cxx-ifdef
:language: c++ :language: c++
:start-after: // if we have both log and exp then use them :start-after: // if we have both log and exp then use them
:end-before: // do ten iterations :end-before: return result;
.. raw:: html .. raw:: html

@ -100,7 +100,7 @@ follows:
:name: MathFunctions/CMakeLists.txt-target_include_directories-INTERFACE :name: MathFunctions/CMakeLists.txt-target_include_directories-INTERFACE
:language: cmake :language: cmake
:start-after: # to find MathFunctions.h :start-after: # to find MathFunctions.h
:end-before: # TODO 3: Link to :end-before: # should we use our own
.. raw:: html .. raw:: html
@ -108,24 +108,26 @@ follows:
Now that we've specified usage requirements for ``MathFunctions`` we can Now that we've specified usage requirements for ``MathFunctions`` we can
safely remove our uses of the ``EXTRA_INCLUDES`` variable from the top-level safely remove our uses of the ``EXTRA_INCLUDES`` variable from the top-level
``CMakeLists.txt``, here: ``CMakeLists.txt``.
Remove this line:
.. raw:: html .. raw:: html
<details><summary>TODO 2: Click to show/hide answer</summary> <details><summary>TODO 2: Click to show/hide answer</summary>
.. literalinclude:: Step4/CMakeLists.txt .. literalinclude:: Step3/CMakeLists.txt
:caption: TODO 2: CMakeLists.txt :caption: TODO 2: CMakeLists.txt
:name: CMakeLists.txt-remove-EXTRA_INCLUDES :name: CMakeLists.txt-remove-EXTRA_INCLUDES
:language: cmake :language: cmake
:start-after: # add the MathFunctions library :start-after: add_subdirectory(MathFunctions)
:end-before: # add the executable :end-before: # add the executable
.. raw:: html .. raw:: html
</details> </details>
And here: And the lines:
.. raw:: html .. raw:: html
@ -141,7 +143,181 @@ And here:
</details> </details>
The remaining code looks like:
.. raw:: html
<details><summary>Click to show/hide the resulting code</summary>
.. literalinclude:: Step4/CMakeLists.txt
:caption: Remaining code after removing EXTRA_INCLUDES
:name: CMakeLists.txt-after-removing-EXTRA_INCLUDES
:language: cmake
:start-after: add_subdirectory(MathFunctions)
.. raw:: html
</details>
Notice that with this technique, the only thing our executable target does to Notice that with this technique, the only thing our executable target does to
use our library is call :command:`target_link_libraries` with the name use our library is call :command:`target_link_libraries` with the name
of the library target. In larger projects, the classic method of specifying of the library target. In larger projects, the classic method of specifying
library dependencies manually becomes very complicated very quickly. library dependencies manually becomes very complicated very quickly.
Exercise 2 - Setting the C++ Standard with Interface Libraries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Now that we have switched our code to a more modern approach, let's demonstrate
a modern technique to set properties to multiple targets.
Let's refactor our existing code to use an ``INTERFACE`` library. We will
use that library in the next step to demonstrate a common use for
:manual:`generator expressions <cmake-generator-expressions(7)>`.
Goal
----
Add an ``INTERFACE`` library target to specify the required C++ standard.
Helpful Resources
-----------------
* :command:`add_library`
* :command:`target_compile_features`
* :command:`target_link_libraries`
Files to Edit
-------------
* ``CMakeLists.txt``
* ``MathFunctions/CMakeLists.txt``
Getting Started
---------------
In this exercise, we will refactor our code to use an ``INTERFACE`` library to
specify the C++ standard.
Start this exercise from what we left at the end of Step3 exercise 1. You will
have to complete ``TODO 4`` through ``TODO 7``.
Start by editing the top level ``CMakeLists.txt`` file. Construct an
``INTERFACE`` library target called ``tutorial_compiler_flags`` and
specify ``cxx_std_11`` as a target compiler feature.
Modify ``CMakeLists.txt`` and ``MathFunctions/CMakeLists.txt`` so that all
targets have a :command:`target_link_libraries` call to
``tutorial_compiler_flags``.
Build and Run
-------------
Since we have our build directory already configured from Exercise 1, simply
rebuild our code by calling the following:
.. code-block:: console
cd Step3_build
cmake --build .
Next, use the newly built ``Tutorial`` and verify that it is working as
expected.
Solution
--------
Let's update our code from the previous step to use interface libraries
to set our C++ requirements.
To start, we need to remove the two :command:`set` calls on the variables
:variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_STANDARD_REQUIRED`.
The specific lines to remove are as follows:
.. literalinclude:: Step3/CMakeLists.txt
:caption: CMakeLists.txt
:name: CMakeLists.txt-CXX_STANDARD-variable-remove
:language: cmake
:start-after: # specify the C++ standard
:end-before: # configure a header file
Next, we need to create an interface library, ``tutorial_compiler_flags``. And
then use :command:`target_compile_features` to add the compiler feature
``cxx_std_11``.
.. raw:: html
<details><summary>TODO 4: Click to show/hide answer</summary>
.. literalinclude:: Step4/CMakeLists.txt
:caption: TODO 4: CMakeLists.txt
:name: CMakeLists.txt-cxx_std-feature
:language: cmake
:start-after: # specify the C++ standard
:end-before: # TODO 2: Create helper
.. raw:: html
</details>
Finally, with our interface library set up, we need to link our
executable ``Target``, our ``MathFunctions`` library, and our ``SqrtLibrary``
library to our new
``tutorial_compiler_flags`` library. Respectively, the code will look like
this:
.. raw:: html
<details><summary>TODO 5: Click to show/hide answer</summary>
.. literalinclude:: Step4/CMakeLists.txt
:caption: TODO 5: CMakeLists.txt
:name: CMakeLists.txt-target_link_libraries-step4
:language: cmake
:start-after: add_executable(Tutorial tutorial.cxx)
:end-before: # add the binary tree to the search path for include file
.. raw:: html
</details>
this:
.. raw:: html
<details><summary>TODO 6: Click to show/hide answer</summary>
.. literalinclude:: Step4/MathFunctions/CMakeLists.txt
:caption: TODO 6: MathFunctions/CMakeLists.txt
:name: MathFunctions-CMakeLists.txt-target_link_libraries-step4
:language: cmake
:start-after: # link our compiler flags interface library
:end-before: target_link_libraries(MathFunctions
.. raw:: html
</details>
and this:
.. raw:: html
<details><summary>TODO 7: Click to show/hide answer</summary>
.. literalinclude:: Step4/MathFunctions/CMakeLists.txt
:caption: TODO 7: MathFunctions/CMakeLists.txt
:name: MathFunctions-SqrtLibrary-target_link_libraries-step4
:language: cmake
:start-after: target_link_libraries(SqrtLibrary
:end-before: endif()
.. raw:: html
</details>
With this, all of our code still requires C++ 11 to build. Notice
though that with this method, it gives us the ability to be specific about
which targets get specific requirements. In addition, we create a single
source of truth in our interface library.

@ -18,41 +18,49 @@ In the ``MathFunctions`` subdirectory, a new source file named
After reviewing the file, we can see that the table is produced as valid C++ After reviewing the file, we can see that the table is produced as valid C++
code and that the output filename is passed in as an argument. code and that the output filename is passed in as an argument.
The next step is to add the appropriate commands to the The next step is to create ``MathFunctions/MakeTable.cmake``. Then, add the
``MathFunctions/CMakeLists.txt`` file to build the MakeTable executable and appropriate commands to the file to build the ``MakeTable`` executable and
then run it as part of the build process. A few commands are needed to then run it as part of the build process. A few commands are needed to
accomplish this. accomplish this.
First, at the top of ``MathFunctions/CMakeLists.txt``, the executable for First, we add an executable for ``MakeTable``.
``MakeTable`` is added as any other executable would be added.
.. literalinclude:: Step9/MathFunctions/CMakeLists.txt .. literalinclude:: Step9/MathFunctions/MakeTable.cmake
:caption: MathFunctions/CMakeLists.txt :caption: MathFunctions/MakeTable.cmake
:name: MathFunctions/CMakeLists.txt-add_executable-MakeTable :name: MathFunctions/MakeTable.cmake-add_executable-MakeTable
:language: cmake :language: cmake
:start-after: # first we add the executable that generates the table :start-after: # first we add the executable that generates the table
:end-before: # add the command to generate the source code :end-before: target_link_libraries
After creating the executable, we add the ``tutorial_compiler_flags`` to our
executable using :command:`target_link_libraries`.
.. literalinclude:: Step9/MathFunctions/MakeTable.cmake
:caption: MathFunctions/MakeTable.cmake
:name: MathFunctions/MakeTable.cmake-link-tutorial-compiler-flags
:language: cmake
:start-after: add_executable
:end-before: # add the command to generate
Then we add a custom command that specifies how to produce ``Table.h`` Then we add a custom command that specifies how to produce ``Table.h``
by running MakeTable. by running MakeTable.
.. literalinclude:: Step9/MathFunctions/CMakeLists.txt .. literalinclude:: Step9/MathFunctions/MakeTable.cmake
:caption: MathFunctions/CMakeLists.txt :caption: MathFunctions/MakeTable.cmake
:name: MathFunctions/CMakeLists.txt-add_custom_command-Table.h :name: MathFunctions/MakeTable.cmake-add_custom_command-Table.h
:language: cmake :language: cmake
:start-after: # add the command to generate the source code :start-after: # add the command to generate the source code
:end-before: # add the main library
Next we have to let CMake know that ``mysqrt.cxx`` depends on the generated Next we have to let CMake know that ``mysqrt.cxx`` depends on the generated
file ``Table.h``. This is done by adding the generated ``Table.h`` to the list file ``Table.h``. This is done by adding the generated ``Table.h`` to the list
of sources for the library MathFunctions. of sources for the library ``SqrtLibrary``.
.. literalinclude:: Step9/MathFunctions/CMakeLists.txt .. literalinclude:: Step9/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt :caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_library-Table.h :name: MathFunctions/CMakeLists.txt-add_library-Table.h
:language: cmake :language: cmake
:start-after: # add the main library :start-after: # library that just does sqrt
:end-before: # state that anybody linking :end-before: # state that we depend on
We also have to add the current binary directory to the list of include We also have to add the current binary directory to the list of include
directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``. directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``.
@ -62,7 +70,17 @@ directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``.
:name: MathFunctions/CMakeLists.txt-target_include_directories-Table.h :name: MathFunctions/CMakeLists.txt-target_include_directories-Table.h
:language: cmake :language: cmake
:start-after: # state that we depend on our bin :start-after: # state that we depend on our bin
:end-before: # install libs :end-before: target_link_libraries
As the last step, we need to include
``MakeTable.cmake`` at the top of the ``MathFunctions/CMakeLists.txt``.
.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-include-MakeTable.cmake
:language: cmake
:start-after: # generate Table.h
:end-before: # library that just does sqrt
Now let's use the generated table. First, modify ``mysqrt.cxx`` to include Now let's use the generated table. First, modify ``mysqrt.cxx`` to include
``Table.h``. Next, we can rewrite the ``mysqrt`` function to use the table: ``Table.h``. Next, we can rewrite the ``mysqrt`` function to use the table:

@ -51,11 +51,13 @@ then use this library instead of the standard square root function provided by
the compiler. the compiler.
For this tutorial we will put the library into a subdirectory called For this tutorial we will put the library into a subdirectory called
``MathFunctions``. This directory already contains a header file, ``MathFunctions``. This directory already contains the header files
``MathFunctions.h``, and a source file ``mysqrt.cxx``. We will not need to ``MathFunctions.h`` and ``mysqrt.h``. Their respective source files
modify either of these files. The source file has one function called ``MathFunctions.cxx`` and ``mysqrt.cxx`` are also provided. We will not need
to modify any of these files. ``mysqrt.cxx`` has one function called
``mysqrt`` that provides similar functionality to the compiler's ``sqrt`` ``mysqrt`` that provides similar functionality to the compiler's ``sqrt``
function. function. ``MathFunctions.cxx`` contains one function ``sqrt`` which serves
to hide the implementation details of ``sqrt``.
From the ``Help/guide/tutorial/Step2`` directory, start with ``TODO 1`` and From the ``Help/guide/tutorial/Step2`` directory, start with ``TODO 1`` and
complete through ``TODO 6``. complete through ``TODO 6``.
@ -91,18 +93,18 @@ Solution
In the ``CMakeLists.txt`` file in the ``MathFunctions`` directory, we create In the ``CMakeLists.txt`` file in the ``MathFunctions`` directory, we create
a library target called ``MathFunctions`` with :command:`add_library`. The a library target called ``MathFunctions`` with :command:`add_library`. The
source file for the library is passed as an argument to source files for the library are passed as an argument to
:command:`add_library`. This looks like the following line: :command:`add_library`. This looks like the following line:
.. raw:: html .. raw:: html/
<details><summary>TODO 1: Click to show/hide answer</summary> <details><summary>TODO 1: Click to show/hide answer</summary>
.. literalinclude:: Step3/MathFunctions/CMakeLists.txt .. code-block:: cmake
:caption: TODO 1: MathFunctions/CMakeLists.txt :caption: TODO 1: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_library :name: MathFunctions/CMakeLists.txt-add_library
:language: cmake
:end-before: # TODO 1 add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
.. raw:: html .. raw:: html
@ -171,36 +173,40 @@ Now let's use our library. In ``tutorial.cxx``, include ``MathFunctions.h``:
<details><summary>TODO 5: Click to show/hide answer</summary> <details><summary>TODO 5: Click to show/hide answer</summary>
.. code-block:: c++ .. literalinclude:: Step3/tutorial.cxx
:caption: TODO 5 : tutorial.cxx :caption: TODO 5: tutorial.cxx
:name: tutorial.cxx-include_MathFunctions.h :name: CMakeLists.txt-include-MathFunctions.h
:language: cmake
#include "MathFunctions.h" :start-after: #include <string>
:end-before: #include "TutorialConfig.h"
.. raw:: html .. raw:: html
</details> </details>
Lastly, replace ``sqrt`` with our library function ``mysqrt``. Lastly, replace ``sqrt`` with our library function ``mathfunctions::mysqrt``.
.. raw:: html .. raw:: html
<details><summary>TODO 6: Click to show/hide answer</summary> <details><summary>TODO 6: Click to show/hide answer</summary>
.. code-block:: c++ .. literalinclude:: Step3/tutorial.cxx
:caption: TODO 6 : tutorial.cxx :caption: TODO 6: tutorial.cxx
:name: tutorial.cxx-call_mysqrt :name: CMakeLists.txt-option
:language: cmake
const double outputValue = mysqrt(inputValue); :start-after: const double inputValue = std::stod(argv[1]);
:end-before: std::cout
.. raw:: html .. raw:: html
</details> </details>
Exercise 2 - Making Our Library Optional Exercise 2 - Adding an Option
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Now let us make the MathFunctions library optional. While for the tutorial Now let us add an option in the MathFunctions library to allow developers to
select either the custom square root implementation or the built in standard
implementation. While for the tutorial
there really isn't any need to do so, for larger projects this is a common there really isn't any need to do so, for larger projects this is a common
occurrence. occurrence.
@ -219,30 +225,32 @@ Helpful Resources
----------------- -----------------
* :command:`if` * :command:`if`
* :command:`list`
* :command:`option` * :command:`option`
* :command:`cmakedefine <configure_file>` * :command:`target_compile_definitions`
Files to Edit Files to Edit
------------- -------------
* ``CMakeLists.txt`` * ``MathFunctions/CMakeLists.txt``
* ``tutorial.cxx`` * ``MathFunctions/MathFunctions.cxx``
* ``TutorialConfig.h.in``
Getting Started Getting Started
--------------- ---------------
Start with the resulting files from Exercise 1. Complete ``TODO 7`` through Start with the resulting files from Exercise 1. Complete ``TODO 7`` through
``TODO 13``. ``TODO 14``.
First create a variable ``USE_MYMATH`` using the :command:`option` command First create a variable ``USE_MYMATH`` using the :command:`option` command
in the top-level ``CMakeLists.txt`` file. In that same file, use that option in ``MathFunctions/CMakeLists.txt``. In that same file, use that option
to determine whether to build and use the ``MathFunctions`` library. to pass a compile definition to the ``MathFunctions`` library.
Then, update ``tutorial.cxx`` and ``TutorialConfig.h.in`` to use Then, update ``MathFunctions.cxx`` to redirect compilation based on
``USE_MYMATH``. ``USE_MYMATH``.
Lastly, prevent ``mysqrt.cxx`` from being compiled when ``USE_MYMATH`` is on
by making it its own library inside of the ``USE_MYMATH`` block of
``MathFunctions/CMakeLists.txt``.
Build and Run Build and Run
------------- -------------
@ -279,7 +287,7 @@ or ``mysqrt``?
Solution Solution
-------- --------
The first step is to add an option to the top-level ``CMakeLists.txt`` file. The first step is to add an option to ``MathFunctions/CMakeLists.txt``.
This option will be displayed in the :manual:`cmake-gui <cmake-gui(1)>` and This option will be displayed in the :manual:`cmake-gui <cmake-gui(1)>` and
:manual:`ccmake <ccmake(1)>` with a default value of ``ON`` that can be :manual:`ccmake <ccmake(1)>` with a default value of ``ON`` that can be
changed by the user. changed by the user.
@ -288,172 +296,160 @@ changed by the user.
<details><summary>TODO 7: Click to show/hide answer</summary> <details><summary>TODO 7: Click to show/hide answer</summary>
.. literalinclude:: Step3/CMakeLists.txt .. literalinclude:: Step3/MathFunctions/CMakeLists.txt
:caption: TODO 7: CMakeLists.txt :caption: TODO 7: MathFunctions/CMakeLists.txt
:name: CMakeLists.txt-option :name: CMakeLists.txt-option-library-level
:language: cmake :language: cmake
:start-after: # should we use our own math functions :start-after: # should we use our own math functions
:end-before: # configure a header file to pass some of the CMake settings :end-before: if (USE_MYMATH)
.. raw:: html .. raw:: html
</details> </details>
Next, make building and linking the ``MathFunctions`` library Next, make building and linking our library with ``mysqrt`` function
conditional. conditional using this new option.
Start by creating a :command:`list` of the optional library targets for our
project. At the moment, it is just ``MathFunctions``. Let's name our list
``EXTRA_LIBS``.
Similarly, we need to make a :command:`list` for the optional includes which Create an :command:`if` statement which checks the value of
we will call ``EXTRA_INCLUDES``. In this list, we will ``APPEND`` the path of
the header file needed for our library.
Next, create an :command:`if` statement which checks the value of
``USE_MYMATH``. Inside the :command:`if` block, put the ``USE_MYMATH``. Inside the :command:`if` block, put the
:command:`add_subdirectory` command from Exercise 1 with the additional :command:`target_compile_definitions` command with the compile
:command:`list` commands. definition ``USE_MYMATH``.
When ``USE_MYMATH`` is ``ON``, the lists will be generated and will be added to
our project. When ``USE_MYMATH`` is ``OFF``, the lists stay empty. With this
strategy, we allow users to toggle ``USE_MYMATH`` to manipulate what library is
used in the build.
The top-level CMakeLists.txt file will now look like the following:
.. raw:: html .. raw:: html
<details><summary>TODO 8: Click to show/hide answer</summary> <details><summary>TODO 8: Click to show/hide answer</summary>
.. literalinclude:: Step3/CMakeLists.txt .. code-block:: cmake
:caption: TODO 8: CMakeLists.txt :caption: TODO 8: MathFunctions/CMakeLists.txt
:name: CMakeLists.txt-USE_MYMATH :name: CMakeLists.txt-USE_MYMATH
:language: cmake
:start-after: # add the MathFunctions library if (USE_MYMATH)
:end-before: # add the executable target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
endif()
.. raw:: html .. raw:: html
</details> </details>
Now that we have these two lists, we need to update When ``USE_MYMATH`` is ``ON``, the compile definition ``USE_MYMATH`` will
:command:`target_link_libraries` and :command:`target_include_directories` to be set. We can then use this compile definition to enable or disable
use them. Changing them is fairly straightforward. sections of our source code.
For :command:`target_link_libraries`, we replace the written out The corresponding changes to the source code are fairly straightforward.
library names with ``EXTRA_LIBS``. This looks like the following: In ``MathFunctions.cxx``, we make ``USE_MYMATH`` control which square root
function is used:
.. raw:: html .. raw:: html
<details><summary>TODO 9: Click to show/hide answer</summary> <details><summary>TODO 9: Click to show/hide answer</summary>
.. literalinclude:: Step3/CMakeLists.txt .. literalinclude:: Step3/MathFunctions/MathFunctions.cxx
:caption: TODO 9: CMakeLists.txt :caption: TODO 9: MathFunctions/MathFunctions.cxx
:name: CMakeLists.txt-target_link_libraries-EXTRA_LIBS :name: MathFunctions-USE_MYMATH-if
:language: cmake :language: c++
:start-after: add_executable(Tutorial tutorial.cxx) :start-after: which square root function should we use?
:end-before: # TODO 3 :end-before: }
.. raw:: html .. raw:: html
</details> </details>
Then, we do the same thing with :command:`target_include_directories` and Next, we need to include ``mysqrt.h`` if ``USE_MYMATH`` is defined.
``EXTRA_INCLUDES``.
.. raw:: html .. raw:: html
<details><summary>TODO 10: Click to show/hide answer</summary> <details><summary>TODO 10: Click to show/hide answer</summary>
.. literalinclude:: Step3/CMakeLists.txt .. literalinclude:: Step3/MathFunctions/MathFunctions.cxx
:caption: TODO 10 : CMakeLists.txt :caption: TODO 10: MathFunctions/MathFunctions.cxx
:name: CMakeLists.txt-target_link_libraries-EXTRA_INCLUDES :name: MathFunctions-USE_MYMATH-if-include
:language: cmake :language: c++
:start-after: # so that we will find TutorialConfig.h :start-after: include <cmath>
:end-before: namespace mathfunctions
.. raw:: html .. raw:: html
</details> </details>
Note that this is a classic approach when dealing with many components. We Finally, we need to include ``cmath`` now that we are using ``std::sqrt``.
will cover the modern approach in the Step 3 of the tutorial.
The corresponding changes to the source code are fairly straightforward.
First, in ``tutorial.cxx``, we include the ``MathFunctions.h`` header if
``USE_MYMATH`` is defined.
.. raw:: html .. raw:: html
<details><summary>TODO 11: Click to show/hide answer</summary> <details><summary>TODO 11: Click to show/hide answer</summary>
.. literalinclude:: Step3/tutorial.cxx .. code-block:: c++
:caption: TODO 11 : tutorial.cxx :caption: TODO 11 : MathFunctions/MathFunctions.cxx
:name: tutorial.cxx-ifdef-include :name: tutorial.cxx-include_cmath
:language: c++
:start-after: // should we include the MathFunctions header #include <cmath>
:end-before: int main
.. raw:: html .. raw:: html
</details> </details>
Then, in the same file, we make ``USE_MYMATH`` control which square root At this point, if ``USE_MYMATH`` is ``OFF``, ``mysqrt.cxx`` would not be used
function is used: but it will still be compiled because the ``MathFunctions`` target has
``mysqrt.cxx`` listed under sources.
There are a few ways to fix this. The first option is to use
:command:`target_sources` to add ``mysqrt.cxx`` from within the ``USE_MYMATH``
block. Another option is to create an additional library within the
``USE_MYMATH`` block which is responsible for compiling ``mysqrt.cxx``. For
the sake of this tutorial, we are going to create an additional library.
First, from within ``USE_MYMATH`` create a library called ``SqrtLibrary``
that has sources ``mysqrt.cxx``.
.. raw:: html .. raw:: html
<details><summary>TODO 12: Click to show/hide answer</summary> <details><summary>TODO 12: Click to show/hide answer</summary>
.. literalinclude:: Step3/tutorial.cxx .. literalinclude:: Step3/MathFunctions/CMakeLists.txt
:caption: TODO 12 : tutorial.cxx :caption: TODO 12 : MathFunctions/CMakeLists.txt
:name: tutorial.cxx-ifdef-const :name: MathFunctions/CMakeLists.txt-add_library-SqrtLibrary
:language: c++ :language: cmake
:start-after: // which square root function should we use? :start-after: # library that just does sqrt
:end-before: std::cout << "The square root of :end-before: # TODO 7: Link
.. raw:: html .. raw:: html
</details> </details>
Since the source code now requires ``USE_MYMATH`` we can add it to Next, we link ``SqrtLibrary`` onto ``MathFunctions`` when ``USE_MYMATH`` is
``TutorialConfig.h.in`` with the following line: enabled.
.. raw:: html .. raw:: html
<details><summary>TODO 13: Click to show/hide answer</summary> <details><summary>TODO 13: Click to show/hide answer</summary>
.. literalinclude:: Step3/TutorialConfig.h.in .. literalinclude:: Step3/MathFunctions/CMakeLists.txt
:caption: TODO 13 : TutorialConfig.h.in :caption: TODO 13 : MathFunctions/CMakeLists.txt
:name: TutorialConfig.h.in-cmakedefine :name: MathFunctions/CMakeLists.txt-target_link_libraries-SqrtLibrary
:language: c++ :language: cmake
:lines: 4 :start-after: to tutorial_compiler_flags
:end-before: endif()
.. raw:: html .. raw:: html
</details> </details>
With these changes, our library is now completely optional to whoever is Finally, we can remove ``mysqrt.cxx`` from our ``MathFunctions`` library
building and using it. source list because it will be pulled in when ``SqrtLibrary`` is included.
Bonus Question
--------------
Why is it important that we configure ``TutorialConfig.h.in``
after the option for ``USE_MYMATH``? What would happen if we inverted the two?
Answer
------
.. raw:: html .. raw:: html
<details><summary>Click to show/hide answer</summary> <details><summary>TODO 14: Click to show/hide answer</summary>
We configure after because ``TutorialConfig.h.in`` uses the value of .. literalinclude:: Step3/MathFunctions/CMakeLists.txt
``USE_MYMATH``. If we configure the file before :caption: TODO 14 : MathFunctions/CMakeLists.txt
calling :command:`option`, we won't be using the expected value of :name: MathFunctions/CMakeLists.txt-remove-mysqrt.cxx-MathFunctions
``USE_MYMATH``. :language: cmake
:end-before: # TODO 1:
.. raw:: html .. raw:: html
</details> </details>
With these changes, the ``mysqrt`` function is now completely optional to
whoever is building and using the ``MathFunctions`` library. Users can toggle
``USE_MYMATH`` to manipulate what library is used in the build.

@ -15,16 +15,7 @@ if(USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH") target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
# first we add the executable that generates the table include(MakeTable.cmake) # generates Table.h
add_executable(MakeTable MakeTable.cxx)
target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
# add the command to generate the source code
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)
# library that just does sqrt # library that just does sqrt
add_library(SqrtLibrary STATIC add_library(SqrtLibrary STATIC

@ -0,0 +1,10 @@
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
# add the command to generate the source code
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)

@ -10,6 +10,7 @@
namespace mathfunctions { namespace mathfunctions {
double sqrt(double x) double sqrt(double x)
{ {
// which square root function should we use?
#ifdef USE_MYMATH #ifdef USE_MYMATH
return detail::mysqrt(x); return detail::mysqrt(x);
#else #else

@ -10,49 +10,22 @@ To accomplish this we need to add :variable:`BUILD_SHARED_LIBS` to the
top-level ``CMakeLists.txt``. We use the :command:`option` command as it allows top-level ``CMakeLists.txt``. We use the :command:`option` command as it allows
users to optionally select if the value should be ``ON`` or ``OFF``. users to optionally select if the value should be ``ON`` or ``OFF``.
Next we are going to refactor ``MathFunctions`` to become a real library that
encapsulates using ``mysqrt`` or ``sqrt``, instead of requiring the calling
code to do this logic. This will also mean that ``USE_MYMATH`` will not control
building ``MathFunctions``, but instead will control the behavior of this
library.
The first step is to update the starting section of the top-level
``CMakeLists.txt`` to look like:
.. literalinclude:: Step11/CMakeLists.txt .. literalinclude:: Step11/CMakeLists.txt
:caption: CMakeLists.txt :caption: CMakeLists.txt
:name: CMakeLists.txt-option-BUILD_SHARED_LIBS :name: CMakeLists.txt-option-BUILD_SHARED_LIBS
:language: cmake :language: cmake
:end-before: # add the binary tree :start-after: set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
:end-before: # configure a header file to pass the version number only
Now that we have made ``MathFunctions`` always be used, we will need to update
the logic of that library. So, in ``MathFunctions/CMakeLists.txt`` we need to
create a SqrtLibrary that will conditionally be built and installed when
``USE_MYMATH`` is enabled. Now, since this is a tutorial, we are going to
explicitly require that SqrtLibrary is built statically.
The end result is that ``MathFunctions/CMakeLists.txt`` should look like: Next, we need to specify output directories for our static and shared
libraries.
.. literalinclude:: Step11/MathFunctions/CMakeLists.txt .. literalinclude:: Step11/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt :caption: CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_library-STATIC :name: CMakeLists.txt-cmake-output-directories
:language: cmake :language: cmake
:lines: 1-36,42- :start-after: # we don't need to tinker with the path to run the executable
:end-before: # configure a header file to pass the version number only
Next, update ``MathFunctions/mysqrt.cxx`` to use the ``mathfunctions`` and
``detail`` namespaces:
.. literalinclude:: Step11/MathFunctions/mysqrt.cxx
:caption: MathFunctions/mysqrt.cxx
:name: MathFunctions/mysqrt.cxx-namespace
:language: c++
We also need to make some changes in ``tutorial.cxx``, so that it no longer
uses ``USE_MYMATH``:
#. Always include ``MathFunctions.h``
#. Always use ``mathfunctions::sqrt``
#. Don't include ``cmath``
Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines: Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines:

@ -16,22 +16,15 @@ target_compile_options(tutorial_compiler_flags INTERFACE
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>" "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
) )
# should we use our own math functions # configure a header file to pass the version number only
option(USE_MYMATH "Use tutorial provided math implementation" ON)
# configure a header file to pass some of the CMake settings
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h) configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library # add the MathFunctions library
if(USE_MYMATH) add_subdirectory(MathFunctions)
add_subdirectory(MathFunctions)
list(APPEND EXTRA_LIBS MathFunctions)
endif()
# add the executable # add the executable
add_executable(Tutorial tutorial.cxx) add_executable(Tutorial tutorial.cxx)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags) target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files # add the binary tree to the search path for include files
# so that we will find TutorialConfig.h # so that we will find TutorialConfig.h

@ -1,32 +1,42 @@
# first we add the executable that generates the table # add the library that runs
add_executable(MakeTable MakeTable.cxx) add_library(MathFunctions MathFunctions.cxx)
# add the command to generate the source code # state that anybody linking to us needs to include the current source dir
add_custom_command( # to find MathFunctions.h, while we don't.
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h target_include_directories(MathFunctions
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS MakeTable
) )
# add the main library # should we use our own math functions
add_library(MathFunctions option(USE_MYMATH "Use tutorial provided math implementation" ON)
if(USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
include(MakeTable.cmake) # generates Table.h
# library that just does sqrt
add_library(SqrtLibrary STATIC
mysqrt.cxx mysqrt.cxx
${CMAKE_CURRENT_BINARY_DIR}/Table.h ${CMAKE_CURRENT_BINARY_DIR}/Table.h
) )
# state that anybody linking to us needs to include the current source dir # state that we depend on our binary dir to find Table.h
# to find MathFunctions.h, while we don't. target_include_directories(SqrtLibrary PRIVATE
# state that we depend on our binary dir to find Table.h ${CMAKE_CURRENT_BINARY_DIR}
target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
) )
# link our compiler flags interface library target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
target_link_libraries(MathFunctions tutorial_compiler_flags) target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs # install libs
set(installable_libs MathFunctions tutorial_compiler_flags) set(installable_libs MathFunctions tutorial_compiler_flags)
if(TARGET SqrtLibrary)
list(APPEND installable_libs SqrtLibrary)
endif()
install(TARGETS ${installable_libs} DESTINATION lib) install(TARGETS ${installable_libs} DESTINATION lib)
# install include headers # install include headers
install(FILES MathFunctions.h DESTINATION include) install(FILES MathFunctions.h DESTINATION include)

@ -0,0 +1,10 @@
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
# add the command to generate the source code
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)

@ -10,6 +10,7 @@
namespace mathfunctions { namespace mathfunctions {
double sqrt(double x) double sqrt(double x)
{ {
// which square root function should we use?
#ifdef USE_MYMATH #ifdef USE_MYMATH
return detail::mysqrt(x); return detail::mysqrt(x);
#else #else

@ -1 +1,3 @@
double mysqrt(double x); namespace mathfunctions {
double sqrt(double x);
}

@ -5,6 +5,8 @@
// include the generated table // include the generated table
#include "Table.h" #include "Table.h"
namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations // a hack square root calculation using simple operations
double mysqrt(double x) double mysqrt(double x)
{ {
@ -31,3 +33,5 @@ double mysqrt(double x)
return result; return result;
} }
}
}

@ -1,4 +1,3 @@
// the configured options and settings for Tutorial // the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#cmakedefine USE_MYMATH

@ -1,15 +1,11 @@
// A simple program that computes the square root of a number // A simple program that computes the square root of a number
#include <cmath>
#include <iostream> #include <iostream>
#include <sstream>
#include <string> #include <string>
#include "MathFunctions.h"
#include "TutorialConfig.h" #include "TutorialConfig.h"
// should we include the MathFunctions header?
#ifdef USE_MYMATH
# include "MathFunctions.h"
#endif
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc < 2) { if (argc < 2) {
@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double // convert input to double
const double inputValue = std::stod(argv[1]); const double inputValue = std::stod(argv[1]);
// which square root function should we use? const double outputValue = mathfunctions::sqrt(inputValue);
#ifdef USE_MYMATH
const double outputValue = mysqrt(inputValue);
#else
const double outputValue = sqrt(inputValue);
#endif
std::cout << "The square root of " << inputValue << " is " << outputValue std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl; << std::endl;

@ -13,16 +13,7 @@ if(USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH") target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
# first we add the executable that generates the table include(MakeTable.cmake) # generates Table.h
add_executable(MakeTable MakeTable.cxx)
target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
# add the command to generate the source code
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)
# library that just does sqrt # library that just does sqrt
add_library(SqrtLibrary STATIC add_library(SqrtLibrary STATIC

@ -0,0 +1,10 @@
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
# add the command to generate the source code
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)

@ -10,6 +10,7 @@
namespace mathfunctions { namespace mathfunctions {
double sqrt(double x) double sqrt(double x)
{ {
// which square root function should we use?
#ifdef USE_MYMATH #ifdef USE_MYMATH
return detail::mysqrt(x); return detail::mysqrt(x);
#else #else

@ -15,16 +15,7 @@ if(USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH") target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
# first we add the executable that generates the table include(MakeTable.cmake) # generates Table.h
add_executable(MakeTable MakeTable.cxx)
target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
# add the command to generate the source code
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)
# library that just does sqrt # library that just does sqrt
add_library(SqrtLibrary STATIC add_library(SqrtLibrary STATIC

@ -0,0 +1,10 @@
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
# add the command to generate the source code
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)

@ -10,6 +10,7 @@
namespace mathfunctions { namespace mathfunctions {
double sqrt(double x) double sqrt(double x)
{ {
// which square root function should we use?
#ifdef USE_MYMATH #ifdef USE_MYMATH
return detail::mysqrt(x); return detail::mysqrt(x);
#else #else

@ -7,36 +7,20 @@ project(Tutorial VERSION 1.0)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_STANDARD_REQUIRED True)
# TODO 7: Create a variable USE_MYMATH using option and set default to ON
# configure a header file to pass some of the CMake settings # configure a header file to pass some of the CMake settings
# to the source code # to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h) configure_file(TutorialConfig.h.in TutorialConfig.h)
# TODO 8: Use list() and APPEND to create a list of optional libraries
# called EXTRA_LIBS and a list of optional include directories called
# EXTRA_INCLUDES. Add the MathFunctions library and source directory to
# the appropriate lists.
#
# Only call add_subdirectory and only add MathFunctions specific values
# to EXTRA_LIBS and EXTRA_INCLUDES if USE_MYMATH is true.
# TODO 2: Use add_subdirectory() to add MathFunctions to this project # TODO 2: Use add_subdirectory() to add MathFunctions to this project
# add the executable # add the executable
add_executable(Tutorial tutorial.cxx) add_executable(Tutorial tutorial.cxx)
# TODO 9: Use EXTRA_LIBS instead of the MathFunctions specific values
# in target_link_libraries.
# TODO 3: Use target_link_libraries to link the library to our executable # TODO 3: Use target_link_libraries to link the library to our executable
# TODO 4: Add MathFunctions to Tutorial's target_include_directories() # TODO 4: Add MathFunctions to Tutorial's target_include_directories()
# Hint: ${PROJECT_SOURCE_DIR} is a path to the project source. AKA This folder! # Hint: ${PROJECT_SOURCE_DIR} is a path to the project source. AKA This folder!
# TODO 10: Use EXTRA_INCLUDES instead of the MathFunctions specific values
# in target_include_directories.
# add the binary tree to the search path for include files # add the binary tree to the search path for include files
# so that we will find TutorialConfig.h # so that we will find TutorialConfig.h
target_include_directories(Tutorial PUBLIC target_include_directories(Tutorial PUBLIC

@ -1,2 +1,15 @@
# TODO 1: Add a library called MathFunctions # TODO 14: Remove mysqrt.cxx from the list of sources
# TODO 1: Add a library called MathFunctions with sources MathFunctions.cxx
# and mysqrt.cxx
# Hint: You will need the add_library command # Hint: You will need the add_library command
# TODO 7: Create a variable USE_MYMATH using option and set default to ON
# TODO 8: If USE_MYMATH is ON, use target_compile_definitions to pass
# USE_MYMATH as a precompiled definition to our source files
# TODO 12: When USE_MYMATH is ON, add a library for SqrtLibrary with
# source mysqrt.cxx
# TODO 13: When USE_MYMATH is ON, link SqrtLibrary to the MathFunctions Library

@ -0,0 +1,15 @@
#include "MathFunctions.h"
// TODO 11: include cmath
// TODO 10: Wrap the mysqrt include in a precompiled ifdef based on USE_MYMATH
#include "mysqrt.h"
namespace mathfunctions {
double sqrt(double x)
{
// TODO 9: If USE_MYMATH is defined, use detail::mysqrt.
// Otherwise, use std::sqrt.
return detail::mysqrt(x);
}
}

@ -1 +1,5 @@
double mysqrt(double x); #pragma once
namespace mathfunctions {
double sqrt(double x);
}

@ -1,5 +1,9 @@
#include "mysqrt.h"
#include <iostream> #include <iostream>
namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations // a hack square root calculation using simple operations
double mysqrt(double x) double mysqrt(double x)
{ {
@ -20,3 +24,5 @@ double mysqrt(double x)
} }
return result; return result;
} }
}
}

@ -0,0 +1,7 @@
#pragma once
namespace mathfunctions {
namespace detail {
double mysqrt(double x);
}
}

@ -1,5 +1,3 @@
// the configured options and settings for Tutorial // the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
// TODO 13: use cmakedefine to define USE_MYMATH

@ -3,11 +3,8 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include "TutorialConfig.h"
// TODO 11: Only include MathFunctions if USE_MYMATH is defined
// TODO 5: Include MathFunctions.h // TODO 5: Include MathFunctions.h
#include "TutorialConfig.h"
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
@ -22,9 +19,7 @@ int main(int argc, char* argv[])
// convert input to double // convert input to double
const double inputValue = std::stod(argv[1]); const double inputValue = std::stod(argv[1]);
// TODO 12: Use mysqrt if USE_MYMATH is defined and sqrt otherwise // TODO 6: Replace sqrt with mathfunctions::sqrt
// TODO 6: Replace sqrt with mysqrt
// calculate square root // calculate square root
const double outputValue = sqrt(inputValue); const double outputValue = sqrt(inputValue);

@ -3,13 +3,16 @@ cmake_minimum_required(VERSION 3.10)
# set the project name and version # set the project name and version
project(Tutorial VERSION 1.0) project(Tutorial VERSION 1.0)
# TODO 4: Replace the following code by:
# * Creating an interface library called tutorial_compiler_flags
# Hint: use add_library() with the INTERFACE signature
# * Add compiler feature cxx_std_11 to tutorial_compiler_flags
# Hint: Use target_compile_features()
# specify the C++ standard # specify the C++ standard
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_STANDARD_REQUIRED True)
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
# configure a header file to pass some of the CMake settings # configure a header file to pass some of the CMake settings
# to the source code # to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h) configure_file(TutorialConfig.h.in TutorialConfig.h)
@ -17,16 +20,15 @@ configure_file(TutorialConfig.h.in TutorialConfig.h)
# TODO 2: Remove EXTRA_INCLUDES list # TODO 2: Remove EXTRA_INCLUDES list
# add the MathFunctions library # add the MathFunctions library
if(USE_MYMATH) add_subdirectory(MathFunctions)
add_subdirectory(MathFunctions) list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
list(APPEND EXTRA_LIBS MathFunctions)
list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
endif()
# add the executable # add the executable
add_executable(Tutorial tutorial.cxx) add_executable(Tutorial tutorial.cxx)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS}) # TODO 5: Link Tutorial to tutorial_compiler_flags
target_link_libraries(Tutorial PUBLIC MathFunctions)
# TODO 3: Remove use of EXTRA_INCLUDES # TODO 3: Remove use of EXTRA_INCLUDES

@ -1,5 +1,22 @@
add_library(MathFunctions mysqrt.cxx) add_library(MathFunctions MathFunctions.cxx)
# TODO 1: State that anybody linking to MathFunctions needs to include the # TODO 1: State that anybody linking to MathFunctions needs to include the
# current source directory, while MathFunctions itself doesn't. # current source directory, while MathFunctions itself doesn't.
# Hint: Use target_include_directories with the INTERFACE keyword # Hint: Use target_include_directories with the INTERFACE keyword
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
if (USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
# library that just does sqrt
add_library(SqrtLibrary STATIC
mysqrt.cxx
)
# TODO 7: Link SqrtLibrary to tutorial_compiler_flags
target_link_libraries(MathFunctions PUBLIC SqrtLibrary)
endif()
# TODO 6: Link MathFunctions to tutorial_compiler_flags

@ -0,0 +1,19 @@
#include "MathFunctions.h"
#include <cmath>
#ifdef USE_MYMATH
# include "mysqrt.h"
#endif
namespace mathfunctions {
double sqrt(double x)
{
// which square root function should we use?
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else
return std::sqrt(x);
#endif
}
}

@ -1 +1,5 @@
double mysqrt(double x); #pragma once
namespace mathfunctions {
double sqrt(double x);
}

@ -1,7 +1,9 @@
#include <iostream> #include "mysqrt.h"
#include "MathFunctions.h" #include <iostream>
namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations // a hack square root calculation using simple operations
double mysqrt(double x) double mysqrt(double x)
{ {
@ -22,3 +24,5 @@ double mysqrt(double x)
} }
return result; return result;
} }
}
}

@ -0,0 +1,7 @@
#pragma once
namespace mathfunctions {
namespace detail {
double mysqrt(double x);
}
}

@ -1,4 +1,3 @@
// the configured options and settings for Tutorial // the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#cmakedefine USE_MYMATH

@ -3,13 +3,9 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include "MathFunctions.h"
#include "TutorialConfig.h" #include "TutorialConfig.h"
// should we include the MathFunctions header?
#ifdef USE_MYMATH
# include "MathFunctions.h"
#endif
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc < 2) { if (argc < 2) {
@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double // convert input to double
const double inputValue = std::stod(argv[1]); const double inputValue = std::stod(argv[1]);
// which square root function should we use? const double outputValue = mathfunctions::sqrt(inputValue);
#ifdef USE_MYMATH
const double outputValue = mysqrt(inputValue);
#else
const double outputValue = sqrt(inputValue);
#endif
std::cout << "The square root of " << inputValue << " is " << outputValue std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl; << std::endl;

@ -1,55 +1,41 @@
# TODO 4: Update the minimum required version to 3.15 # TODO 1: Update the minimum required version to 3.15
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.10)
# set the project name and version # set the project name and version
project(Tutorial VERSION 1.0) project(Tutorial VERSION 1.0)
# TODO 1: Replace the following code by:
# * Creating an interface library called tutorial_compiler_flags
# Hint: use add_library() with the INTERFACE signature
# * Add compiler feature cxx_std_11 to tutorial_compiler_flags
# Hint: Use target_compile_features()
# specify the C++ standard # specify the C++ standard
set(CMAKE_CXX_STANDARD 11) add_library(tutorial_compiler_flags INTERFACE)
set(CMAKE_CXX_STANDARD_REQUIRED True) target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
# TODO 5: Create helper variables to determine which compiler we are using: # TODO 2: Create helper variables to determine which compiler we are using:
# * Create a new variable gcc_like_cxx that is true if we are using CXX and # * Create a new variable gcc_like_cxx that is true if we are using CXX and
# any of the following compilers: ARMClang, AppleClang, Clang, GNU, LCC # any of the following compilers: ARMClang, AppleClang, Clang, GNU, LCC
# * Create a new variable msvc_cxx that is true if we are using CXX and MSVC # * Create a new variable msvc_cxx that is true if we are using CXX and MSVC
# Hint: Use set() and COMPILE_LANG_AND_ID # Hint: Use set() and COMPILE_LANG_AND_ID
# TODO 6: Add warning flag compile options to the interface library # TODO 3: Add warning flag compile options to the interface library
# tutorial_compiler_flags. # tutorial_compiler_flags.
# * For gcc_like_cxx, add flags -Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused # * For gcc_like_cxx, add flags -Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused
# * For msvc_cxx, add flags -W3 # * For msvc_cxx, add flags -W3
# Hint: Use target_compile_options() # Hint: Use target_compile_options()
# TODO 7: With nested generator expressions, only use the flags for the # TODO 4: With nested generator expressions, only use the flags for the
# build-tree # build-tree
# Hint: Use BUILD_INTERFACE # Hint: Use BUILD_INTERFACE
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
# configure a header file to pass some of the CMake settings # configure a header file to pass some of the CMake settings
# to the source code # to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h) configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library # add the MathFunctions library
if(USE_MYMATH) add_subdirectory(MathFunctions)
add_subdirectory(MathFunctions)
list(APPEND EXTRA_LIBS MathFunctions)
endif()
# add the executable # add the executable
add_executable(Tutorial tutorial.cxx) add_executable(Tutorial tutorial.cxx)
# TODO 2: Link to tutorial_compiler_flags target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
# add the binary tree to the search path for include files # add the binary tree to the search path for include files
# so that we will find TutorialConfig.h # so that we will find TutorialConfig.h

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save