Merge branch 'experimental'

ci/unstable
Timo Röhling 1 year ago
commit 5c412d7000

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

@ -372,7 +372,7 @@ optional argument topic will be appended to the argument list."
(interactive "s")
(let* ((bufname (if buffer buffer (concat "*CMake" type (if topic "-") topic "*")))
(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.
(resize-mini-windows nil)
)
@ -391,7 +391,7 @@ optional argument topic will be appended to the argument list."
(interactive "s")
(let* ((bufname (if buffer buffer (concat "*CMake" type (if topic "-") topic "*")))
(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.
(resize-mini-windows nil)
)

@ -73,6 +73,7 @@ syn keyword cmakeProperty contained
\ AUTOGEN_ORIGIN_DEPENDS
\ AUTOGEN_PARALLEL
\ AUTOGEN_SOURCE_GROUP
\ AUTOGEN_USE_SYSTEM_INCLUDE
\ AUTOGEN_TARGETS_FOLDER
\ AUTOGEN_TARGET_DEPENDS
\ AUTOMOC
@ -128,7 +129,10 @@ syn keyword cmakeProperty contained
\ CPACK_WIX_ACL
\ CROSSCOMPILING_EMULATOR
\ CUDA_ARCHITECTURES
\ CUDA_CUBIN_COMPILATION
\ CUDA_EXTENSIONS
\ CUDA_FATBIN_COMPILATION
\ CUDA_OPTIX_COMPILATION
\ CUDA_PTX_COMPILATION
\ CUDA_RESOLVE_DEVICE_SYMBOLS
\ CUDA_RUNTIME_LIBRARY
@ -193,6 +197,10 @@ syn keyword cmakeProperty contained
\ HAS_CXX
\ HEADER_FILE_ONLY
\ HELPSTRING
\ HIP_ARCHITECTURES
\ HIP_EXTENSIONS
\ HIP_STANDARD
\ HIP_STANDARD_REQUIRED
\ IMPLICIT_DEPENDS_INCLUDE_TRANSFORM
\ IMPORTED
\ IMPORTED_COMMON_LANGUAGE_RUNTIME
@ -217,6 +225,7 @@ syn keyword cmakeProperty contained
\ INSTALL_RPATH
\ INSTALL_RPATH_USE_LINK_PATH
\ INTERFACE_AUTOUIC_OPTIONS
\ INTERFACE_AUTOMOC_MACRO_NAMES
\ INTERFACE_COMPILE_DEFINITIONS
\ INTERFACE_COMPILE_FEATURES
\ INTERFACE_COMPILE_OPTIONS
@ -320,6 +329,7 @@ syn keyword cmakeProperty contained
\ SKIP_AUTORCC
\ SKIP_AUTOUIC
\ SKIP_BUILD_RPATH
\ SKIP_LINTING
\ SKIP_PRECOMPILE_HEADERS
\ SKIP_REGULAR_EXPRESSION
\ SKIP_RETURN_CODE
@ -459,6 +469,7 @@ syn keyword cmakeVariable contained
\ BUILD_SHARED_LIBS
\ CACHE
\ CMAKE_ABSOLUTE_DESTINATION_FILES
\ CMAKE_ADD_CUSTOM_COMMAND_DEPENDS_EXPLICIT_ONLY
\ CMAKE_AIX_EXPORT_ALL_SYMBOLS
\ CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS
\ CMAKE_ANDROID_API
@ -678,6 +689,7 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_VISIBILITY_PRESET
\ CMAKE_AUTOGEN_ORIGIN_DEPENDS
\ CMAKE_AUTOGEN_PARALLEL
\ CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE
\ CMAKE_AUTOGEN_VERBOSE
\ CMAKE_AUTOMOC
\ CMAKE_AUTOMOC_COMPILER_PREDEFINES
@ -686,11 +698,14 @@ syn keyword cmakeVariable contained
\ CMAKE_AUTOMOC_MOC_OPTIONS
\ CMAKE_AUTOMOC_PATH_PREFIX
\ CMAKE_AUTOMOC_RELAXED_MODE
\ CMAKE_AUTOMOC_EXECUTABLE
\ CMAKE_AUTORCC
\ CMAKE_AUTORCC_OPTIONS
\ CMAKE_AUTORCC_EXECUTABLE
\ CMAKE_AUTOUIC
\ CMAKE_AUTOUIC_OPTIONS
\ CMAKE_AUTOUIC_SEARCH_PATHS
\ CMAKE_AUTOUIC_EXECUTABLE
\ CMAKE_BACKWARDS_COMPATIBILITY
\ CMAKE_BINARY_DIR
\ CMAKE_BUILD_RPATH
@ -1139,6 +1154,74 @@ syn keyword cmakeVariable contained
\ CMAKE_GLOBAL_AUTORCC_TARGET
\ CMAKE_GLOBAL_AUTORCC_TARGET_NAME
\ CMAKE_GNUtoMS
\ CMAKE_HIP
\ CMAKE_HIP_ANDROID_TOOLCHAIN_MACHINE
\ CMAKE_HIP_ANDROID_TOOLCHAIN_PREFIX
\ CMAKE_HIP_ANDROID_TOOLCHAIN_SUFFIX
\ CMAKE_HIP_ARCHITECTURES
\ CMAKE_HIP_ARCHIVE_APPEND
\ CMAKE_HIP_ARCHIVE_CREATE
\ CMAKE_HIP_ARCHIVE_FINISH
\ CMAKE_HIP_CLANG_TIDY
\ CMAKE_HIP_COMPILER
\ CMAKE_HIP_COMPILER_ABI
\ CMAKE_HIP_COMPILER_AR
\ CMAKE_HIP_COMPILER_ARCHITECTURE_ID
\ CMAKE_HIP_COMPILER_EXTERNAL_TOOLCHAIN
\ CMAKE_HIP_COMPILER_ID
\ CMAKE_HIP_COMPILER_LAUNCHER
\ CMAKE_HIP_COMPILER_LOADED
\ CMAKE_HIP_COMPILER_PREDEFINES_COMMAND
\ CMAKE_HIP_COMPILER_RANLIB
\ CMAKE_HIP_COMPILER_TARGET
\ CMAKE_HIP_COMPILER_VERSION
\ CMAKE_HIP_COMPILER_VERSION_INTERNAL
\ CMAKE_HIP_COMPILE_FEATURES
\ CMAKE_HIP_COMPILE_OBJECT
\ CMAKE_HIP_CPPCHECK
\ CMAKE_HIP_CPPLINT
\ CMAKE_HIP_CREATE_SHARED_LIBRARY
\ CMAKE_HIP_CREATE_SHARED_MODULE
\ CMAKE_HIP_CREATE_STATIC_LIBRARY
\ CMAKE_HIP_EXTENSIONS
\ CMAKE_HIP_FLAGS
\ CMAKE_HIP_FLAGS_DEBUG
\ CMAKE_HIP_FLAGS_DEBUG_INIT
\ CMAKE_HIP_FLAGS_INIT
\ CMAKE_HIP_FLAGS_MINSIZEREL
\ CMAKE_HIP_FLAGS_MINSIZEREL_INIT
\ CMAKE_HIP_FLAGS_RELEASE
\ CMAKE_HIP_FLAGS_RELEASE_INIT
\ CMAKE_HIP_FLAGS_RELWITHDEBINFO
\ CMAKE_HIP_FLAGS_RELWITHDEBINFO_INIT
\ CMAKE_HIP_IGNORE_EXTENSIONS
\ CMAKE_HIP_IMPLICIT_INCLUDE_DIRECTORIES
\ CMAKE_HIP_IMPLICIT_LINK_DIRECTORIES
\ CMAKE_HIP_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES
\ CMAKE_HIP_IMPLICIT_LINK_LIBRARIES
\ CMAKE_HIP_INCLUDE_WHAT_YOU_USE
\ CMAKE_HIP_INIT
\ CMAKE_HIP_LIBRARY_ARCHITECTURE
\ CMAKE_HIP_LINKER_LAUNCHER
\ CMAKE_HIP_LINKER_PREFERENCE
\ CMAKE_HIP_LINKER_PREFERENCE_PROPAGATES
\ CMAKE_HIP_LINKER_WRAPPER_FLAG
\ CMAKE_HIP_LINKER_WRAPPER_FLAG_SEP
\ CMAKE_HIP_LINK_EXECUTABLE
\ CMAKE_HIP_LINK_LIBRARY_FILE_FLAG
\ CMAKE_HIP_LINK_LIBRARY_FLAG
\ CMAKE_HIP_LINK_LIBRARY_SUFFIX
\ CMAKE_HIP_OUTPUT_EXTENSION
\ CMAKE_HIP_PLATFORM_ID
\ CMAKE_HIP_SIMULATE_ID
\ CMAKE_HIP_SIMULATE_VERSION
\ CMAKE_HIP_SIZEOF_DATA_PTR
\ CMAKE_HIP_SOURCE_FILE_EXTENSIONS
\ CMAKE_HIP_STANDARD
\ CMAKE_HIP_STANDARD_INCLUDE_DIRECTORIES
\ CMAKE_HIP_STANDARD_LIBRARIES
\ CMAKE_HIP_STANDARD_REQUIRED
\ CMAKE_HIP_VISIBILITY_PRESET
\ CMAKE_HOME_DIRECTORY
\ CMAKE_HOST_APPLE
\ CMAKE_HOST_SOLARIS
@ -1491,6 +1574,7 @@ syn keyword cmakeVariable contained
\ CMAKE_USER_MAKE_RULES_OVERRIDE_CUDA
\ CMAKE_USER_MAKE_RULES_OVERRIDE_CXX
\ CMAKE_USER_MAKE_RULES_OVERRIDE_Fortran
\ CMAKE_USER_MAKE_RULES_OVERRIDE_HIP
\ CMAKE_USER_MAKE_RULES_OVERRIDE_Java
\ CMAKE_USER_MAKE_RULES_OVERRIDE_RC
\ CMAKE_USER_MAKE_RULES_OVERRIDE_Swift
@ -2095,6 +2179,7 @@ syn keyword cmakeKWadd_custom_command contained
\ COMMENT
\ CROSSCOMPILING_EMULATOR
\ DEPENDS
\ DEPENDS_EXPLICIT_ONLY
\ DEPFILE
\ GENERATED
\ IMPLICIT_DEPENDS
@ -2563,6 +2648,7 @@ syn keyword cmakeKWdoxygen_add_docs contained
syn keyword cmakeKWenable_language contained
\ ASM
\ CUDA
\ HIP
\ ISPC
\ OBJC
\ OBJCXX
@ -2735,6 +2821,7 @@ syn keyword cmakeKWfile contained
\ READ_SYMLINK
\ REAL_PATH
\ REGEX
\ RELATIVE
\ RELATIVE_PATH
\ RELEASE
\ REMOVE
@ -3304,6 +3391,7 @@ syn keyword cmakeKWproject contained
\ CMAKE_PROJECT_
\ CUDA
\ DESCRIPTION
\ HIP
\ HOMEPAGE_URL
\ ISPC
\ LANGUAGES
@ -3617,6 +3705,9 @@ syn keyword cmakeKWtry_compile contained
\ EXECUTABLE
\ FALSE
\ GHS
\ HIP_EXTENSIONS
\ HIP_STANDARD
\ HIP_STANDARD_REQUIRED
\ INCLUDE_DIRECTORIES
\ LANG
\ LINK_DIRECTORIES
@ -3736,6 +3827,9 @@ syn keyword cmakeGeneratorExpressions contained
\ GENERATE
\ GENEX_EVAL
\ GNU
\ HIP_COMPILER_ID
\ HIP_COMPILER_VERSION
\ HIP_STANDARD
\ HOST_LINK
\ IF
\ IGNORE

@ -1,7 +1,7 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# 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_CXX ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideCXX.cmake)
@ -131,6 +131,23 @@ if(CMake_BUILD_LTO)
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
# 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
# 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)
if(NOT DEFINED CMAKE_USE_SYSTEM_LIBRARY_${util}
AND DEFINED CMAKE_USE_SYSTEM_LIBRARIES)
@ -169,6 +186,9 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
# Optionally use system utility libraries.
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_EXPAT "Use system-installed expat" "${CMAKE_USE_SYSTEM_LIBRARY_EXPAT}")
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_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_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_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)
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")
set(_CLANG_MSVC_WINDOWS 1)
endif()
@ -22,18 +22,19 @@ if(MSVC OR _INTEL_WINDOWS OR _CLANG_MSVC_WINDOWS)
else()
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.
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_CXX_FLAGS "${CMAKE_CXX_FLAGS} -wd5105")
endif()
if(_CLANG_MSVC_WINDOWS AND "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Xlinker -stack:20000000")
# Use a stack size large enough for CMake_DEFAULT_RECURSION_LIMIT.
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()
#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::
|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::
|prefix_XXX_SUBDIR| for each ``<prefix>/[s]bin`` in ``PATH``, and
|entry_XXX_SUBDIR| for other entries in ``PATH``
@ -140,21 +143,40 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
|prefix_XXX_SUBDIR| for each ``<prefix>`` in
:variable:`CMAKE_SYSTEM_PREFIX_PATH`
1. .. versionadded:: 3.12
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
current package being found. Specifically, look in the
:variable:`<PackageName>_ROOT` CMake variable and the
:envvar:`<PackageName>_ROOT` environment variable.
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
module or config package will be searched after paths from the current
module or package. In other words, the search order would be
``<CurrentPackage>_ROOT``, ``ENV{<CurrentPackage>_ROOT}``,
``<ParentPackage>_ROOT``, ``ENV{<ParentPackage>_ROOT}``, etc.
This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
See policy :policy:`CMP0074`.
1. 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
current package being found. See policy :policy:`CMP0074`.
.. 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
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 package. In other words, the search order would be
``<CurrentPackage>_ROOT``, ``ENV{<CurrentPackage>_ROOT}``,
``<ParentPackage>_ROOT``, ``ENV{<ParentPackage>_ROOT}``, etc.
This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
* |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
by setting the :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH` to ``FALSE``.
* |CMAKE_PREFIX_PATH_XXX|
* |CMAKE_XXX_PATH|
* |CMAKE_XXX_MAC_PATH|
* |ENV_CMAKE_PREFIX_PATH_XXX|
* |ENV_CMAKE_XXX_PATH|
* |ENV_CMAKE_XXX_MAC_PATH|
4. Search the paths specified by the ``HINTS`` option.
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
directory and below.
.. note::
These options are not used when linking.
See the :command:`add_link_options` command for that.
Arguments
^^^^^^^^^
@ -48,5 +53,15 @@ See Also
* 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
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]
[JOB_POOL job_pool]
[VERBATIM] [APPEND] [USES_TERMINAL]
[COMMAND_EXPAND_LISTS])
[COMMAND_EXPAND_LISTS]
[DEPENDS_EXPLICIT_ONLY])
This defines a command to generate specified ``OUTPUT`` file(s).
A target created in the same directory (``CMakeLists.txt`` file)
@ -357,6 +358,24 @@ The options are:
:ref:`Makefile Generators`, :ref:`Visual Studio Generators`,
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
^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -459,7 +478,7 @@ target is already built, the command will not execute.
[BYPRODUCTS [files...]]
[WORKING_DIRECTORY dir]
[COMMENT comment]
[VERBATIM] [USES_TERMINAL]
[VERBATIM]
[COMMAND_EXPAND_LISTS])
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:
``PRE_BUILD``
On :ref:`Visual Studio Generators`, run before any other rules are
executed within the target.
On other generators, run just before ``PRE_LINK`` commands.
This option has unique behavior for the :ref:`Visual Studio Generators`.
When using one of the Visual Studio generators, the command will run before
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``
Run after sources have been compiled but before linking the binary
or running the librarian or archiver tool of a static library.

@ -38,3 +38,7 @@ See Also
* :command:`link_libraries`
* :command:`target_link_libraries`
* :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
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``
Specify the test command-line. If ``<command>`` specifies an
executable target (created by :command:`add_executable`) it will
automatically be replaced by the location of the executable created
at build time.
Specify the test command-line. If ``<command>`` specifies an executable
target created by :command:`add_executable`, it will automatically be
replaced by the location of the executable created at build time.
The command may be specified using
: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.
``WORKING_DIRECTORY``
Set the :prop_test:`WORKING_DIRECTORY` test property to
specify the working directory in which to execute the test.
If not specified the test will be run with the current working
directory set to the build directory corresponding to the
current source directory.
The working directory may be specified using
:manual:`generator expressions <cmake-generator-expressions(7)>`.
Set the test property :prop_test:`WORKING_DIRECTORY` in which to execute the
test. If not specified, the test will be run in
:variable:`CMAKE_CURRENT_BINARY_DIR`. The working directory may be specified
using :manual:`generator expressions <cmake-generator-expressions(7)>`.
``COMMAND_EXPAND_LISTS``
.. versionadded:: 3.16
Lists in ``COMMAND`` arguments will be expanded, including those
created with
Lists in ``COMMAND`` arguments will be expanded, including those created with
:manual:`generator expressions <cmake-generator-expressions(7)>`.
The given test command is expected to exit with code ``0`` to pass and
non-zero to fail, or vice-versa if the :prop_test:`WILL_FAIL` test
property is set. Any output written to stdout or stderr will be
captured by :manual:`ctest(1)` but does not affect the pass/fail status
unless the :prop_test:`PASS_REGULAR_EXPRESSION`,
:prop_test:`FAIL_REGULAR_EXPRESSION` or
:prop_test:`SKIP_REGULAR_EXPRESSION` test property is used.
If the test command exits with code ``0`` the test passes. Non-zero exit code
is a "failed" test. The test property :prop_test:`WILL_FAIL` inverts this
logic. Note that system-level test failures such as segmentation faults or
heap errors will still fail the test even if ``WILL_FALL`` is true. Output
written to stdout or stderr is captured by :manual:`ctest(1)` and only
affects the pass/fail status via the :prop_test:`PASS_REGULAR_EXPRESSION`,
:prop_test:`FAIL_REGULAR_EXPRESSION`, or :prop_test:`SKIP_REGULAR_EXPRESSION`
test properties.
.. versionadded:: 3.16
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:
.. 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
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

@ -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,163 +27,155 @@ those created via the :command:`macro` or :command:`function` commands.
Calling Commands
^^^^^^^^^^^^^^^^
.. _CALL:
.. code-block:: cmake
.. signature::
cmake_language(CALL <command> [<arg>...])
Calls the named ``<command>`` with the given arguments (if any).
For example, the code:
Calls the named ``<command>`` with the given arguments (if any).
For example, the code:
.. code-block:: cmake
.. code-block:: cmake
set(message_command "message")
cmake_language(CALL ${message_command} STATUS "Hello World!")
set(message_command "message")
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::
To ensure consistency of the code, the following commands are not allowed:
.. note::
To ensure consistency of the code, the following commands are not allowed:
* ``if`` / ``elseif`` / ``else`` / ``endif``
* ``block`` / ``endblock``
* ``while`` / ``endwhile``
* ``foreach`` / ``endforeach``
* ``function`` / ``endfunction``
* ``macro`` / ``endmacro``
* ``if`` / ``elseif`` / ``else`` / ``endif``
* ``block`` / ``endblock``
* ``while`` / ``endwhile``
* ``foreach`` / ``endforeach``
* ``function`` / ``endfunction``
* ``macro`` / ``endmacro``
Evaluating Code
^^^^^^^^^^^^^^^
.. _EVAL:
.. code-block:: cmake
.. signature::
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(B TRUE)
set(C TRUE)
set(condition "(A AND B) OR C")
set(A TRUE)
set(B TRUE)
set(C TRUE)
set(condition "(A AND B) OR C")
cmake_language(EVAL CODE "
if (${condition})
message(STATUS TRUE)
else()
message(STATUS FALSE)
endif()"
)
cmake_language(EVAL CODE "
if (${condition})
message(STATUS TRUE)
else()
message(STATUS FALSE)
endif()"
)
is equivalent to
is equivalent to
.. code-block:: cmake
.. code-block:: cmake
set(A TRUE)
set(B TRUE)
set(C TRUE)
set(condition "(A AND B) OR C")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/eval.cmake "
if (${condition})
message(STATUS TRUE)
else()
message(STATUS FALSE)
endif()"
)
set(A TRUE)
set(B TRUE)
set(C TRUE)
set(condition "(A AND B) OR C")
include(${CMAKE_CURRENT_BINARY_DIR}/eval.cmake)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/eval.cmake "
if (${condition})
message(STATUS TRUE)
else()
message(STATUS FALSE)
endif()"
)
include(${CMAKE_CURRENT_BINARY_DIR}/eval.cmake)
Deferring Calls
^^^^^^^^^^^^^^^
.. versionadded:: 3.19
.. _DEFER:
.. code-block:: cmake
.. signature::
cmake_language(DEFER <options>... CALL <command> [<arg>...])
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
written at the end of the current directory's ``CMakeLists.txt`` file,
except that they run even after a :command:`return` call. Variable
references in arguments are evaluated at the time the deferred call is
executed.
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
written at the end of the current directory's ``CMakeLists.txt`` file,
except that they run even after a :command:`return` call. Variable
references in arguments are evaluated at the time the deferred call is
executed.
The options are:
The options are:
``DIRECTORY <dir>``
Schedule the call for the end of the given directory instead of the
current directory. The ``<dir>`` may reference either a source
directory or its corresponding binary directory. Relative paths are
treated as relative to the current source directory.
``DIRECTORY <dir>``
Schedule the call for the end of the given directory instead of the
current directory. The ``<dir>`` may reference either a source
directory or its corresponding binary directory. Relative paths are
treated as relative to the current source directory.
The given directory must be known to CMake, being either the top-level
directory or one added by :command:`add_subdirectory`. Furthermore,
the given directory must not yet be finished processing. This means
it can be the current directory or one of its ancestors.
The given directory must be known to CMake, being either the top-level
directory or one added by :command:`add_subdirectory`. Furthermore,
the given directory must not yet be finished processing. This means
it can be the current directory or one of its ancestors.
``ID <id>``
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 begin with an underscore (``_``) only if it was generated
automatically by an earlier call that used ``ID_VAR`` to get the id.
``ID <id>``
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 begin with an underscore (``_``) only if it was generated
automatically by an earlier call that used ``ID_VAR`` to get the id.
``ID_VAR <var>``
Specify a variable in which to store the identification for the
deferred call. If ``ID <id>`` is not given, a new identification
will be generated and the generated id will start with an underscore (``_``).
``ID_VAR <var>``
Specify a variable in which to store the identification for the
deferred call. If ``ID <id>`` is not given, a new identification
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
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
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.
If that option is not given, the call ids for the current directory scope will
be returned.
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
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``
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 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
Lists>` in which the first element is the name of the command to be
called, and the remaining elements are its unevaluated arguments (any
contained ``;`` characters are included literally and cannot be distinguished
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
the specified ``DIRECTORY`` scope (or the current directory scope if no
``DIRECTORY`` option is given), this stores an empty string in the variable.
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
called, and the remaining elements are its unevaluated arguments (any
contained ``;`` characters are included literally and cannot be distinguished
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
the specified ``DIRECTORY`` scope (or the current directory scope if no
``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
``DIRECTORY`` scope (or the current directory scope if no ``DIRECTORY`` option
is given). Unknown ids are silently ignored.
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
is given). Unknown ids are silently ignored.
Deferred Call Examples
""""""""""""""""""""""
@ -229,8 +221,6 @@ also prints::
Deferred Message 1
Deferred Message 2
.. _SET_DEPENDENCY_PROVIDER:
.. _dependency_providers:
Dependency Providers
@ -241,51 +231,50 @@ Dependency Providers
.. note:: A high-level introduction to this feature can be found in the
:ref:`Using Dependencies Guide <dependency_providers_overview>`.
.. code-block:: cmake
.. signature::
cmake_language(SET_DEPENDENCY_PROVIDER <command>
SUPPORTED_METHODS <methods>...)
When a call is made to :command:`find_package` or
:command:`FetchContent_MakeAvailable`, the call may be forwarded to a
dependency provider which then has the opportunity to fulfill the request.
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
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
is set, the built-in :command:`find_package` or
:command:`FetchContent_MakeAvailable` implementation is used to fulfill
the request in the usual way.
One or more of the following values can be specified for the ``<methods>``
when setting the provider:
``FIND_PACKAGE``
The provider command accepts :command:`find_package` requests.
``FETCHCONTENT_MAKEAVAILABLE_SERIAL``
The provider command accepts :command:`FetchContent_MakeAvailable`
requests. It expects each dependency to be fed to the provider command
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
set when ``cmake_language(SET_DEPENDENCY_PROVIDER)`` is called, the new
provider replaces the previously set one. The specified ``<command>`` must
already exist when ``cmake_language(SET_DEPENDENCY_PROVIDER)`` is called.
As a special case, providing an empty string for the ``<command>`` and no
``<methods>`` will discard any previously set provider.
The dependency provider can only be set while processing one of the files
specified by the :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` variable.
Thus, dependency providers can only be set as part of the first call to
:command:`project`. Calling ``cmake_language(SET_DEPENDENCY_PROVIDER)``
outside of that context will result in an error.
.. note::
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
list in their :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` variable, but
the use of such a file should always be the user's choice.
When a call is made to :command:`find_package` or
:command:`FetchContent_MakeAvailable`, the call may be forwarded to a
dependency provider which then has the opportunity to fulfill the request.
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
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
is set, the built-in :command:`find_package` or
:command:`FetchContent_MakeAvailable` implementation is used to fulfill
the request in the usual way.
One or more of the following values can be specified for the ``<methods>``
when setting the provider:
``FIND_PACKAGE``
The provider command accepts :command:`find_package` requests.
``FETCHCONTENT_MAKEAVAILABLE_SERIAL``
The provider command accepts :command:`FetchContent_MakeAvailable`
requests. It expects each dependency to be fed to the provider command
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
set when ``cmake_language(SET_DEPENDENCY_PROVIDER)`` is called, the new
provider replaces the previously set one. The specified ``<command>`` must
already exist when ``cmake_language(SET_DEPENDENCY_PROVIDER)`` is called.
As a special case, providing an empty string for the ``<command>`` and no
``<methods>`` will discard any previously set provider.
The dependency provider can only be set while processing one of the files
specified by the :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` variable.
Thus, dependency providers can only be set as part of the first call to
:command:`project`. Calling ``cmake_language(SET_DEPENDENCY_PROVIDER)``
outside of that context will result in an error.
.. note::
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
list in their :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` variable, but
the use of such a file should always be the user's choice.
Provider commands
"""""""""""""""""
@ -499,23 +488,21 @@ Getting current message log level
.. versionadded:: 3.25
.. _GET_MESSAGE_LOG_LEVEL:
.. _query_message_log_level:
.. code-block:: cmake
.. signature::
cmake_language(GET_MESSAGE_LOG_LEVEL <output_variable>)
Writes the current :command:`message` logging level
into the given ``<output_variable>``.
Writes the current :command:`message` logging level
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
:option:`--log-level <cmake --log-level>`
command line option of the :manual:`cmake(1)` program or using
the :variable:`CMAKE_MESSAGE_LOG_LEVEL` variable.
The current message logging level can be set either using the
:option:`--log-level <cmake --log-level>`
command line option of the :manual:`cmake(1)` program or using
the :variable:`CMAKE_MESSAGE_LOG_LEVEL` variable.
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
is returned.
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
is returned.

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

@ -13,10 +13,6 @@ variables that are created by the project command.
.. 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.
Furthermore, it must be called in the highest directory common to all
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_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``
and ``PATH``.
.. |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_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``
and ``PATH``.
.. |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
enabled.
1. .. versionadded:: 3.12
Search paths specified in the :variable:`<PackageName>_ROOT` CMake
variable and the :envvar:`<PackageName>_ROOT` environment variable,
where ``<PackageName>`` is the package to be found
(the case-preserved first argument to ``find_package``).
The package root variables are maintained as a stack so if
called from within a find module, root paths from the parent's find
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
the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
See policy :policy:`CMP0074`.
1. Search prefixes unique to the current ``<PackageName>`` being found.
See policy :policy:`CMP0074`.
.. versionadded:: 3.12
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
called from within a find module, root paths from the parent's find
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
the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
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>`.
@ -398,8 +418,8 @@ enabled.
* ``<PackageName>_DIR``
* :envvar:`CMAKE_PREFIX_PATH`
* ``CMAKE_FRAMEWORK_PATH``
* ``CMAKE_APPBUNDLE_PATH``
* :envvar:`CMAKE_FRAMEWORK_PATH`
* :envvar:`CMAKE_APPBUNDLE_PATH`
4. Search paths specified by the ``HINTS`` option. These should be paths
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_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``
and ``PATH``.
.. |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_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_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.
.. versionchanged:: 3.20
This command has been superseded by :command:`cmake_path` command, except
``REALPATH`` now offered by :ref:`file(REAL_PATH)<REAL_PATH>` command and
``PROGRAM`` now available in :command:`separate_arguments(PROGRAM)` command.
This command has been superseded by the :command:`cmake_path` command, except
for ``REALPATH``, which is now offered by :command:`file(REAL_PATH)`, and
``PROGRAM``, now available in :command:`separate_arguments(PROGRAM)`.
.. versionchanged:: 3.24
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:
1. Parentheses.
1. `Parentheses`_.
2. Unary tests such as `EXISTS`_, `COMMAND`_, and `DEFINED`_.
@ -57,262 +57,284 @@ Compound conditions are evaluated in the following order of precedence:
Basic Expressions
"""""""""""""""""
``if(<constant>)``
True if the constant is ``1``, ``ON``, ``YES``, ``TRUE``, ``Y``,
or a non-zero number (including floating point numbers).
False if the constant is ``0``, ``OFF``,
``NO``, ``FALSE``, ``N``, ``IGNORE``, ``NOTFOUND``, the empty string,
or ends in the suffix ``-NOTFOUND``. Named boolean constants are
case-insensitive. If the argument is not one of these specific
constants, it is treated as a variable or string (see `Variable Expansion`_
further below) and one of the following two forms applies.
``if(<variable>)``
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.
Note that macro arguments are not variables.
:ref:`Environment Variables <CMake Language Environment Variables>` also
cannot be tested this way, e.g. ``if(ENV{some_var})`` will always evaluate
to false.
``if(<string>)``
A quoted string always evaluates to false unless:
* The string's value is one of the true constants, or
* Policy :policy:`CMP0054` is not set to ``NEW`` and the string's value
happens to be a variable name that is affected by :policy:`CMP0054`'s
behavior.
.. signature:: if(<constant>)
:target: constant
True if the constant is ``1``, ``ON``, ``YES``, ``TRUE``, ``Y``,
or a non-zero number (including floating point numbers).
False if the constant is ``0``, ``OFF``,
``NO``, ``FALSE``, ``N``, ``IGNORE``, ``NOTFOUND``, the empty string,
or ends in the suffix ``-NOTFOUND``. Named boolean constants are
case-insensitive. If the argument is not one of these specific
constants, it is treated as a variable or string (see `Variable Expansion`_
further below) and one of the following two forms applies.
.. signature:: if(<variable>)
:target: variable
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.
Note that macro arguments are not variables.
:ref:`Environment Variables <CMake Language Environment Variables>` also
cannot be tested this way, e.g. ``if(ENV{some_var})`` will always evaluate
to false.
.. signature:: if(<string>)
:target: string
A quoted string always evaluates to false unless:
* The string's value is one of the true constants, or
* Policy :policy:`CMP0054` is not set to ``NEW`` and the string's value
happens to be a variable name that is affected by :policy:`CMP0054`'s
behavior.
Logic Operators
"""""""""""""""
.. _NOT:
.. signature:: if(NOT <condition>)
True if the condition is not true.
``if(NOT <condition>)``
True if the condition is not true.
.. signature:: if(<cond1> AND <cond2>)
:target: AND
.. _AND:
True if both conditions would be considered true individually.
``if(<cond1> AND <cond2>)``
True if both conditions would be considered true individually.
.. signature:: if(<cond1> OR <cond2>)
:target: OR
.. _OR:
True if either condition would be considered true individually.
``if(<cond1> OR <cond2>)``
True if either condition would be considered true individually.
.. signature:: if((condition) AND (condition OR (condition)))
:target: parentheses
``if((condition) AND (condition OR (condition)))``
The conditions inside the parenthesis are evaluated first and then
the remaining condition is evaluated as in the other examples.
Where there are nested parenthesis the innermost are evaluated as part
of evaluating the condition that contains them.
The conditions inside the parenthesis are evaluated first and then
the remaining condition is evaluated as in the other examples.
Where there are nested parenthesis the innermost are evaluated as part
of evaluating the condition that contains them.
Existence Checks
""""""""""""""""
.. _COMMAND:
.. signature:: if(COMMAND <command-name>)
True if the given name is a command, macro or function that can be
invoked.
.. signature:: if(POLICY <policy-id>)
True if the given name is an existing policy (of the form ``CMP<NNNN>``).
``if(COMMAND command-name)``
True if the given name is a command, macro or function that can be
invoked.
.. signature:: if(TARGET <target-name>)
``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 logical target name created
by a call to the :command:`add_executable`, :command:`add_library`,
or :command:`add_custom_target` command that has already been invoked
(in any directory).
``if(TARGET target-name)``
True if the given name is an existing logical target name created
by a call to the :command:`add_executable`, :command:`add_library`,
or :command:`add_custom_target` command that has already been invoked
(in any directory).
.. signature:: if(TEST <test-name>)
.. versionadded:: 3.3
``if(TEST test-name)``
.. versionadded:: 3.3
True if the given name is an existing test name created by the
: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
with given ``<name>`` is defined. The value of the variable
does not matter. Note the following caveats:
True if a variable, cache variable or environment variable
with given ``<name>`` is defined. The value of the variable
does not matter. Note the following caveats:
* Macro arguments are not variables.
* It is not possible to test directly whether a `<name>` is a non-cache
variable. The expression ``if(DEFINED someName)`` will evaluate to true
if either a cache or non-cache variable ``someName`` exists. In
comparison, the expression ``if(DEFINED CACHE{someName})`` will only
evaluate to true if a cache variable ``someName`` exists. Both expressions
need to be tested if you need to know whether a non-cache variable exists:
``if(DEFINED someName AND NOT DEFINED CACHE{someName})``.
* Macro arguments are not variables.
* It is not possible to test directly whether a `<name>` is a non-cache
variable. The expression ``if(DEFINED someName)`` will evaluate to true
if either a cache or non-cache variable ``someName`` exists. In
comparison, the expression ``if(DEFINED CACHE{someName})`` will only
evaluate to true if a cache variable ``someName`` exists. Both expressions
need to be tested if you need to know whether a non-cache variable exists:
``if(DEFINED someName AND NOT DEFINED CACHE{someName})``.
.. versionadded:: 3.14
Added support for ``CACHE{<name>}`` variables.
``if(<variable|string> IN_LIST <variable>)``
.. versionadded:: 3.3
.. signature:: if(<variable|string> IN_LIST <variable>)
:target: IN_LIST
.. versionadded:: 3.3
True if the given element is contained in the named list variable.
File Operations
"""""""""""""""
.. _EXISTS:
.. signature:: if(EXISTS <path-to-file-or-directory>)
True if the named file or directory exists. Behavior is well-defined
only for explicit full paths (a leading ``~/`` is not expanded as
a home directory and is considered a relative path).
Resolves symbolic links, i.e. if the named file or directory is a
symbolic link, returns true if the target of the symbolic link exists.
False if the given path is an empty string.
``if(EXISTS path-to-file-or-directory)``
True if the named file or directory exists. Behavior is well-defined
only for explicit full paths (a leading ``~/`` is not expanded as
a home directory and is considered a relative path).
Resolves symbolic links, i.e. if the named file or directory is a
symbolic link, returns true if the target of the symbolic link exists.
.. signature:: if(<file1> IS_NEWER_THAN <file2>)
:target: IS_NEWER_THAN
False if the given path is an empty string.
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
time stamps are exactly the same, an ``IS_NEWER_THAN`` comparison returns
true, so that any dependent build operations will occur in the event
of a tie. This includes the case of passing the same file name for
both file1 and file2.
``if(file1 IS_NEWER_THAN file2)``
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
time stamps are exactly the same, an ``IS_NEWER_THAN`` comparison returns
true, so that any dependent build operations will occur in the event
of a tie. This includes the case of passing the same file name for
both file1 and file2.
.. signature:: if(IS_DIRECTORY <path>)
``if(IS_DIRECTORY path)``
True if ``path`` is a directory. Behavior is well-defined only
for full paths.
True if ``path`` is a directory. Behavior is well-defined only
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)``
True if the given name is a symbolic link. Behavior is well-defined
only for full paths.
.. signature:: if(IS_SYMLINK <path>)
``if(IS_ABSOLUTE path)``
True if the given path is an absolute path. Note the following special
cases:
True if the given path is a symbolic link. Behavior is well-defined
only for full paths.
* An empty ``path`` evaluates to false.
* On Windows hosts, any ``path`` that begins with a drive letter and colon
(e.g. ``C:``), a forward slash or a backslash will evaluate to true.
This means a path like ``C:no\base\dir`` will evaluate to true, even
though the non-drive part of the path is relative.
* On non-Windows hosts, any ``path`` that begins with a tilde (``~``)
evaluates to true.
.. signature:: if(IS_ABSOLUTE <path>)
True if the given path is an absolute path. Note the following special
cases:
* An empty ``path`` evaluates to false.
* On Windows hosts, any ``path`` that begins with a drive letter and colon
(e.g. ``C:``), a forward slash or a backslash will evaluate to true.
This means a path like ``C:no\base\dir`` will evaluate to true, even
though the non-drive part of the path is relative.
* On non-Windows hosts, any ``path`` that begins with a tilde (``~``)
evaluates to true.
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
expression. See :ref:`Regex Specification` for regex format.
True if the given string or variable's value matches the given regular
expression. See :ref:`Regex Specification` for regex format.
.. versionadded:: 3.9
``()`` groups are captured in :variable:`CMAKE_MATCH_<n>` variables.
.. versionadded:: 3.9
``()`` 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
than that on the right.
True if the given string or variable's value is a valid number and less
than that on the right.
.. _GREATER:
.. signature:: if(<variable|string> GREATER <variable|string>)
:target: GREATER
True if the given string or variable's value is a valid number and greater
than that on the right.
``if(<variable|string> GREATER <variable|string>)``
True if the given string or variable's value is a valid number and greater
than that on the right.
.. signature:: if(<variable|string> EQUAL <variable|string>)
:target: EQUAL
.. _EQUAL:
True if the given string or variable's value is a valid number and equal
to that on the right.
``if(<variable|string> EQUAL <variable|string>)``
True if the given string or variable's value is a valid number and equal
to that on the right.
.. signature:: if(<variable|string> LESS_EQUAL <variable|string>)
:target: LESS_EQUAL
.. _LESS_EQUAL:
.. versionadded:: 3.7
``if(<variable|string> LESS_EQUAL <variable|string>)``
.. versionadded:: 3.7
True if the given string or variable's value is a valid number and less
than or equal to that on the right.
.. _GREATER_EQUAL:
.. signature:: if(<variable|string> GREATER_EQUAL <variable|string>)
:target: GREATER_EQUAL
.. versionadded:: 3.7
``if(<variable|string> GREATER_EQUAL <variable|string>)``
.. versionadded:: 3.7
True if the given string or variable's value is a valid number and greater
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
than the string or variable on the right.
True if the given string or variable's value is lexicographically less
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
than the string or variable on the right.
True if the given string or variable's value is lexicographically greater
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
to the string or variable on the right.
True if the given string or variable's value is lexicographically equal
to the string or variable on the right.
.. _STRLESS_EQUAL:
.. signature:: if(<variable|string> STRLESS_EQUAL <variable|string>)
:target: STRLESS_EQUAL
.. versionadded:: 3.7
``if(<variable|string> STRLESS_EQUAL <variable|string>)``
.. versionadded:: 3.7
True if the given string or variable's value is lexicographically less
than or equal to the string or variable on the right.
.. _STRGREATER_EQUAL:
.. signature:: if(<variable|string> STRGREATER_EQUAL <variable|string>)
:target: STRGREATER_EQUAL
.. versionadded:: 3.7
``if(<variable|string> STRGREATER_EQUAL <variable|string>)``
.. versionadded:: 3.7
True if the given string or variable's value is lexicographically greater
than or equal to the string or variable on the right.
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
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
Any non-integer version component or non-integer trailing part of a version
component effectively truncates the string at that point.
Component-wise integer version number comparison (version format is
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
Any non-integer version component or non-integer trailing part of a version
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
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
Any non-integer version component or non-integer trailing part of a version
component effectively truncates the string at that point.
Component-wise integer version number comparison (version format is
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
Any non-integer version component or non-integer trailing part of a version
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
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
Any non-integer version component or non-integer trailing part of a version
component effectively truncates the string at that point.
Component-wise integer version number comparison (version format is
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
Any non-integer version component or non-integer trailing part of a version
component effectively truncates the string at that point.
.. _VERSION_LESS_EQUAL:
.. signature:: if(<variable|string> VERSION_LESS_EQUAL <variable|string>)
:target: VERSION_LESS_EQUAL
.. versionadded:: 3.7
``if(<variable|string> VERSION_LESS_EQUAL <variable|string>)``
.. versionadded:: 3.7
Component-wise integer version number comparison (version format is
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
Any non-integer version component or non-integer trailing part of a version
component effectively truncates the string at that point.
.. _VERSION_GREATER_EQUAL:
.. signature:: if(<variable|string> VERSION_GREATER_EQUAL <variable|string>)
:target: VERSION_GREATER_EQUAL
.. versionadded:: 3.7
``if(<variable|string> VERSION_GREATER_EQUAL <variable|string>)``
.. versionadded:: 3.7
Component-wise integer version number comparison (version format is
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
Any non-integer version component or non-integer trailing part of a version
@ -321,9 +343,9 @@ Version 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
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
above-documented condition syntax accepts ``<variable|string>``:
* 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
* 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
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
* Both left and right hand arguments to ``LESS``, ``GREATER``, ``EQUAL``,
``LESS_EQUAL``, and ``GREATER_EQUAL``, are independently tested to see if
they are defined variables, if so their defined values are used otherwise
* Both left and right hand arguments to `LESS`_, `GREATER`_, `EQUAL`_,
`LESS_EQUAL`_, and `GREATER_EQUAL`_, are independently tested to see if
they are defined variables. If so, their defined values are used otherwise
the original value is used.
* Both left and right hand arguments to ``STRLESS``, ``STRGREATER``,
``STREQUAL``, ``STRLESS_EQUAL``, and ``STRGREATER_EQUAL`` are independently
tested to see if they are defined variables, if so their defined values are
* Both left and right hand arguments to `STRLESS`_, `STRGREATER`_,
`STREQUAL`_, `STRLESS_EQUAL`_, and `STRGREATER_EQUAL`_ are independently
tested to see if they are defined variables. If so, their defined values are
used otherwise the original value is used.
* Both left and right hand arguments to ``VERSION_LESS``,
``VERSION_GREATER``, ``VERSION_EQUAL``, ``VERSION_LESS_EQUAL``, and
``VERSION_GREATER_EQUAL`` are independently tested to see if they are defined
variables, if so their defined values are used otherwise the original value
* Both left and right hand arguments to `VERSION_LESS`_,
`VERSION_GREATER`_, `VERSION_EQUAL`_, `VERSION_LESS_EQUAL`_, and
`VERSION_GREATER_EQUAL`_ are independently tested to see if they are defined
variables. If so, their defined values are used otherwise the original value
is used.
* 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
* 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
variable and it is dereferenced.
* 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
* 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
such, otherwise they are assumed to be variables and are dereferenced.
.. versionchanged:: 3.1

@ -25,7 +25,7 @@ prepending, independent of the default.
If the ``SYSTEM`` option is given, the compiler will be told the
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
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``);
* On AIX, the *linker import file* created for executables with
: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``
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
``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:
.. 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
``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
``COMPONENT`` may be used to specify the installation component of the
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
``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
is not recommended to use ``NAMELINK_SKIP`` in conjunction with
``NAMELINK_COMPONENT``.

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

@ -105,6 +105,9 @@ The options are:
.. 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``
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``
.. _`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

@ -8,109 +8,119 @@ and cache entries.
Signatures of this command that specify a ``<value>...`` placeholder
expect zero or more arguments. Multiple arguments will be joined as
a :ref:`semicolon-separated list <CMake Language Lists>` to form the actual variable
value to be set. Zero arguments will cause normal variables to be
unset. See the :command:`unset` command to unset variables explicitly.
a :ref:`semicolon-separated list <CMake Language Lists>` to form the
actual variable value to be set.
Set Normal Variable
^^^^^^^^^^^^^^^^^^^
.. code-block:: cmake
.. signature::
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 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).
The :command:`block(PROPAGATE)` and :command:`return(PROPAGATE)` commands
can be used as an alternate method to the :command:`set(PARENT_SCOPE)`
and :command:`unset(PARENT_SCOPE)` commands to update the parent scope.
The :command:`block(PROPAGATE)` and :command:`return(PROPAGATE)` commands can
be used as an alternate method to the :command:`set(PARENT_SCOPE)` and
:command:`unset(PARENT_SCOPE)` commands to update the parent scope.
.. include:: UNSET_NOTE.txt
Set Cache Entry
^^^^^^^^^^^^^^^
.. code-block:: cmake
.. signature::
set(<variable> <value>... CACHE <type> <docstring> [FORCE])
Sets the given cache ``<variable>`` (cache entry). Since cache entries
are meant to provide user-settable values this does not overwrite
existing cache entries by default. Use the ``FORCE`` option to
overwrite existing entries.
The ``<type>`` must be specified as one of:
``BOOL``
Boolean ``ON/OFF`` value. :manual:`cmake-gui(1)` offers a checkbox.
``FILEPATH``
Path to a file on disk. :manual:`cmake-gui(1)` offers a file dialog.
``PATH``
Path to a directory on disk. :manual:`cmake-gui(1)` offers a file dialog.
``STRING``
A line of text. :manual:`cmake-gui(1)` offers a text field or a
drop-down selection if the :prop_cache:`STRINGS` cache entry
property is set.
``INTERNAL``
A line of text. :manual:`cmake-gui(1)` does not show internal entries.
They may be used to store variables persistently across runs.
Use of this type implies ``FORCE``.
The ``<docstring>`` must be specified as a line of text providing
a quick summary of the option for presentation to :manual:`cmake-gui(1)`
users.
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.
.. note::
The content of the cache variable will not be directly accessible if a normal
variable of the same name already exists (see :ref:`rules of variable
evaluation <CMake Language Variables>`). 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
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
specifying a type. In this case the ``set`` command will add the
type. Furthermore, if the ``<type>`` is ``PATH`` or ``FILEPATH``
and the ``<value>`` provided on the command line is a relative path,
then the ``set`` command will treat the path as relative to the
current working directory and convert it to an absolute path.
:target: CACHE
Sets the given cache ``<variable>`` (cache entry). Since cache entries
are meant to provide user-settable values this does not overwrite
existing cache entries by default. Use the ``FORCE`` option to
overwrite existing entries.
The ``<type>`` must be specified as one of:
``BOOL``
Boolean ``ON/OFF`` value.
:manual:`cmake-gui(1)` offers a checkbox.
``FILEPATH``
Path to a file on disk.
:manual:`cmake-gui(1)` offers a file dialog.
``PATH``
Path to a directory on disk.
:manual:`cmake-gui(1)` offers a file dialog.
``STRING``
A line of text.
:manual:`cmake-gui(1)` offers a text field or a drop-down selection
if the :prop_cache:`STRINGS` cache entry property is set.
``INTERNAL``
A line of text.
:manual:`cmake-gui(1)` does not show internal entries.
They may be used to store variables persistently across runs.
Use of this type implies ``FORCE``.
The ``<docstring>`` must be specified as a line of text
providing a quick summary of the option
for presentation to :manual:`cmake-gui(1)` users.
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.
.. note::
The content of the cache variable will not be directly accessible
if a normal variable of the same name already exists
(see :ref:`rules of variable evaluation <CMake Language Variables>`).
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
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 specifying a type. In this case the ``set`` command will add the
type. Furthermore, if the ``<type>`` is ``PATH`` or ``FILEPATH``
and the ``<value>`` provided on the command line is a relative path,
then the ``set`` command will treat the path as relative to the
current working directory and convert it to an absolute path.
Set Environment Variable
^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: cmake
.. signature::
set(ENV{<variable>} [<value>])
:target: ENV
Sets an :manual:`Environment Variable <cmake-env-variables(7)>`
to the given value.
Subsequent calls of ``$ENV{<variable>}`` will return this new value.
Sets an :manual:`Environment Variable <cmake-env-variables(7)>`
to the given value.
Subsequent calls of ``$ENV{<variable>}`` will return this new value.
This command affects only the current CMake process, not the process
from which CMake was called, nor the system environment at large,
nor the environment of subsequent build or test processes.
This command affects only the current CMake process, not the process
from which CMake was called, nor the system environment at large,
nor the environment of subsequent build or test processes.
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
environment variable.
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
environment variable.
Arguments after ``<value>`` are ignored. If extra arguments are found,
then an author warning is issued.
Arguments after ``<value>`` are ignored. If extra arguments are found,
then an author warning is issued.
See Also
^^^^^^^^

@ -38,6 +38,8 @@ It must be one of the following:
Scope may name zero or more existing targets.
See also the :command:`set_target_properties` command.
:ref:`Alias Targets` do not support setting target properties.
``SOURCE``
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``).
@ -82,15 +84,15 @@ It must be one of the following:
to the installation prefix.
``TEST``
Scope may name zero or more existing tests.
See also the :command:`set_tests_properties` command.
Scope is limited to the directory the command is called in. It may name zero
or more existing tests. See also command :command:`set_tests_properties`.
Test property values may be specified using
:manual:`generator expressions <cmake-generator-expressions(7)>`
for tests created by the :command:`add_test(NAME)` signature.
``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 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`
command.
:ref:`Alias Targets` do not support setting target properties.
See Also
^^^^^^^^

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

@ -12,19 +12,14 @@ Unset Normal Variable or Cache Entry
Removes a normal variable from the current scope, causing it
to become undefined. If ``CACHE`` is present, then a cache variable
is removed instead of a normal variable. Note that 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.
is removed instead of a normal variable.
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
for further details.
.. include:: UNSET_NOTE.txt
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
.. _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 specification: https://spdx.github.io/spdx-spec/SPDX-license-expressions
.. _SPDX license identifier: https://spdx.org/licenses
.. _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

@ -111,7 +111,7 @@ Windows using WiX.
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
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
@ -319,7 +319,7 @@ Windows using WiX.
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
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

@ -168,46 +168,175 @@ documentation:
See the `cmake-variables(7)`_ manual
and the `set()`_ command.
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
type ``<type>``. The object name is extracted from the document title,
which is expected to be of the form::
<object-name>
-------------
and to appear at or near the top of the ``.rst`` file before any other
lines starting in a letter, digit, ``<``, or ``$``. If no such title appears
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
to ``<object-name>`` with any ``<`` and ``>`` characters removed,
or in the case of a ``$<genex-name>`` or ``$<genex-name:...>``, the
``genex-name``.
Second, the CMake Domain provides directives to define objects inside
other documents:
Documentation objects in the CMake Domain come from two sources:
1. The CMake extension to Sphinx transforms every document named
with the form ``Help/<type>/<file-name>.rst`` to a domain object with
type ``<type>``. The object name is extracted from the document title,
which is expected to be of the form::
<object-name>
-------------
and to appear at or near the top of the ``.rst`` file before any other lines
starting in a letter, digit, ``<``, or ``$``. If no such title appears
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
to ``<object-name>`` with any ``<`` and ``>`` characters removed,
or in the case of a ``$<genex-name>`` or ``$<genex-name:...>``, the
``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
^^^^^^^^^^^^^^^^^^^^^
Document a "command" object:
.. code-block:: rst
.. command:: <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
.. command:: <command-name>
.. envvar:: <envvar-name>
This indented block documents <envvar-name>.
The directive requires a single argument, the environment variable name.
This indented block documents <command-name>.
``genex`` directive
^^^^^^^^^^^^^^^^^^^
.. envvar:: <envvar-name>
Document a "genex" object:
This indented block documents <envvar-name>.
.. code-block:: rst
.. genex:: <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>
This indented block documents <variable-name>.
Object types for which no directive is available must be defined using
the first approach above.
The directive requires a single argument, the variable name.
.. _`Sphinx Domain`: http://sphinx-doc.org/domains.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 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(APPEND)`: 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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Command signatures should be marked up as plain literal blocks, not as
cmake ``code-blocks``.
Signatures are separated from preceding content by a section header.
That is, use:
A ``Help/command/<command-name>.rst`` document defines one ``command``
object in the `CMake Domain`_, but some commands have multiple signatures.
Use the CMake Domain's `signature directive`_ to document each signature.
Separate signatures from preceding content by a section header.
For example:
.. code-block:: rst
@ -342,17 +475,23 @@ That is, use:
Normal Libraries
^^^^^^^^^^^^^^^^
::
.. signature::
add_library(<lib> ...)
This signature is used for ...
This signature is used for ...
Use the following conventions in command signature documentation:
* Use an angle-bracket ``<placeholder>`` for arguments to be specified
by the caller. Refer to them in prose using
`inline literal <Style: Inline Literals_>`_ syntax.
* Wrap optional parts with square brackets.
* Mark repeatable parts with a trailing ellipsis (``...``).
Signatures of commands should wrap optional parts with square brackets,
and should mark list of optional arguments with an ellipsis (``...``).
Elements of the signature which are specified by the user should be
specified with angle brackets, and may be referred to in prose using
``inline-literal`` syntax.
The ``signature`` directive may be used multiple times for different
signatures of the same command.
Style: Boolean Constants
^^^^^^^^^^^^^^^^^^^^^^^^

@ -18,7 +18,7 @@ C++20 Module APIs
=================
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
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``
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:
* 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
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
string(CONCAT CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE
"<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> <SOURCE>"
" -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).
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
----------
.. 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.
Project files for CodeBlocks will be created in the top directory and

@ -1,6 +1,12 @@
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.
Project files for CodeLite will be created in the top directory and

@ -1,6 +1,12 @@
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.
Project files for Eclipse will be created in the top directory. In

@ -1,6 +1,12 @@
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.
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``
Generate with :generator:`Ninja`.
``Kate - Ninja Multi-Config``
Generate with :generator:`Ninja Multi-Config`.
``Kate - Unix Makefiles``
Generate with :generator:`Unix Makefiles`.

@ -1,6 +1,12 @@
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.
Project files for Sublime Text 2 will be created in the top directory

@ -1,7 +1,15 @@
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
^^^^^^^^^^^^^^^^^^

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

@ -285,9 +285,9 @@ command.
:end-before: # include CMakePackageConfigHelpers macro
This command generates the ``MathFunctionsTargets.cmake`` file and arranges
to install it to ``lib/cmake``. The file contains code suitable for
use by downstreams to import all targets listed in the install command from
the installation tree.
to install it to ``${CMAKE_INSTALL_LIBDIR}/cmake/MathFunctions``. The file
contains code suitable for use by downstreams to import all targets listed in
the install command from the installation tree.
The ``NAMESPACE`` option will prepend ``MathFunctions::`` to the target names
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
: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 )
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
:language: cmake
:start-after: # add the executable
:end-before: # TODO 9:
:end-before: # TODO 3:
.. raw:: html
@ -240,7 +240,7 @@ the following:
:name: tutorial.cxx-cxx11
:language: c++
:start-after: // convert input to double
:end-before: // TODO 12:
:end-before: // TODO 6:
.. raw:: html
@ -265,7 +265,7 @@ add the :variable:`CMAKE_CXX_STANDARD` declarations above the call to
:name: CMakeLists.txt-CXX_STANDARD
:language: cmake
:start-after: # specify the C++ standard
:end-before: # TODO 7:
:end-before: # configure a header file
.. raw:: html
@ -375,7 +375,7 @@ specified CMake variables replaced:
:name: CMakeLists.txt-configure_file
:language: cmake
:start-after: # to the source code
:end-before: # TODO 8:
:end-before: # TODO 2:
.. raw:: html
@ -420,7 +420,6 @@ be replaced with the corresponding version numbers from the project in
:caption: TODO 10: TutorialConfig.h.in
:name: TutorialConfig.h.in
:language: c++
:end-before: // TODO 13:
.. 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
be nested.
Exercise 1 - Setting the C++ Standard with Interface Libraries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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
Exercise 1 - Adding Compiler Warning Flags with Generator Expressions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A common usage of
@ -199,8 +57,8 @@ Files to Edit
Getting Started
---------------
Start with the resulting files from Exercise 1. Complete ``TODO 4`` through
``TODO 7``.
Open the file ``Step4/CMakeLists.txt`` and complete ``TODO 1`` through
``TODO 4``.
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
@ -214,12 +72,16 @@ given a language and a set of compiler ids.
Build and Run
-------------
Since we have our build directory already configured from Exercise 1, simply
rebuild our code by calling the following:
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.
.. code-block:: console
mkdir Step4_build
cd Step4_build
cmake ../Step4
cmake --build .
Solution
@ -230,10 +92,10 @@ version ``3.15``:
.. 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
:caption: TODO 4: CMakeLists.txt
:caption: TODO 1: CMakeLists.txt
:name: MathFunctions-CMakeLists.txt-minimum-required-step4
:language: cmake
:end-before: # set the project name and version
@ -249,10 +111,10 @@ variables ``gcc_like_cxx`` and ``msvc_cxx`` as follows:
.. 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
:caption: TODO 5: CMakeLists.txt
:caption: TODO 2: CMakeLists.txt
:name: CMakeLists.txt-compile_lang_and_id
:language: cmake
:start-after: # the BUILD_INTERFACE genex
@ -270,10 +132,10 @@ interface library.
.. 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
:caption: TODO 6: CMakeLists.txt
:caption: TODO 3: CMakeLists.txt
:name: CMakeLists.txt-compile_flags
target_compile_options(tutorial_compiler_flags INTERFACE
@ -292,14 +154,14 @@ condition. The resulting full code looks like the following:
.. 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
:caption: TODO 7: CMakeLists.txt
:caption: TODO 4: CMakeLists.txt
:name: CMakeLists.txt-target_compile_options-genex
:language: cmake
: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

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

@ -100,7 +100,7 @@ follows:
:name: MathFunctions/CMakeLists.txt-target_include_directories-INTERFACE
:language: cmake
:start-after: # to find MathFunctions.h
:end-before: # TODO 3: Link to
:end-before: # should we use our own
.. raw:: html
@ -108,24 +108,26 @@ follows:
Now that we've specified usage requirements for ``MathFunctions`` we can
safely remove our uses of the ``EXTRA_INCLUDES`` variable from the top-level
``CMakeLists.txt``, here:
``CMakeLists.txt``.
Remove this line:
.. raw:: html
<details><summary>TODO 2: Click to show/hide answer</summary>
.. literalinclude:: Step4/CMakeLists.txt
.. literalinclude:: Step3/CMakeLists.txt
:caption: TODO 2: CMakeLists.txt
:name: CMakeLists.txt-remove-EXTRA_INCLUDES
:language: cmake
:start-after: # add the MathFunctions library
:start-after: add_subdirectory(MathFunctions)
:end-before: # add the executable
.. raw:: html
</details>
And here:
And the lines:
.. raw:: html
@ -141,7 +143,181 @@ And here:
</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
use our library is call :command:`target_link_libraries` with the name
of the library target. In larger projects, the classic method of specifying
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++
code and that the output filename is passed in as an argument.
The next step is to add the appropriate commands to the
``MathFunctions/CMakeLists.txt`` file to build the MakeTable executable and
The next step is to create ``MathFunctions/MakeTable.cmake``. Then, add the
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
accomplish this.
First, at the top of ``MathFunctions/CMakeLists.txt``, the executable for
``MakeTable`` is added as any other executable would be added.
First, we add an executable for ``MakeTable``.
.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_executable-MakeTable
.. literalinclude:: Step9/MathFunctions/MakeTable.cmake
:caption: MathFunctions/MakeTable.cmake
:name: MathFunctions/MakeTable.cmake-add_executable-MakeTable
:language: cmake
: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``
by running MakeTable.
.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_custom_command-Table.h
.. literalinclude:: Step9/MathFunctions/MakeTable.cmake
:caption: MathFunctions/MakeTable.cmake
:name: MathFunctions/MakeTable.cmake-add_custom_command-Table.h
:language: cmake
: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
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
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_library-Table.h
:language: cmake
:start-after: # add the main library
:end-before: # state that anybody linking
:start-after: # library that just does sqrt
:end-before: # state that we depend on
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``.
@ -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
:language: cmake
: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
``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.
For this tutorial we will put the library into a subdirectory called
``MathFunctions``. This directory already contains a header file,
``MathFunctions.h``, and a source file ``mysqrt.cxx``. We will not need to
modify either of these files. The source file has one function called
``MathFunctions``. This directory already contains the header files
``MathFunctions.h`` and ``mysqrt.h``. Their respective source files
``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``
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
complete through ``TODO 6``.
@ -91,18 +93,18 @@ Solution
In the ``CMakeLists.txt`` file in the ``MathFunctions`` directory, we create
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:
.. raw:: html
.. raw:: html/
<details><summary>TODO 1: Click to show/hide answer</summary>
.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
.. code-block:: cmake
:caption: TODO 1: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_library
:language: cmake
:end-before: # TODO 1
add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
.. 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>
.. code-block:: c++
:caption: TODO 5 : tutorial.cxx
:name: tutorial.cxx-include_MathFunctions.h
#include "MathFunctions.h"
.. literalinclude:: Step3/tutorial.cxx
:caption: TODO 5: tutorial.cxx
:name: CMakeLists.txt-include-MathFunctions.h
:language: cmake
:start-after: #include <string>
:end-before: #include "TutorialConfig.h"
.. raw:: html
</details>
Lastly, replace ``sqrt`` with our library function ``mysqrt``.
Lastly, replace ``sqrt`` with our library function ``mathfunctions::mysqrt``.
.. raw:: html
<details><summary>TODO 6: Click to show/hide answer</summary>
.. code-block:: c++
:caption: TODO 6 : tutorial.cxx
:name: tutorial.cxx-call_mysqrt
const double outputValue = mysqrt(inputValue);
.. literalinclude:: Step3/tutorial.cxx
:caption: TODO 6: tutorial.cxx
:name: CMakeLists.txt-option
:language: cmake
:start-after: const double inputValue = std::stod(argv[1]);
:end-before: std::cout
.. raw:: html
</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
occurrence.
@ -219,30 +225,32 @@ Helpful Resources
-----------------
* :command:`if`
* :command:`list`
* :command:`option`
* :command:`cmakedefine <configure_file>`
* :command:`target_compile_definitions`
Files to Edit
-------------
* ``CMakeLists.txt``
* ``tutorial.cxx``
* ``TutorialConfig.h.in``
* ``MathFunctions/CMakeLists.txt``
* ``MathFunctions/MathFunctions.cxx``
Getting Started
---------------
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
in the top-level ``CMakeLists.txt`` file. In that same file, use that option
to determine whether to build and use the ``MathFunctions`` library.
in ``MathFunctions/CMakeLists.txt``. In that same file, use that option
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``.
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
-------------
@ -279,7 +287,7 @@ or ``mysqrt``?
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
:manual:`ccmake <ccmake(1)>` with a default value of ``ON`` that can be
changed by the user.
@ -288,172 +296,160 @@ changed by the user.
<details><summary>TODO 7: Click to show/hide answer</summary>
.. literalinclude:: Step3/CMakeLists.txt
:caption: TODO 7: CMakeLists.txt
:name: CMakeLists.txt-option
.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
:caption: TODO 7: MathFunctions/CMakeLists.txt
:name: CMakeLists.txt-option-library-level
:language: cmake
: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
</details>
Next, make building and linking the ``MathFunctions`` library
conditional.
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``.
Next, make building and linking our library with ``mysqrt`` function
conditional using this new option.
Similarly, we need to make a :command:`list` for the optional includes which
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
Create an :command:`if` statement which checks the value of
``USE_MYMATH``. Inside the :command:`if` block, put the
:command:`add_subdirectory` command from Exercise 1 with the additional
:command:`list` commands.
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:
:command:`target_compile_definitions` command with the compile
definition ``USE_MYMATH``.
.. raw:: html
<details><summary>TODO 8: Click to show/hide answer</summary>
.. literalinclude:: Step3/CMakeLists.txt
:caption: TODO 8: CMakeLists.txt
.. code-block:: cmake
:caption: TODO 8: MathFunctions/CMakeLists.txt
:name: CMakeLists.txt-USE_MYMATH
:language: cmake
:start-after: # add the MathFunctions library
:end-before: # add the executable
if (USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
endif()
.. raw:: html
</details>
Now that we have these two lists, we need to update
:command:`target_link_libraries` and :command:`target_include_directories` to
use them. Changing them is fairly straightforward.
When ``USE_MYMATH`` is ``ON``, the compile definition ``USE_MYMATH`` will
be set. We can then use this compile definition to enable or disable
sections of our source code.
For :command:`target_link_libraries`, we replace the written out
library names with ``EXTRA_LIBS``. This looks like the following:
The corresponding changes to the source code are fairly straightforward.
In ``MathFunctions.cxx``, we make ``USE_MYMATH`` control which square root
function is used:
.. raw:: html
<details><summary>TODO 9: Click to show/hide answer</summary>
.. literalinclude:: Step3/CMakeLists.txt
:caption: TODO 9: CMakeLists.txt
:name: CMakeLists.txt-target_link_libraries-EXTRA_LIBS
:language: cmake
:start-after: add_executable(Tutorial tutorial.cxx)
:end-before: # TODO 3
.. literalinclude:: Step3/MathFunctions/MathFunctions.cxx
:caption: TODO 9: MathFunctions/MathFunctions.cxx
:name: MathFunctions-USE_MYMATH-if
:language: c++
:start-after: which square root function should we use?
:end-before: }
.. raw:: html
</details>
Then, we do the same thing with :command:`target_include_directories` and
``EXTRA_INCLUDES``.
Next, we need to include ``mysqrt.h`` if ``USE_MYMATH`` is defined.
.. raw:: html
<details><summary>TODO 10: Click to show/hide answer</summary>
.. literalinclude:: Step3/CMakeLists.txt
:caption: TODO 10 : CMakeLists.txt
:name: CMakeLists.txt-target_link_libraries-EXTRA_INCLUDES
:language: cmake
:start-after: # so that we will find TutorialConfig.h
.. literalinclude:: Step3/MathFunctions/MathFunctions.cxx
:caption: TODO 10: MathFunctions/MathFunctions.cxx
:name: MathFunctions-USE_MYMATH-if-include
:language: c++
:start-after: include <cmath>
:end-before: namespace mathfunctions
.. raw:: html
</details>
Note that this is a classic approach when dealing with many components. We
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.
Finally, we need to include ``cmath`` now that we are using ``std::sqrt``.
.. raw:: html
<details><summary>TODO 11: Click to show/hide answer</summary>
.. literalinclude:: Step3/tutorial.cxx
:caption: TODO 11 : tutorial.cxx
:name: tutorial.cxx-ifdef-include
:language: c++
:start-after: // should we include the MathFunctions header
:end-before: int main
.. code-block:: c++
:caption: TODO 11 : MathFunctions/MathFunctions.cxx
:name: tutorial.cxx-include_cmath
#include <cmath>
.. raw:: html
</details>
Then, in the same file, we make ``USE_MYMATH`` control which square root
function is used:
At this point, if ``USE_MYMATH`` is ``OFF``, ``mysqrt.cxx`` would not be 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
<details><summary>TODO 12: Click to show/hide answer</summary>
.. literalinclude:: Step3/tutorial.cxx
:caption: TODO 12 : tutorial.cxx
:name: tutorial.cxx-ifdef-const
:language: c++
:start-after: // which square root function should we use?
:end-before: std::cout << "The square root of
.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
:caption: TODO 12 : MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_library-SqrtLibrary
:language: cmake
:start-after: # library that just does sqrt
:end-before: # TODO 7: Link
.. raw:: html
</details>
Since the source code now requires ``USE_MYMATH`` we can add it to
``TutorialConfig.h.in`` with the following line:
Next, we link ``SqrtLibrary`` onto ``MathFunctions`` when ``USE_MYMATH`` is
enabled.
.. raw:: html
<details><summary>TODO 13: Click to show/hide answer</summary>
.. literalinclude:: Step3/TutorialConfig.h.in
:caption: TODO 13 : TutorialConfig.h.in
:name: TutorialConfig.h.in-cmakedefine
:language: c++
:lines: 4
.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
:caption: TODO 13 : MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-target_link_libraries-SqrtLibrary
:language: cmake
:start-after: to tutorial_compiler_flags
:end-before: endif()
.. raw:: html
</details>
With these changes, our library is now completely optional to whoever is
building and using it.
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
------
Finally, we can remove ``mysqrt.cxx`` from our ``MathFunctions`` library
source list because it will be pulled in when ``SqrtLibrary`` is included.
.. 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
``USE_MYMATH``. If we configure the file before
calling :command:`option`, we won't be using the expected value of
``USE_MYMATH``.
.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
:caption: TODO 14 : MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-remove-mysqrt.cxx-MathFunctions
:language: cmake
:end-before: # TODO 1:
.. raw:: html
</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")
# 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
)
include(MakeTable.cmake) # generates Table.h
# library that just does sqrt
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 {
double sqrt(double x)
{
// which square root function should we use?
#ifdef USE_MYMATH
return detail::mysqrt(x);
#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
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
:caption: CMakeLists.txt
:name: CMakeLists.txt-option-BUILD_SHARED_LIBS
:language: cmake
:end-before: # add the binary tree
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.
:start-after: set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
:end-before: # configure a header file to pass the version number only
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
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_library-STATIC
.. literalinclude:: Step11/CMakeLists.txt
:caption: CMakeLists.txt
:name: CMakeLists.txt-cmake-output-directories
:language: cmake
:lines: 1-36,42-
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``
: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
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>>"
)
# 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
# to the source code
# configure a header file to pass the version number only
configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library
if(USE_MYMATH)
add_subdirectory(MathFunctions)
list(APPEND EXTRA_LIBS MathFunctions)
endif()
add_subdirectory(MathFunctions)
# add the executable
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
# so that we will find TutorialConfig.h

@ -1,32 +1,42 @@
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
# 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
)
# add the main library
add_library(MathFunctions
mysqrt.cxx
${CMAKE_CURRENT_BINARY_DIR}/Table.h
)
# add the library that runs
add_library(MathFunctions MathFunctions.cxx)
# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
# state that we depend on our binary dir to find Table.h
target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
)
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
)
# link our compiler flags interface library
target_link_libraries(MathFunctions tutorial_compiler_flags)
# 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")
include(MakeTable.cmake) # generates Table.h
# library that just does sqrt
add_library(SqrtLibrary STATIC
mysqrt.cxx
${CMAKE_CURRENT_BINARY_DIR}/Table.h
)
# state that we depend on our binary dir to find Table.h
target_include_directories(SqrtLibrary PRIVATE
${CMAKE_CURRENT_BINARY_DIR}
)
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs
set(installable_libs MathFunctions tutorial_compiler_flags)
if(TARGET SqrtLibrary)
list(APPEND installable_libs SqrtLibrary)
endif()
install(TARGETS ${installable_libs} DESTINATION lib)
# install include headers
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 {
double sqrt(double x)
{
// which square root function should we use?
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else

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

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

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

@ -13,16 +13,7 @@ if(USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
# 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
)
include(MakeTable.cmake) # generates Table.h
# library that just does sqrt
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 {
double sqrt(double x)
{
// which square root function should we use?
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else

@ -15,16 +15,7 @@ if(USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
# 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
)
include(MakeTable.cmake) # generates Table.h
# library that just does sqrt
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 {
double sqrt(double x)
{
// which square root function should we use?
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else

@ -7,36 +7,20 @@ project(Tutorial VERSION 1.0)
set(CMAKE_CXX_STANDARD 11)
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
# to the source code
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
# add the executable
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 4: Add MathFunctions to Tutorial's target_include_directories()
# 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
# so that we will find TutorialConfig.h
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
# 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>
namespace mathfunctions {
namespace detail {
// a hack square root calculation using simple operations
double mysqrt(double x)
{
@ -20,3 +24,5 @@ double mysqrt(double x)
}
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
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
// TODO 13: use cmakedefine to define USE_MYMATH

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

@ -3,13 +3,16 @@ cmake_minimum_required(VERSION 3.10)
# set the project name and version
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
set(CMAKE_CXX_STANDARD 11)
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
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)
@ -17,16 +20,15 @@ configure_file(TutorialConfig.h.in TutorialConfig.h)
# TODO 2: Remove EXTRA_INCLUDES list
# add the MathFunctions library
if(USE_MYMATH)
add_subdirectory(MathFunctions)
list(APPEND EXTRA_LIBS MathFunctions)
list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
endif()
add_subdirectory(MathFunctions)
list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
# add the executable
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

@ -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
# current source directory, while MathFunctions itself doesn't.
# 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
double mysqrt(double x)
{
@ -22,3 +24,5 @@ double mysqrt(double x)
}
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
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#cmakedefine USE_MYMATH

@ -3,13 +3,9 @@
#include <iostream>
#include <string>
#include "MathFunctions.h"
#include "TutorialConfig.h"
// should we include the MathFunctions header?
#ifdef USE_MYMATH
# include "MathFunctions.h"
#endif
int main(int argc, char* argv[])
{
if (argc < 2) {
@ -23,12 +19,7 @@ int main(int argc, char* argv[])
// convert input to double
const double inputValue = std::stod(argv[1]);
// which square root function should we use?
#ifdef USE_MYMATH
const double outputValue = mysqrt(inputValue);
#else
const double outputValue = sqrt(inputValue);
#endif
const double outputValue = mathfunctions::sqrt(inputValue);
std::cout << "The square root of " << inputValue << " is " << outputValue
<< 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)
# set the project name and version
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
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_library(tutorial_compiler_flags INTERFACE)
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
# 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
# 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.
# * For gcc_like_cxx, add flags -Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused
# * For msvc_cxx, add flags -W3
# 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
# 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
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library
if(USE_MYMATH)
add_subdirectory(MathFunctions)
list(APPEND EXTRA_LIBS MathFunctions)
endif()
add_subdirectory(MathFunctions)
# add the executable
add_executable(Tutorial tutorial.cxx)
# TODO 2: Link to tutorial_compiler_flags
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files
# 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