summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/command/set_property.rst3
-rw-r--r--Help/dev/source.rst11
-rw-r--r--Help/manual/cmake-policies.7.rst1
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/manual/cmake.1.rst3
-rw-r--r--Help/policy/CMP0104.rst31
-rw-r--r--Help/prop_tgt/CUDA_ARCHITECTURES.rst30
-rw-r--r--Help/release/dev/FindPython-dev-subcomponents.rst6
-rw-r--r--Help/release/dev/command-line-cat.rst5
-rw-r--r--Help/release/dev/cuda-architectures-empty.rst7
-rw-r--r--Help/release/dev/cuda-architectures.rst6
-rw-r--r--Help/variable/CMAKE_CUDA_ARCHITECTURES.rst17
-rw-r--r--Modules/CMakeDetermineCUDACompiler.cmake11
-rw-r--r--Modules/FindPython.cmake36
-rw-r--r--Modules/FindPython/Support.cmake304
-rw-r--r--Modules/FindPython2.cmake36
-rw-r--r--Modules/FindPython3.cmake36
-rw-r--r--Modules/Platform/Darwin-Initialize.cmake87
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx4
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx5
-rw-r--r--Source/CTest/cmCTestCoverageCommand.cxx5
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx7
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx13
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx8
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx17
-rw-r--r--Source/cmAlgorithms.h42
-rw-r--r--Source/cmComputeLinkInformation.cxx16
-rw-r--r--Source/cmConditionEvaluator.cxx3
-rw-r--r--Source/cmCoreTryCompile.cxx3
-rw-r--r--Source/cmDepends.cxx4
-rw-r--r--Source/cmDepends.h12
-rw-r--r--Source/cmDependsC.cxx11
-rw-r--r--Source/cmDependsC.h4
-rw-r--r--Source/cmDependsFortran.cxx4
-rw-r--r--Source/cmDependsFortran.h4
-rw-r--r--Source/cmExportBuildAndroidMKGenerator.cxx5
-rw-r--r--Source/cmExportBuildFileGenerator.cxx5
-rw-r--r--Source/cmExportCommand.cxx4
-rw-r--r--Source/cmFileCommand.cxx4
-rw-r--r--Source/cmGeneratorExpressionNode.cxx9
-rw-r--r--Source/cmGeneratorTarget.cxx123
-rw-r--r--Source/cmGeneratorTarget.h2
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.h1
-rw-r--r--Source/cmGlobalGenerator.cxx11
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx6
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx7
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx78
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h9
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx9
-rw-r--r--Source/cmLinkItem.h5
-rw-r--r--Source/cmLinkLineDeviceComputer.cxx5
-rw-r--r--Source/cmListCommand.cxx3
-rw-r--r--Source/cmLocalGenerator.cxx14
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx55
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h6
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx3
-rw-r--r--Source/cmMakefile.cxx33
-rw-r--r--Source/cmMakefileTargetGenerator.cxx14
-rw-r--r--Source/cmOutputConverter.cxx2
-rw-r--r--Source/cmPolicies.h7
-rw-r--r--Source/cmQtAutoGen.cxx3
-rw-r--r--Source/cmQtAutoGenInitializer.cxx8
-rw-r--r--Source/cmServerProtocol.cxx4
-rw-r--r--Source/cmSourceGroupCommand.cxx5
-rw-r--r--Source/cmTarget.cxx1
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx8
-rw-r--r--Source/cmXCodeObject.h9
-rw-r--r--Source/cmXCodeScheme.cxx4
-rw-r--r--Source/cmake.cxx3
-rw-r--r--Source/cmcmd.cxx38
-rw-r--r--Tests/CMakeLists.txt2
-rw-r--r--Tests/Cuda/CXXStandardSetTwice/CMakeLists.txt3
-rw-r--r--Tests/Cuda/Complex/CMakeLists.txt2
-rw-r--r--Tests/Cuda/MixedStandardLevels1/CMakeLists.txt3
-rw-r--r--Tests/Cuda/MixedStandardLevels2/CMakeLists.txt3
-rw-r--r--Tests/Cuda/MixedStandardLevels3/CMakeLists.txt2
-rw-r--r--Tests/Cuda/MixedStandardLevels4/CMakeLists.txt3
-rw-r--r--Tests/Cuda/MixedStandardLevels5/CMakeLists.txt3
-rw-r--r--Tests/Cuda/ProperDeviceLibraries/CMakeLists.txt2
-rw-r--r--Tests/Cuda/WithC/CMakeLists.txt2
-rw-r--r--Tests/CudaOnly/Architecture/CMakeLists.txt5
-rw-r--r--Tests/CudaOnly/Architecture/main.cu9
-rw-r--r--Tests/CudaOnly/CMakeLists.txt2
-rw-r--r--Tests/CudaOnly/CircularLinkLine/CMakeLists.txt2
-rw-r--r--Tests/CudaOnly/CompileFlags/CMakeLists.txt16
-rw-r--r--Tests/CudaOnly/CompileFlags/main.cu16
-rw-r--r--Tests/CudaOnly/DontResolveDeviceSymbols/CMakeLists.txt2
-rw-r--r--Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt2
-rw-r--r--Tests/CudaOnly/RuntimeControls/CMakeLists.txt3
-rw-r--r--Tests/CudaOnly/SeparateCompilation/CMakeLists.txt4
-rw-r--r--Tests/CudaOnly/Standard98/CMakeLists.txt2
-rw-r--r--Tests/CudaOnly/WithDefs/CMakeLists.txt13
-rw-r--r--Tests/FindPython/CMakeLists.txt23
-rw-r--r--Tests/FindPython/Python/CMakeLists.txt6
-rw-r--r--Tests/FindPython/Python2/CMakeLists.txt9
-rw-r--r--Tests/FindPython/Python2Embedded/CMakeLists.txt15
-rw-r--r--Tests/FindPython/Python2Module/CMakeLists.txt37
-rw-r--r--Tests/FindPython/Python3/CMakeLists.txt9
-rw-r--r--Tests/FindPython/Python3Embedded/CMakeLists.txt15
-rw-r--r--Tests/FindPython/Python3Module/CMakeLists.txt37
-rw-r--r--Tests/IncludeDirectories/CMakeLists.txt41
-rw-r--r--Tests/IncludeDirectories/main.cpp3
-rw-r--r--Tests/RunCMake/CMP0104/CMP0104-Common.cmake2
-rw-r--r--Tests/RunCMake/CMP0104/CMP0104-NEW.cmake6
-rw-r--r--Tests/RunCMake/CMP0104/CMP0104-OLD.cmake12
-rw-r--r--Tests/RunCMake/CMP0104/CMP0104-WARN-stderr.txt8
-rw-r--r--Tests/RunCMake/CMP0104/CMP0104-WARN.cmake1
-rw-r--r--Tests/RunCMake/CMP0104/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0104/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0104/main.cu3
-rw-r--r--Tests/RunCMake/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_directory-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt3
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_non_existing_file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_non_readable_file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_option_not_handled-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake38
-rw-r--r--Tests/RunCMake/CompilerLauncher/CUDA-common.cmake1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CudaSimple.cmake1
-rw-r--r--Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt1
-rw-r--r--Tests/TryCompile/CMakeLists.txt2
-rwxr-xr-xUtilities/GitSetup/setup-user9
-rw-r--r--Utilities/std/cmext/algorithm92
-rw-r--r--Utilities/std/cmext/iterator20
-rw-r--r--Utilities/std/cmext/type_traits2
131 files changed, 1387 insertions, 428 deletions
diff --git a/Help/command/set_property.rst b/Help/command/set_property.rst
index ec08c8f..1728c98 100644
--- a/Help/command/set_property.rst
+++ b/Help/command/set_property.rst
@@ -66,7 +66,8 @@ the property to set. Remaining arguments are used to compose the
property value in the form of a semicolon-separated list.
If the ``APPEND`` option is given the list is appended to any existing
-property value. If the ``APPEND_STRING`` option is given the string is
+property value (except that empty values are ignored and not appended).
+If the ``APPEND_STRING`` option is given the string is
appended to any existing property value as string, i.e. it results in a
longer string and not a list of strings. When using ``APPEND`` or
``APPEND_STRING`` with a property defined to support ``INHERITED``
diff --git a/Help/dev/source.rst b/Help/dev/source.rst
index 5371353..65a6adf 100644
--- a/Help/dev/source.rst
+++ b/Help/dev/source.rst
@@ -108,6 +108,9 @@ These are:
* ``cm::append``:
Append elements to a sequential container.
+ * ``cm::contains``:
+ Checks if element or key is contained in container.
+
* ``<cmext/iterator>``:
* ``cm::is_terator``:
@@ -117,12 +120,12 @@ These are:
Checks if a type is an input iterator type.
* ``cm::is_range``:
- Checks if a type is a range type: must have methods ``begin()`` and
- ``end()`` returning an iterator.
+ Checks if a type is a range type: functions ``std::begin()`` and
+ ``std::end()`` apply.
* ``cm::is_input_range``:
- Checks if a type is an input range type: must have methods ``begin()`` and
- ``end()`` returning an input iterator.
+ Checks if a type is an input range type: functions ``std::begin()`` and
+ ``std::end()`` apply and return an input iterator.
* ``<cmext/memory>``:
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 08d59e7..869ae41 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.18
.. toctree::
:maxdepth: 1
+ CMP0104: CMAKE_CUDA_ARCHITECTURES now detected for NVCC, empty CUDA_ARCHITECTURES not allowed. </policy/CMP0104>
CMP0103: Multiple export() with same FILE without APPEND is not allowed. </policy/CMP0103>
Policies Introduced by CMake 3.17
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index cbb2298..4966f86 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -172,6 +172,7 @@ Properties on Targets
/prop_tgt/CONFIG_OUTPUT_NAME
/prop_tgt/CONFIG_POSTFIX
/prop_tgt/CROSSCOMPILING_EMULATOR
+ /prop_tgt/CUDA_ARCHITECTURES
/prop_tgt/CUDA_PTX_COMPILATION
/prop_tgt/CUDA_SEPARABLE_COMPILATION
/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 1642772..7d802e1 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -488,6 +488,7 @@ Variables for Languages
/variable/CMAKE_COMPILER_IS_GNUCC
/variable/CMAKE_COMPILER_IS_GNUCXX
/variable/CMAKE_COMPILER_IS_GNUG77
+ /variable/CMAKE_CUDA_ARCHITECTURES
/variable/CMAKE_CUDA_COMPILE_FEATURES
/variable/CMAKE_CUDA_HOST_COMPILER
/variable/CMAKE_CUDA_EXTENSIONS
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 9a43499..e3e965c 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -554,6 +554,9 @@ Available commands are:
``serverMode``
``true`` if cmake supports server-mode and ``false`` otherwise.
+``cat <files>...``
+ Concatenate files and print on the standard output.
+
``chdir <dir> <cmd> [<arg>...]``
Change the current working directory and run a command.
diff --git a/Help/policy/CMP0104.rst b/Help/policy/CMP0104.rst
new file mode 100644
index 0000000..ca2c571
--- /dev/null
+++ b/Help/policy/CMP0104.rst
@@ -0,0 +1,31 @@
+CMP0104
+-------
+
+Initialize :variable:`CMAKE_CUDA_ARCHITECTURES` when
+:variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` is ``NVIDIA``.
+Raise an error if :prop_tgt:`CUDA_ARCHITECTURES` is empty.
+
+:variable:`CMAKE_CUDA_ARCHITECTURES` introduced in CMake 3.18 is used to
+initialize :prop_tgt:`CUDA_ARCHITECTURES`, which passes correct code generation
+flags to the CUDA compiler.
+
+Previous to this users had to manually specify the code generation flags. This
+policy is for backwards compatibility with manually specifying code generation
+flags.
+
+The ``OLD`` behavior for this policy is to not initialize
+:variable:`CMAKE_CUDA_ARCHITECTURES` when
+:variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` is ``NVIDIA``.
+Empty :prop_tgt:`CUDA_ARCHITECTURES` is allowed.
+
+The ``NEW`` behavior of this policy is to initialize
+:variable:`CMAKE_CUDA_ARCHITECTURES` when
+:variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` is ``NVIDIA``
+and raise an error if :prop_tgt:`CUDA_ARCHITECTURES` is empty during generation.
+
+This policy was introduced in CMake version 3.18. CMake version
+|release| warns when the policy is not set and uses ``OLD`` behavior.
+Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW``
+explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/prop_tgt/CUDA_ARCHITECTURES.rst b/Help/prop_tgt/CUDA_ARCHITECTURES.rst
new file mode 100644
index 0000000..328f40b
--- /dev/null
+++ b/Help/prop_tgt/CUDA_ARCHITECTURES.rst
@@ -0,0 +1,30 @@
+CUDA_ARCHITECTURES
+------------------
+
+List of architectures to generate device code for.
+
+An architecture can be suffixed by either ``-real`` or ``-virtual`` to specify
+the kind of architecture to generate code for.
+If no suffix is given then code is generated for both real and virtual
+architectures.
+
+This property is initialized by the value of the :variable:`CMAKE_CUDA_ARCHITECTURES`
+variable if it is set when a target is created.
+
+The ``CUDA_ARCHITECTURES`` target property must be set to a non-empty value on targets
+that compile CUDA sources, or it is an error. See policy :policy:`CMP0104`.
+
+Examples
+^^^^^^^^
+
+.. code-block:: cmake
+
+ set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES 35 50 72)
+
+Generates code for real and virtual architectures ``30``, ``50`` and ``72``.
+
+.. code-block:: cmake
+
+ set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES 70-real 72-virtual)
+
+Generates code for real architecture ``70`` and virtual architecture ``72``.
diff --git a/Help/release/dev/FindPython-dev-subcomponents.rst b/Help/release/dev/FindPython-dev-subcomponents.rst
new file mode 100644
index 0000000..fe76ee8
--- /dev/null
+++ b/Help/release/dev/FindPython-dev-subcomponents.rst
@@ -0,0 +1,6 @@
+FindPython-dev-subcomponents
+----------------------------
+
+* The :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython`
+ modules gained sub-components ``Development.Module`` and
+ ``Development.Embed`` for ``Development`` component.
diff --git a/Help/release/dev/command-line-cat.rst b/Help/release/dev/command-line-cat.rst
new file mode 100644
index 0000000..acde835
--- /dev/null
+++ b/Help/release/dev/command-line-cat.rst
@@ -0,0 +1,5 @@
+Command-Line
+------------
+* :manual:`cmake(1)` gained a ``cat`` command line
+ option that can be used to concatenate files and print them
+ on standard output.
diff --git a/Help/release/dev/cuda-architectures-empty.rst b/Help/release/dev/cuda-architectures-empty.rst
new file mode 100644
index 0000000..b0fc327
--- /dev/null
+++ b/Help/release/dev/cuda-architectures-empty.rst
@@ -0,0 +1,7 @@
+cuda-architectures-empty
+------------------------
+
+* :variable:`CMAKE_CUDA_ARCHITECTURES` is now initialized when
+ :variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` is ``NVIDIA``.
+ Empty :prop_tgt:`CUDA_ARCHITECTURES` raises an error. See policy
+ :policy:`CMP0104`.
diff --git a/Help/release/dev/cuda-architectures.rst b/Help/release/dev/cuda-architectures.rst
new file mode 100644
index 0000000..dc6c55b
--- /dev/null
+++ b/Help/release/dev/cuda-architectures.rst
@@ -0,0 +1,6 @@
+cuda-architectures
+------------------
+
+* Added :prop_tgt:`CUDA_ARCHITECTURES` target property for specifying CUDA
+ output architectures. Users are encouraged to use this instead of specifying
+ options manually, as this approach is compiler-agnostic.
diff --git a/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst b/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst
new file mode 100644
index 0000000..149bffa
--- /dev/null
+++ b/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst
@@ -0,0 +1,17 @@
+CMAKE_CUDA_ARCHITECTURES
+------------------------
+
+Default value for :prop_tgt:`CUDA_ARCHITECTURES` property of targets.
+
+This is initialized as follows depending on :variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>`:
+
+- For ``Clang``: the oldest architecture that works.
+
+- For ``NVIDIA``: the default architecture chosen by the compiler.
+ See policy :policy:`CMP0104`.
+
+Users are encouraged to override this, as the default varies across compilers
+and compiler versions.
+
+This variable is used to initialize the :prop_tgt:`CUDA_ARCHITECTURES` property
+on all targets. See the target property for additional information.
diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake
index 55ca800..ead4125 100644
--- a/Modules/CMakeDetermineCUDACompiler.cmake
+++ b/Modules/CMakeDetermineCUDACompiler.cmake
@@ -226,6 +226,17 @@ if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Failed to detect CUDA nvcc include information:\n${_nvcc_log}\n\n")
endif()
+
+ # Parse default CUDA architecture.
+ cmake_policy(GET CMP0104 _CUDA_CMP0104)
+ if(NOT CMAKE_CUDA_ARCHITECTURES AND _CUDA_CMP0104 STREQUAL "NEW")
+ string(REGEX MATCH "arch[ =]compute_([0-9]+)" dont_care "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
+ set(CMAKE_CUDA_ARCHITECTURES "${CMAKE_MATCH_1}" CACHE STRING "CUDA architectures")
+
+ if(NOT CMAKE_CUDA_ARCHITECTURES)
+ message(FATAL_ERROR "Failed to find default CUDA architecture.")
+ endif()
+ endif()
endif()
# configure all variables set in this file
diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake
index 95426ba..95c4a0f 100644
--- a/Modules/FindPython.cmake
+++ b/Modules/FindPython.cmake
@@ -13,13 +13,24 @@ The following components are supported:
* ``Interpreter``: search for Python interpreter.
* ``Compiler``: search for Python compiler. Only offered by IronPython.
* ``Development``: search for development artifacts (include directories and
- libraries).
+ libraries). This component includes two sub-components which can be specified
+ independently:
+
+ * ``Development.Module``: search for artifacts for Python module
+ developments.
+ * ``Development.Embed``: search for artifacts for Python embedding
+ developments.
+
* ``NumPy``: search for NumPy include directories.
If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed.
+If component ``Development`` is specified, it implies sub-components
+``Development.Module`` and ``Development.Embed``.
+
To ensure consistent versions between components ``Interpreter``, ``Compiler``,
-``Development`` and ``NumPy``, specify all components at the same time::
+``Development`` (or one of its sub-components) and ``NumPy``, specify all
+components at the same time::
find_package (Python COMPONENTS Interpreter Development)
@@ -30,10 +41,11 @@ To manage concurrent versions 3 and 2 of Python, use :module:`FindPython3` and
.. note::
- If components ``Interpreter`` and ``Development`` are both specified, this
- module search only for interpreter with same platform architecture as the one
- defined by ``CMake`` configuration. This contraint does not apply if only
- ``Interpreter`` component is specified.
+ If components ``Interpreter`` and ``Development`` (or one of its
+ sub-components) are both specified, this module search only for interpreter
+ with same platform architecture as the one defined by ``CMake``
+ configuration. This contraint does not apply if only ``Interpreter``
+ component is specified.
Imported Targets
^^^^^^^^^^^^^^^^
@@ -45,12 +57,12 @@ This module defines the following :ref:`Imported Targets <Imported Targets>`
Python interpreter. Target defined if component ``Interpreter`` is found.
``Python::Compiler``
Python compiler. Target defined if component ``Compiler`` is found.
+``Python::Module``
+ Python library for Python module. Target defined if component
+ ``Development.Module`` is found.
``Python::Python``
Python library for Python embedding. Target defined if component
- ``Development`` is found.
-``Python::Module``
- Python library for Python module. Target defined if component ``Development``
- is found.
+ ``Development.Embed`` is found.
``Python::NumPy``
NumPy Python library. Target defined if component ``NumPy`` is found.
@@ -115,6 +127,10 @@ This module will set the following variables in your project
* IronPython
``Python_Development_FOUND``
System has the Python development artifacts.
+``Python_Development.Module_FOUND``
+ System has the Python development artifacts for Python module.
+``Python_Development.Embed_FOUND``
+ System has the Python development artifacts for Python embedding.
``Python_INCLUDE_DIRS``
The Python include directories.
``Python_LIBRARIES``
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index a990f0d..7562879 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -22,9 +22,9 @@ endif()
if (NOT DEFINED _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
message (FATAL_ERROR "FindPython: INTERNAL ERROR")
endif()
-if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 3)
+if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "3")
set(_${_PYTHON_PREFIX}_VERSIONS 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
-elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 2)
+elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "2")
set(_${_PYTHON_PREFIX}_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
else()
message (FATAL_ERROR "FindPython: INTERNAL ERROR")
@@ -572,7 +572,8 @@ function (_PYTHON_VALIDATE_INTERPRETER)
endif()
endif()
- if (CMAKE_SIZEOF_VOID_P AND "Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ if (CMAKE_SIZEOF_VOID_P AND ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
AND NOT CMAKE_CROSSCOMPILING)
# In this case, interpreter must have same architecture as environment
execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
@@ -651,6 +652,7 @@ endfunction()
function (_PYTHON_VALIDATE_LIBRARY)
if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+ unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG)
return()
endif()
@@ -782,6 +784,25 @@ function (_PYTHON_SET_LIBRARY_DIRS _PYTHON_SLD_RESULT)
endfunction()
+function (_PYTHON_SET_DEVELOPMENT_MODULE_FOUND module)
+ if ("Development.${module}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ string(TOUPPER "${module}" id)
+ set (module_found TRUE)
+
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
+ AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+ set (module_found FALSE)
+ endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
+ AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
+ set (module_found FALSE)
+ endif()
+
+ set (${_PYTHON_PREFIX}_Development.${module}_FOUND ${module_found} PARENT_SCOPE)
+ endif()
+endfunction()
+
+
# If major version is specified, it must be the same as internal major version
if (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR
AND NOT ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
@@ -795,19 +816,42 @@ if (NOT ${_PYTHON_PREFIX}_FIND_COMPONENTS)
set (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter TRUE)
endif()
if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
- list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Interpreter" "Development")
- list (REMOVE_DUPLICATES ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Interpreter" "Development.Module")
endif()
-foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development NumPy)
+if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Development.Module" "Development.Embed")
+endif()
+list (REMOVE_DUPLICATES ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development Development.Module Development.Embed NumPy)
set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE)
endforeach()
+if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development)
+ set (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Module TRUE)
+ set (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Embed TRUE)
+endif()
+
+unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
+unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS)
+if ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$")
+ list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "LIBRARY")
+ endif()
+ list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "INCLUDE_DIR")
+endif()
+if ("Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS "LIBRARY" "INCLUDE_DIR")
+endif()
+set (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS} ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS})
+list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+
unset (_${_PYTHON_PREFIX}_FIND_VERSIONS)
# Set versions to search
## default: search any version
set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSIONS})
-if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT GREATER 1)
+if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT GREATER "1")
if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT)
set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR})
else()
@@ -962,6 +1006,63 @@ if (CMAKE_HOST_WIN32)
string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${_${_PYTHON_PREFIX}_FIND_REGISTRY}")
endif()
+function (_PYTHON_CHECK_DEVELOPMENT_SIGNATURE module)
+ if ("Development.${module}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ string (TOUPPER "${module}" id)
+ set (signature "${_${_PYTHON_PREFIX}_SIGNATURE}:")
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+ list (APPEND signature "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:")
+ endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+ list (APPEND signature "${_${_PYTHON_PREFIX}_INCLUDE_DIR}:")
+ endif()
+ string (MD5 signature "${signature}")
+ if (signature STREQUAL _${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE)
+ if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT)
+ set (exact EXACT)
+ endif()
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+ _python_validate_library (${${_PYTHON_PREFIX}_FIND_VERSION} ${exact} CHECK_EXISTS)
+ endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+ _python_validate_include_dir (${${_PYTHON_PREFIX}_FIND_VERSION} ${exact} CHECK_EXISTS)
+ endif()
+ else()
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+ unset (_${_PYTHON_PREFIX}_LIBRARY_RELEASE CACHE)
+ unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE)
+ endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+ unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE)
+ endif()
+ endif()
+ if (("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
+ AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+ OR ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
+ AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR))
+ unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ unset (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE CACHE)
+ endif()
+ endif()
+endfunction()
+
+function (_PYTHON_COMPUTE_DEVELOPMENT_SIGNATURE module)
+ string (TOUPPER "${module}" id)
+ if (${_PYTHON_PREFIX}_Development.${module}_FOUND)
+ set (signature "${_${_PYTHON_PREFIX}_SIGNATURE}:")
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+ list (APPEND signature "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:")
+ endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+ list (APPEND signature "${_${_PYTHON_PREFIX}_INCLUDE_DIR}:")
+ endif()
+ string (MD5 signature "${signature}")
+ set (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE "${signature}" CACHE INTERNAL "")
+ else()
+ unset (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE CACHE)
+ endif()
+endfunction()
+
unset (_${_PYTHON_PREFIX}_REQUIRED_VARS)
unset (_${_PYTHON_PREFIX}_CACHED_VARS)
@@ -1633,46 +1734,38 @@ endif()
# third step, search for the development artifacts
## Development environment is not compatible with IronPython interpreter
-if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython")
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_LIBRARY_RELEASE
_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
_${_PYTHON_PREFIX}_LIBRARY_DEBUG
- _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
- _${_PYTHON_PREFIX}_INCLUDE_DIR)
- if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development)
- list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES
- ${_PYTHON_PREFIX}_INCLUDE_DIRS)
+ _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
endif()
-
- if (DEFINED _${_PYTHON_PREFIX}_LIBRARY_RELEASE OR DEFINED _${_PYTHON_PREFIX}_INCLUDE_DIR)
- # compute development signature and check validity of definition
- string (MD5 __${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
- if (WIN32 AND NOT DEFINED _${_PYTHON_PREFIX}_LIBRARY_DEBUG)
- set (_${_PYTHON_PREFIX}_LIBRARY_DEBUG "${_PYTHON_PREFIX}_LIBRARY_DEBUG-NOTFOUND" CACHE INTERNAL "")
- endif()
- if (NOT DEFINED _${_PYTHON_PREFIX}_INCLUDE_DIR)
- set (_${_PYTHON_PREFIX}_INCLUDE_DIR "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND" CACHE INTERNAL "")
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+ list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_INCLUDE_DIR)
+ endif()
+ if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Module)
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
+ list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES)
endif()
- if (__${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE)
- # check version validity
- if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT)
- _python_validate_library (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS)
- _python_validate_include_dir (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS)
- else()
- _python_validate_library (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS)
- _python_validate_include_dir (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS)
- endif()
- else()
- unset (_${_PYTHON_PREFIX}_LIBRARY_RELEASE CACHE)
- unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE)
- unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE)
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
+ list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS)
endif()
endif()
- if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE OR NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
- unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
- unset (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE CACHE)
+ if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Embed)
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS)
+ list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES)
+ endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS)
+ list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS)
+ endif()
endif()
+ list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_REQUIRED_VARS)
+
+ _python_check_development_signature (Module)
+ _python_check_development_signature (Embed)
if (DEFINED ${_PYTHON_PREFIX}_LIBRARY
AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_LIBRARY}")
@@ -1895,6 +1988,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
endif()
endif()
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG)
# retrieve root install directory
@@ -2139,9 +2233,16 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
HINTS "${_${_PYTHON_PREFIX}_PATH}" "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS}
PATH_SUFFIXES bin)
endif()
+ endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+ while (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS
+ AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
# Don't search for include dir if no library was founded
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
+ break()
+ endif()
+
if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG)
_python_get_config_var (_${_PYTHON_PREFIX}_INCLUDE_DIRS INCLUDES)
@@ -2160,10 +2261,11 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
endif()
unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS)
+ if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
# Use the library's install prefix as a hint
- if (${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)")
+ if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)")
list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
- elseif (${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config")
+ elseif (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config")
list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
@@ -2173,6 +2275,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY)
list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}")
endif()
+ endif()
_python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION})
_python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION})
@@ -2228,7 +2331,9 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
# search header file in standard locations
find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
NAMES Python.h)
- endif()
+
+ break()
+ endwhile()
set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
@@ -2241,10 +2346,18 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
# retrieve version from header file
_python_get_version (INCLUDE PREFIX _${_PYTHON_PREFIX}_INC_)
+ if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
# update versioning
if (_${_PYTHON_PREFIX}_INC_VERSION VERSION_EQUAL _${_PYTHON_PREFIX}_VERSION)
set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH})
endif()
+ else()
+ set (_${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_INC_VERSION})
+ set (_${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR})
+ set (_${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_INC_VERSION_MINOR})
+ set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH})
+ endif()
+ endif()
endif()
if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT ${_PYTHON_PREFIX}_Compiler_FOUND)
@@ -2256,6 +2369,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
endif()
# define public variables
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
set (${_PYTHON_PREFIX}_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_LIBRARY_DEBUG}")
_python_select_library_configurations (${_PYTHON_PREFIX})
@@ -2280,37 +2394,42 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
_python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS
_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
endif()
+ endif()
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND _${_PYTHON_PREFIX}_INCLUDE_DIR)
+ if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE OR _${_PYTHON_PREFIX}_INCLUDE_DIR)
if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND)
# development environment must be compatible with interpreter/compiler
if ("${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}" VERSION_EQUAL "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}"
AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}")
- set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
+ _python_set_development_module_found (Module)
+ _python_set_development_module_found (Embed)
endif()
elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR
AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}")
- set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
+ _python_set_development_module_found (Module)
+ _python_set_development_module_found (Embed)
endif()
if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND
(NOT _${_PYTHON_PREFIX}_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS
OR NOT _${_PYTHON_PREFIX}_INC_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS))
- set (${_PYTHON_PREFIX}_Development_FOUND FALSE)
+ set (${_PYTHON_PREFIX}_Development.Module_FOUND FALSE)
+ set (${_PYTHON_PREFIX}_Development.Embed_FOUND FALSE)
endif()
endif()
+ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ AND ${_PYTHON_PREFIX}_Development.Module_FOUND
+ AND ${_PYTHON_PREFIX}_Development.Embed_FOUND)
+ set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
+ endif()
+
if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL "3"
AND NOT DEFINED ${_PYTHON_PREFIX}_SOABI)
_python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI)
endif()
- if (${_PYTHON_PREFIX}_Development_FOUND)
- # compute and save development signature
- string (MD5 __${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
- set (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE "${__${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE}" CACHE INTERNAL "")
- else()
- unset (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE CACHE)
- endif()
+ _python_compute_development_signature (Module)
+ _python_compute_development_signature (Embed)
# Restore the original find library ordering
if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES)
@@ -2318,9 +2437,13 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
endif()
if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE)
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
set (${_PYTHON_PREFIX}_LIBRARY "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" CACHE FILEPATH "${_PYTHON_PREFIX} Library")
+ endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
set (${_PYTHON_PREFIX}_INCLUDE_DIR "${_${_PYTHON_PREFIX}_INCLUDE_DIR}" CACHE FILEPATH "${_PYTHON_PREFIX} Include Directory")
endif()
+ endif()
_python_mark_as_internal (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
_${_PYTHON_PREFIX}_LIBRARY_DEBUG
@@ -2328,7 +2451,8 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
_${_PYTHON_PREFIX}_INCLUDE_DIR
_${_PYTHON_PREFIX}_CONFIG
- _${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE)
+ _${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE
+ _${_PYTHON_PREFIX}_DEVELOPMENT_EMBED_SIGNATURE)
endif()
if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Interpreter_FOUND)
@@ -2342,7 +2466,7 @@ if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Inte
set (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}" CACHE INTERNAL "")
elseif (DEFINED _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR)
# compute numpy signature. Depends on interpreter and development signatures
- string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE}:${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
+ string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
if (NOT __${_PYTHON_PREFIX}_NUMPY_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_NUMPY_SIGNATURE
OR NOT EXISTS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
unset (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR CACHE)
@@ -2386,15 +2510,15 @@ if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Inte
unset (${_PYTHON_PREFIX}_NumPy_VERSION)
endif()
- # final step: set NumPy founded only if Development component is founded as well
- set(${_PYTHON_PREFIX}_NumPy_FOUND ${${_PYTHON_PREFIX}_Development_FOUND})
+ # final step: set NumPy founded only if Development.Module component is founded as well
+ set(${_PYTHON_PREFIX}_NumPy_FOUND ${${_PYTHON_PREFIX}_Development.Module_FOUND})
else()
set (${_PYTHON_PREFIX}_NumPy_FOUND FALSE)
endif()
if (${_PYTHON_PREFIX}_NumPy_FOUND)
# compute and save numpy signature
- string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE}:${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}")
+ string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}")
set (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${__${_PYTHON_PREFIX}_NUMPY_SIGNATURE}" CACHE INTERNAL "")
else()
unset (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE CACHE)
@@ -2446,8 +2570,10 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_COMPILER}")
endif()
- if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
- AND ${_PYTHON_PREFIX}_Development_FOUND)
+ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ AND ${_PYTHON_PREFIX}_Development.Module_FOUND)
+ OR ("Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ AND ${_PYTHON_PREFIX}_Development.Embed_FOUND))
macro (__PYTHON_IMPORT_LIBRARY __name)
if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$"
@@ -2508,31 +2634,35 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
endif()
endmacro()
+ if (${_PYTHON_PREFIX}_Development.Embed_FOUND)
__python_import_library (${_PYTHON_PREFIX}::Python)
+ endif()
- if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$")
- # On Windows/CYGWIN/MSYS, Python::Module is the same as Python::Python
- # but ALIAS cannot be used because the imported library is not GLOBAL.
- __python_import_library (${_PYTHON_PREFIX}::Module)
- else()
- if (NOT TARGET ${_PYTHON_PREFIX}::Module )
- add_library (${_PYTHON_PREFIX}::Module INTERFACE IMPORTED)
- endif()
- set_property (TARGET ${_PYTHON_PREFIX}::Module
- PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}")
-
- # When available, enforce shared library generation with undefined symbols
- if (APPLE)
- set_property (TARGET ${_PYTHON_PREFIX}::Module
- PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup")
- endif()
- if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
- set_property (TARGET ${_PYTHON_PREFIX}::Module
- PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-z,nodefs")
- endif()
- if (CMAKE_SYSTEM_NAME STREQUAL "AIX")
+ if (${_PYTHON_PREFIX}_Development.Module_FOUND)
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
+ # On Windows/CYGWIN/MSYS, Python::Module is the same as Python::Python
+ # but ALIAS cannot be used because the imported library is not GLOBAL.
+ __python_import_library (${_PYTHON_PREFIX}::Module)
+ else()
+ if (NOT TARGET ${_PYTHON_PREFIX}::Module)
+ add_library (${_PYTHON_PREFIX}::Module INTERFACE IMPORTED)
+ endif()
set_property (TARGET ${_PYTHON_PREFIX}::Module
- PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-b,erok")
+ PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}")
+
+ # When available, enforce shared library generation with undefined symbols
+ if (APPLE)
+ set_property (TARGET ${_PYTHON_PREFIX}::Module
+ PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup")
+ endif()
+ if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+ set_property (TARGET ${_PYTHON_PREFIX}::Module
+ PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-z,nodefs")
+ endif()
+ if (CMAKE_SYSTEM_NAME STREQUAL "AIX")
+ set_property (TARGET ${_PYTHON_PREFIX}::Module
+ PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-b,erok")
+ endif()
endif()
endif()
@@ -2556,6 +2686,16 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
else()
set (type MODULE)
endif()
+
+ if (type STREQUAL "MODULE" AND NOT TARGET ${prefix}::Module)
+ message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::Module' is not defined.\n Did you miss to request COMPONENT 'Development.Module'?")
+ return()
+ endif()
+ if (NOT type STREQUAL "MODULE" AND NOT TARGET ${prefix}::Python)
+ message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::Python' is not defined.\n Did you miss to request COMPONENT 'Development.Embed'?")
+ return()
+ endif()
+
add_library (${name} ${type} ${PYTHON_ADD_LIBRARY_UNPARSED_ARGUMENTS})
get_property (type TARGET ${name} PROPERTY TYPE)
diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake
index 3d9ceb4..ef3280f 100644
--- a/Modules/FindPython2.cmake
+++ b/Modules/FindPython2.cmake
@@ -13,13 +13,24 @@ The following components are supported:
* ``Interpreter``: search for Python 2 interpreter
* ``Compiler``: search for Python 2 compiler. Only offered by IronPython.
* ``Development``: search for development artifacts (include directories and
- libraries)
+ libraries). This component includes two sub-components which can be specified
+ independently:
+
+ * ``Development.Module``: search for artifacts for Python 2 module
+ developments.
+ * ``Development.Embed``: search for artifacts for Python 2 embedding
+ developments.
+
* ``NumPy``: search for NumPy include directories.
If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed.
+If component ``Development`` is specified, it implies sub-components
+``Development.Module`` and ``Development.Embed``.
+
To ensure consistent versions between components ``Interpreter``, ``Compiler``,
-``Development`` and ``NumPy``, specify all components at the same time::
+``Development`` (or one of its sub-components) and ``NumPy``, specify all
+components at the same time::
find_package (Python2 COMPONENTS Interpreter Development)
@@ -31,10 +42,11 @@ for you.
.. note::
- If components ``Interpreter`` and ``Development`` are both specified, this
- module search only for interpreter with same platform architecture as the one
- defined by ``CMake`` configuration. This contraint does not apply if only
- ``Interpreter`` component is specified.
+ If components ``Interpreter`` and ``Development`` (or one of its
+ sub-components) are both specified, this module search only for interpreter
+ with same platform architecture as the one defined by ``CMake``
+ configuration. This contraint does not apply if only ``Interpreter``
+ component is specified.
Imported Targets
^^^^^^^^^^^^^^^^
@@ -46,12 +58,12 @@ This module defines the following :ref:`Imported Targets <Imported Targets>`
Python 2 interpreter. Target defined if component ``Interpreter`` is found.
``Python2::Compiler``
Python 2 compiler. Target defined if component ``Compiler`` is found.
-``Python2::Python``
- Python 2 library for Python embedding. Target defined if component
- ``Development`` is found.
``Python2::Module``
Python 2 library for Python module. Target defined if component
- ``Development`` is found.
+ ``Development.Module`` is found.
+``Python2::Python``
+ Python 2 library for Python embedding. Target defined if component
+ ``Development.Embed`` is found.
``Python2::NumPy``
NumPy library for Python 2. Target defined if component ``NumPy`` is found.
@@ -107,6 +119,10 @@ This module will set the following variables in your project
* IronPython
``Python2_Development_FOUND``
System has the Python 2 development artifacts.
+``Python2_Development.Module_FOUND``
+ System has the Python 2 development artifacts for Python module.
+``Python2_Development.Embed_FOUND``
+ System has the Python 2 development artifacts for Python embedding.
``Python2_INCLUDE_DIRS``
The Python 2 include directories.
``Python2_LIBRARIES``
diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake
index 122316b..1373407 100644
--- a/Modules/FindPython3.cmake
+++ b/Modules/FindPython3.cmake
@@ -13,13 +13,24 @@ The following components are supported:
* ``Interpreter``: search for Python 3 interpreter
* ``Compiler``: search for Python 3 compiler. Only offered by IronPython.
* ``Development``: search for development artifacts (include directories and
- libraries)
+ libraries). This component includes two sub-components which can be specified
+ independently:
+
+ * ``Development.Module``: search for artifacts for Python 3 module
+ developments.
+ * ``Development.Embed``: search for artifacts for Python 3 embedding
+ developments.
+
* ``NumPy``: search for NumPy include directories.
If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed.
+If component ``Development`` is specified, it implies sub-components
+``Development.Module`` and ``Development.Embed``.
+
To ensure consistent versions between components ``Interpreter``, ``Compiler``,
-``Development`` and ``NumPy``, specify all components at the same time::
+``Development`` (or one of its sub-components) and ``NumPy``, specify all
+components at the same time::
find_package (Python3 COMPONENTS Interpreter Development)
@@ -31,10 +42,11 @@ for you.
.. note::
- If components ``Interpreter`` and ``Development`` are both specified, this
- module search only for interpreter with same platform architecture as the one
- defined by ``CMake`` configuration. This contraint does not apply if only
- ``Interpreter`` component is specified.
+ If components ``Interpreter`` and ``Development`` (or one of its
+ sub-components) are both specified, this module search only for interpreter
+ with same platform architecture as the one defined by ``CMake``
+ configuration. This contraint does not apply if only ``Interpreter``
+ component is specified.
Imported Targets
^^^^^^^^^^^^^^^^
@@ -46,12 +58,12 @@ This module defines the following :ref:`Imported Targets <Imported Targets>`
Python 3 interpreter. Target defined if component ``Interpreter`` is found.
``Python3::Compiler``
Python 3 compiler. Target defined if component ``Compiler`` is found.
-``Python3::Python``
- Python 3 library for Python embedding. Target defined if component
- ``Development`` is found.
``Python3::Module``
Python 3 library for Python module. Target defined if component
- ``Development`` is found.
+ ``Development.Module`` is found.
+``Python3::Python``
+ Python 3 library for Python embedding. Target defined if component
+ ``Development.Embed`` is found.
``Python3::NumPy``
NumPy library for Python 3. Target defined if component ``NumPy`` is found.
@@ -116,6 +128,10 @@ This module will set the following variables in your project
* IronPython
``Python3_Development_FOUND``
System has the Python 3 development artifacts.
+``Python3_Development.Module_FOUND``
+ System has the Python 3 development artifacts for Python module.
+``Python3_Development.Embed_FOUND``
+ System has the Python 3 development artifacts for Python embedding.
``Python3_INCLUDE_DIRS``
The Python 3 include directories.
``Python3_LIBRARIES``
diff --git a/Modules/Platform/Darwin-Initialize.cmake b/Modules/Platform/Darwin-Initialize.cmake
index 80e668e..80e9a40 100644
--- a/Modules/Platform/Darwin-Initialize.cmake
+++ b/Modules/Platform/Darwin-Initialize.cmake
@@ -133,6 +133,80 @@ function(_apple_resolve_sdk_path sdk_name ret)
)
set(${ret} "${_stdout}" PARENT_SCOPE)
endfunction()
+
+function(_apple_resolve_supported_archs_for_sdk_from_system_lib sdk_path ret ret_failed)
+ # Detect the supported SDK architectures by inspecting the main libSystem library.
+ set(common_lib_prefix "${sdk_path}/usr/lib/libSystem")
+ set(system_lib_dylib_path "${common_lib_prefix}.dylib")
+ set(system_lib_tbd_path "${common_lib_prefix}.tbd")
+
+ # Newer SDKs ship text based dylib stub files which contain the architectures supported by the
+ # library in text form.
+ if(EXISTS "${system_lib_tbd_path}")
+ file(STRINGS "${system_lib_tbd_path}" tbd_lines REGEX "^archs: +\\[.+\\]")
+ if(NOT tbd_lines)
+ set(${ret_failed} TRUE PARENT_SCOPE)
+ return()
+ endif()
+
+ # The tbd architectures line looks like the following:
+ # archs: [ armv7, armv7s, arm64, arm64e ]
+ list(GET tbd_lines 0 first_arch_line)
+ string(REGEX REPLACE
+ "archs: +\\[ (.+) \\]" "\\1" arches_comma_separated "${first_arch_line}")
+ string(STRIP "${arches_comma_separated}" arches_comma_separated)
+ string(REPLACE "," ";" arch_list "${arches_comma_separated}")
+ string(REPLACE " " "" arch_list "${arch_list}")
+ if(NOT arch_list)
+ set(${ret_failed} TRUE PARENT_SCOPE)
+ return()
+ endif()
+ set(${ret} "${arch_list}" PARENT_SCOPE)
+ elseif(EXISTS "${system_lib_dylib_path}")
+ # Old SDKs (Xcode < 7) ship dylib files, use lipo to inspect the supported architectures.
+ # Can't use -archs because the option is not available in older Xcode versions.
+ execute_process(
+ COMMAND lipo -info ${system_lib_dylib_path}
+ OUTPUT_VARIABLE lipo_output
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE _stderr
+ RESULT_VARIABLE _failed
+ )
+ if(_failed OR NOT lipo_output OR NOT lipo_output MATCHES "(Non-fat file:|Architectures in the fat file:)")
+ set(${ret_failed} TRUE PARENT_SCOPE)
+ return()
+ endif()
+
+ # The lipo output looks like the following:
+ # Non-fat file: <path> is architecture: i386
+ # Architectures in the fat file: <path> are: i386 x86_64
+ string(REGEX REPLACE
+ "^(.+)is architecture:(.+)" "\\2" arches_space_separated "${lipo_output}")
+ string(REGEX REPLACE
+ "^(.+)are:(.+)" "\\2" arches_space_separated "${arches_space_separated}")
+
+ # Need to clean up the arches, with Xcode 4.6.3 the output of lipo -info contains some
+ # additional info, e.g.
+ # Architectures in the fat file: <path> are: armv7 (cputype (12) cpusubtype (11))
+ string(REGEX REPLACE
+ "\\(.+\\)" "" arches_space_separated "${arches_space_separated}")
+
+ # The output is space separated.
+ string(STRIP "${arches_space_separated}" arches_space_separated)
+ string(REPLACE " " ";" arch_list "${arches_space_separated}")
+
+ if(NOT arch_list)
+ set(${ret_failed} TRUE PARENT_SCOPE)
+ return()
+ endif()
+ set(${ret} "${arch_list}" PARENT_SCOPE)
+ else()
+ # This shouldn't happen, but keep it for safety.
+ message(WARNING "No way to find architectures for given sdk_path '${sdk_path}'")
+ set(${ret_failed} TRUE PARENT_SCOPE)
+ endif()
+endfunction()
+
# Handle multi-arch sysroots. Do this before CMAKE_OSX_SYSROOT is
# transformed into a path, so that we know the sysroot name.
function(_apple_resolve_multi_arch_sysroots)
@@ -166,13 +240,8 @@ function(_apple_resolve_multi_arch_sysroots)
continue()
endif()
- execute_process(
- COMMAND plutil -extract SupportedTargets.${sdk}.Archs json ${_sdk_path}/SDKSettings.plist -o -
- OUTPUT_VARIABLE _sdk_archs_json
- OUTPUT_STRIP_TRAILING_WHITESPACE
- ERROR_VARIABLE _stderr
- RESULT_VARIABLE _failed
- )
+ _apple_resolve_supported_archs_for_sdk_from_system_lib(${_sdk_path} _sdk_archs _failed)
+
if(_failed)
# Failure to extract supported architectures for an SDK means that the installed SDK is old
# and does not provide such information (SDKs that come with Xcode >= 10.x started providing
@@ -181,10 +250,6 @@ function(_apple_resolve_multi_arch_sysroots)
return()
endif()
- # Poor man's JSON decoding
- string(REGEX REPLACE "[]\\[\"]" "" _sdk_archs ${_sdk_archs_json})
- string(REPLACE "," ";" _sdk_archs ${_sdk_archs})
-
set(_sdk_archs_${sdk} ${_sdk_archs})
set(_sdk_path_${sdk} ${_sdk_path})
endforeach()
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 56d9174..fb9cad6 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 17)
-set(CMake_VERSION_PATCH 20200416)
+set(CMake_VERSION_PATCH 20200419)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index e481d13..72af10b 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -6,13 +6,13 @@
#include <cm/memory>
#include <cm/string_view>
+#include <cmext/algorithm>
#include "cmsys/Directory.hxx"
#include "cmsys/Encoding.hxx"
#include "cmsys/FStream.hxx"
#include "cmsys/SystemTools.hxx"
-#include "cmAlgorithms.h"
#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
#include "cmCryptoHash.h"
@@ -954,7 +954,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitions(
shortcut.workingDirectoryId = directoryId;
shortcuts.insert(cmWIXShortcuts::START_MENU, id, shortcut);
- if (cmContains(desktopExecutables, executableName)) {
+ if (cm::contains(desktopExecutables, executableName)) {
shortcuts.insert(cmWIXShortcuts::DESKTOP, id, shortcut);
}
}
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 3067f96..058b090 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -9,10 +9,11 @@
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmsys/Directory.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
@@ -529,7 +530,7 @@ int cmCPackNSISGenerator::InitializeInternal()
<< ".lnk\"" << std::endl;
// see if CPACK_CREATE_DESKTOP_LINK_ExeName is on
// if so add a desktop link
- if (cmContains(cpackPackageDesktopLinksVector, execName)) {
+ if (cm::contains(cpackPackageDesktopLinksVector, execName)) {
str << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n";
str << " CreateShortCut \"$DESKTOP\\" << linkName
<< R"(.lnk" "$INSTDIR\)" << cpackNsisExecutablesDirectory << "\\"
diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx
index d6e6be3..e335923 100644
--- a/Source/CTest/cmCTestCoverageCommand.cxx
+++ b/Source/CTest/cmCTestCoverageCommand.cxx
@@ -4,9 +4,10 @@
#include <set>
+#include <cmext/algorithm>
+
#include "cm_static_string_view.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestCoverageHandler.h"
@@ -22,7 +23,7 @@ void cmCTestCoverageCommand::CheckArguments(
std::vector<std::string> const& keywords)
{
this->LabelsMentioned =
- !this->Labels.empty() || cmContains(keywords, "LABELS");
+ !this->Labels.empty() || cm::contains(keywords, "LABELS");
}
cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index a0bece0..85b8ab1 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -10,11 +10,12 @@
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmDuration.h"
#include "cmSystemTools.h"
@@ -591,11 +592,11 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
std::string tempDrMemoryDir =
this->CTest->GetBinaryDir() + "/Testing/Temporary/DrMemory";
- if (!cmContains(this->MemoryTesterOptions, "-quiet")) {
+ if (!cm::contains(this->MemoryTesterOptions, "-quiet")) {
this->MemoryTesterOptions.emplace_back("-quiet");
}
- if (!cmContains(this->MemoryTesterOptions, "-batch")) {
+ if (!cm::contains(this->MemoryTesterOptions, "-batch")) {
this->MemoryTesterOptions.emplace_back("-batch");
}
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 50c963d..3fc417a 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -29,7 +29,6 @@
#include "cm_uv.h"
#include "cmAffinity.h"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestBinPacker.h"
#include "cmCTestRunTest.h"
@@ -188,7 +187,7 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
// Find any failed dependencies for this test. We assume the more common
// scenario has no failed tests, so make it the outer loop.
for (std::string const& f : *this->Failed) {
- if (cmContains(this->Properties[test]->RequireSuccessDepends, f)) {
+ if (cm::contains(this->Properties[test]->RequireSuccessDepends, f)) {
testRun->AddFailedDependency(f);
}
}
@@ -445,7 +444,7 @@ bool cmCTestMultiProcessHandler::StartTest(int test)
{
// Check for locked resources
for (std::string const& i : this->Properties[test]->LockedResources) {
- if (cmContains(this->LockedResources, i)) {
+ if (cm::contains(this->LockedResources, i)) {
return false;
}
}
@@ -802,7 +801,7 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList()
// In parallel test runs add previously failed tests to the front
// of the cost list and queue other tests for further sorting
for (auto const& t : this->Tests) {
- if (cmContains(this->LastTestsFailed, this->Properties[t.first]->Name)) {
+ if (cm::contains(this->LastTestsFailed, this->Properties[t.first]->Name)) {
// If the test failed last time, it should be run first.
this->SortedTests.push_back(t.first);
alreadySortedTests.insert(t.first);
@@ -841,7 +840,7 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList()
TestComparator(this));
for (auto const& j : sortedCopy) {
- if (!cmContains(alreadySortedTests, j)) {
+ if (!cm::contains(alreadySortedTests, j)) {
this->SortedTests.push_back(j);
alreadySortedTests.insert(j);
}
@@ -873,7 +872,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList()
TestSet alreadySortedTests;
for (int test : presortedList) {
- if (cmContains(alreadySortedTests, test)) {
+ if (cm::contains(alreadySortedTests, test)) {
continue;
}
@@ -881,7 +880,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList()
GetAllTestDependencies(test, dependencies);
for (int testDependency : dependencies) {
- if (!cmContains(alreadySortedTests, testDependency)) {
+ if (!cm::contains(alreadySortedTests, testDependency)) {
alreadySortedTests.insert(testDependency);
this->SortedTests.push_back(testDependency);
}
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index acb75b2..5b2f2e6 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -8,10 +8,10 @@
#include <cm/memory>
#include <cm/vector>
+#include <cmext/algorithm>
#include "cm_static_string_view.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestSubmitHandler.h"
#include "cmCommand.h"
@@ -172,8 +172,10 @@ void cmCTestSubmitCommand::BindArguments()
void cmCTestSubmitCommand::CheckArguments(
std::vector<std::string> const& keywords)
{
- this->PartsMentioned = !this->Parts.empty() || cmContains(keywords, "PARTS");
- this->FilesMentioned = !this->Files.empty() || cmContains(keywords, "FILES");
+ this->PartsMentioned =
+ !this->Parts.empty() || cm::contains(keywords, "PARTS");
+ this->FilesMentioned =
+ !this->Files.empty() || cm::contains(keywords, "FILES");
cm::erase_if(this->Parts, [this](std::string const& arg) -> bool {
cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str());
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index ca65946..7f21633 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -19,6 +19,7 @@
#include <cm/memory>
#include <cm/string_view>
+#include <cmext/algorithm>
#include "cmsys/FStream.hxx"
#include <cmsys/Base64.h>
@@ -28,7 +29,6 @@
#include "cm_static_string_view.hxx"
#include "cm_utf8.h"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestMultiProcessHandler.h"
#include "cmCTestResourceGroupsLexerHelper.h"
@@ -711,7 +711,7 @@ void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject)
cmCTestTestProperties& p = *result.Properties;
for (std::string const& l : p.Labels) {
// only use labels found in labels
- if (cmContains(labels, l)) {
+ if (cm::contains(labels, l)) {
labelTimes[l] +=
result.ExecutionTime.count() * result.Properties->Processors;
++labelCounts[l];
@@ -853,14 +853,15 @@ void cmCTestTestHandler::ComputeTestList()
if (this->UseUnion) {
// if it is not in the list and not in the regexp then skip
- if ((!this->TestsToRun.empty() && !cmContains(this->TestsToRun, cnt)) &&
+ if ((!this->TestsToRun.empty() &&
+ !cm::contains(this->TestsToRun, cnt)) &&
!tp.IsInBasedOnREOptions) {
continue;
}
} else {
// is this test in the list of tests to run? If not then skip it
if ((!this->TestsToRun.empty() &&
- !cmContains(this->TestsToRun, inREcnt)) ||
+ !cm::contains(this->TestsToRun, inREcnt)) ||
!tp.IsInBasedOnREOptions) {
continue;
}
@@ -889,7 +890,7 @@ void cmCTestTestHandler::ComputeTestListForRerunFailed()
cnt++;
// if this test is not in our list of tests to run, then skip it.
- if (!this->TestsToRun.empty() && !cmContains(this->TestsToRun, cnt)) {
+ if (!this->TestsToRun.empty() && !cm::contains(this->TestsToRun, cnt)) {
continue;
}
@@ -1008,7 +1009,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
for (auto sIt = setupRange.first; sIt != setupRange.second; ++sIt) {
const std::string& setupTestName = sIt->second->Name;
tests[i].RequireSuccessDepends.insert(setupTestName);
- if (!cmContains(tests[i].Depends, setupTestName)) {
+ if (!cm::contains(tests[i].Depends, setupTestName)) {
tests[i].Depends.push_back(setupTestName);
}
}
@@ -1112,7 +1113,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
const std::vector<size_t>& indices = cIt->second;
for (size_t index : indices) {
const std::string& reqTestName = tests[index].Name;
- if (!cmContains(p.Depends, reqTestName)) {
+ if (!cm::contains(p.Depends, reqTestName)) {
p.Depends.push_back(reqTestName);
}
}
@@ -1125,7 +1126,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
const std::vector<size_t>& indices = cIt->second;
for (size_t index : indices) {
const std::string& setupTestName = tests[index].Name;
- if (!cmContains(p.Depends, setupTestName)) {
+ if (!cm::contains(p.Depends, setupTestName)) {
p.Depends.push_back(setupTestName);
}
}
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index c0ac551..8b0aa5e 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -13,20 +13,12 @@
#include <utility>
#include <vector>
+#include <cmext/algorithm>
+
#include "cm_kwiml.h"
#include "cmRange.h"
-template <std::size_t N>
-struct cmOverloadPriority : cmOverloadPriority<N - 1>
-{
-};
-
-template <>
-struct cmOverloadPriority<0>
-{
-};
-
template <typename FwdIt>
FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last)
{
@@ -37,34 +29,6 @@ FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last)
return first;
}
-template <typename Range, typename Key>
-auto cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<2>)
- -> decltype(range.exists(key))
-{
- return range.exists(key);
-}
-
-template <typename Range, typename Key>
-auto cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<1>)
- -> decltype(range.find(key) != range.end())
-{
- return range.find(key) != range.end();
-}
-
-template <typename Range, typename Key>
-bool cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<0>)
-{
- using std::begin;
- using std::end;
- return std::find(begin(range), end(range), key) != end(range);
-}
-
-template <typename Range, typename Key>
-bool cmContains(Range const& range, Key const& key)
-{
- return cmContainsImpl(range, key, cmOverloadPriority<2>{});
-}
-
namespace ContainerAlgorithms {
template <typename FwdIt>
@@ -158,7 +122,7 @@ ForwardIterator cmRemoveDuplicates(ForwardIterator first, ForwardIterator last)
ForwardIterator result = first;
while (first != last) {
- if (!cmContains(uniq, first)) {
+ if (!cm::contains(uniq, first)) {
if (result != first) {
*result = std::move(*first);
}
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index d8a6204..f0174d9 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -9,8 +9,8 @@
#include <utility>
#include <cm/memory>
+#include <cmext/algorithm>
-#include "cmAlgorithms.h"
#include "cmComputeLinkDepends.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -610,7 +610,7 @@ void cmComputeLinkInformation::AddRuntimeLinkLibrary(std::string const& lang)
runtimeLibrary)) {
std::vector<std::string> libsVec = cmExpandedList(runtimeLinkOptions);
for (std::string const& i : libsVec) {
- if (!cmContains(this->ImplicitLinkLibs, i)) {
+ if (!cm::contains(this->ImplicitLinkLibs, i)) {
this->AddItem(i, nullptr);
}
}
@@ -627,7 +627,7 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
if (const char* libs = this->Makefile->GetDefinition(libVar)) {
std::vector<std::string> libsVec = cmExpandedList(libs);
for (std::string const& i : libsVec) {
- if (!cmContains(this->ImplicitLinkLibs, i)) {
+ if (!cm::contains(this->ImplicitLinkLibs, i)) {
this->AddItem(i, nullptr);
}
}
@@ -1064,8 +1064,8 @@ void cmComputeLinkInformation::AddTargetItem(BT<std::string> const& item,
// For compatibility with CMake 2.4 include the item's directory in
// the linker search path.
if (this->OldLinkDirMode && !target->IsFrameworkOnApple() &&
- !cmContains(this->OldLinkDirMask,
- cmSystemTools::GetFilenamePath(item.Value))) {
+ !cm::contains(this->OldLinkDirMask,
+ cmSystemTools::GetFilenamePath(item.Value))) {
this->OldLinkDirItems.push_back(item.Value);
}
@@ -1118,8 +1118,8 @@ void cmComputeLinkInformation::AddFullItem(BT<std::string> const& item)
// For compatibility with CMake 2.4 include the item's directory in
// the linker search path.
if (this->OldLinkDirMode &&
- !cmContains(this->OldLinkDirMask,
- cmSystemTools::GetFilenamePath(item.Value))) {
+ !cm::contains(this->OldLinkDirMask,
+ cmSystemTools::GetFilenamePath(item.Value))) {
this->OldLinkDirItems.push_back(item.Value);
}
@@ -1138,7 +1138,7 @@ bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
// Check if this item is in an implicit link directory.
std::string dir = cmSystemTools::GetFilenamePath(item);
- if (!cmContains(this->ImplicitLinkDirs, dir)) {
+ if (!cm::contains(this->ImplicitLinkDirs, dir)) {
// Only libraries in implicit link directories are converted to
// pathless items.
return false;
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index bf11022..7a3a3e8 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -13,7 +13,6 @@
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmState.h"
@@ -673,7 +672,7 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs,
if (def2) {
std::vector<std::string> list = cmExpandedList(def2, true);
- result = cmContains(list, def);
+ result = cm::contains(list, def);
}
this->HandleBinaryOp(result, reducible, arg, newArgs, argP1, argP2);
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 9175dac..dc2df14 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -40,6 +40,8 @@ static std::string const kCMAKE_CXX_LINK_NO_PIE_SUPPORTED =
"CMAKE_CXX_LINK_NO_PIE_SUPPORTED";
static std::string const kCMAKE_CXX_LINK_PIE_SUPPORTED =
"CMAKE_CXX_LINK_PIE_SUPPORTED";
+static std::string const kCMAKE_CUDA_ARCHITECTURES =
+ "CMAKE_CUDA_ARCHITECTURES";
static std::string const kCMAKE_CUDA_COMPILER_TARGET =
"CMAKE_CUDA_COMPILER_TARGET";
static std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS";
@@ -713,6 +715,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
vars.insert(kCMAKE_C_COMPILER_TARGET);
vars.insert(kCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN);
vars.insert(kCMAKE_CXX_COMPILER_TARGET);
+ vars.insert(kCMAKE_CUDA_ARCHITECTURES);
vars.insert(kCMAKE_CUDA_COMPILER_TARGET);
vars.insert(kCMAKE_ENABLE_EXPORTS);
vars.insert(kCMAKE_LINK_SEARCH_END_STATIC);
diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx
index d4e8da6..d8aa730 100644
--- a/Source/cmDepends.cxx
+++ b/Source/cmDepends.cxx
@@ -9,12 +9,12 @@
#include "cmFileTime.h"
#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
-#include "cmLocalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-cmDepends::cmDepends(cmLocalGenerator* lg, std::string targetDir)
+cmDepends::cmDepends(cmLocalUnixMakefileGenerator3* lg, std::string targetDir)
: LocalGenerator(lg)
, TargetDirectory(std::move(targetDir))
{
diff --git a/Source/cmDepends.h b/Source/cmDepends.h
index d938775..8cf528f 100644
--- a/Source/cmDepends.h
+++ b/Source/cmDepends.h
@@ -12,7 +12,7 @@
#include <vector>
class cmFileTimeCache;
-class cmLocalGenerator;
+class cmLocalUnixMakefileGenerator3;
/** \class cmDepends
* \brief Dependency scanner superclass.
@@ -29,7 +29,8 @@ public:
public:
/** Instances need to know the build directory name and the relative
path from the build directory to the target file. */
- cmDepends(cmLocalGenerator* lg = nullptr, std::string targetDir = "");
+ cmDepends(cmLocalUnixMakefileGenerator3* lg = nullptr,
+ std::string targetDir = "");
cmDepends(cmDepends const&) = delete;
cmDepends& operator=(cmDepends const&) = delete;
@@ -38,7 +39,10 @@ public:
scanning dependencies. This is not a full local generator; it
has been setup to do relative path conversions for the current
directory. */
- void SetLocalGenerator(cmLocalGenerator* lg) { this->LocalGenerator = lg; }
+ void SetLocalGenerator(cmLocalUnixMakefileGenerator3* lg)
+ {
+ this->LocalGenerator = lg;
+ }
/** Set the specific language to be scanned. */
void SetLanguage(const std::string& lang) { this->Language = lang; }
@@ -92,7 +96,7 @@ protected:
std::ostream& internalDepends);
// The local generator.
- cmLocalGenerator* LocalGenerator;
+ cmLocalUnixMakefileGenerator3* LocalGenerator;
// Flag for verbose output.
bool Verbose = false;
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index 01bb6ed..4499a66 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -7,7 +7,7 @@
#include "cmsys/FStream.hxx"
#include "cmFileTime.h"
-#include "cmLocalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -22,8 +22,9 @@
cmDependsC::cmDependsC() = default;
-cmDependsC::cmDependsC(cmLocalGenerator* lg, const std::string& targetDir,
- const std::string& lang, const DependencyMap* validDeps)
+cmDependsC::cmDependsC(cmLocalUnixMakefileGenerator3* lg,
+ const std::string& targetDir, const std::string& lang,
+ const DependencyMap* validDeps)
: cmDepends(lg, targetDir)
, ValidDeps(validDeps)
{
@@ -211,12 +212,12 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
// written by the original local generator for this directory
// convert the dependencies to paths relative to the home output
// directory. We must do the same here.
- std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i);
+ std::string obj_m = this->LocalGenerator->ConvertToMakefilePath(obj_i);
internalDepends << obj_i << '\n';
for (std::string const& dep : dependencies) {
makeDepends << obj_m << ": "
- << cmSystemTools::ConvertToOutputPath(
+ << this->LocalGenerator->ConvertToMakefilePath(
this->LocalGenerator->MaybeConvertToRelativePath(binDir,
dep))
<< '\n';
diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h
index 868c94a..e01faa4 100644
--- a/Source/cmDependsC.h
+++ b/Source/cmDependsC.h
@@ -16,7 +16,7 @@
#include "cmDepends.h"
-class cmLocalGenerator;
+class cmLocalUnixMakefileGenerator3;
/** \class cmDependsC
* \brief Dependency scanner for C and C++ object files.
@@ -27,7 +27,7 @@ public:
/** Checking instances need to know the build directory name and the
relative path from the build directory to the target file. */
cmDependsC();
- cmDependsC(cmLocalGenerator* lg, const std::string& targetDir,
+ cmDependsC(cmLocalUnixMakefileGenerator3* lg, const std::string& targetDir,
const std::string& lang, const DependencyMap* validDeps);
/** Virtual destructor to cleanup subclasses properly. */
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index c45cd1c..95dfc4e 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -12,7 +12,7 @@
#include "cmFortranParser.h" /* Interface to parser object. */
#include "cmGeneratedFileStream.h"
-#include "cmLocalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
#include "cmStateDirectory.h"
@@ -70,7 +70,7 @@ public:
cmDependsFortran::cmDependsFortran() = default;
-cmDependsFortran::cmDependsFortran(cmLocalGenerator* lg)
+cmDependsFortran::cmDependsFortran(cmLocalUnixMakefileGenerator3* lg)
: cmDepends(lg)
, Internal(new cmDependsFortranInternals)
{
diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h
index e3e0d05..3e306dd 100644
--- a/Source/cmDependsFortran.h
+++ b/Source/cmDependsFortran.h
@@ -15,7 +15,7 @@
class cmDependsFortranInternals;
class cmFortranSourceInfo;
-class cmLocalGenerator;
+class cmLocalUnixMakefileGenerator3;
/** \class cmDependsFortran
* \brief Dependency scanner for Fortran object files.
@@ -31,7 +31,7 @@ public:
path from the build directory to the target file, the source
file from which to start scanning, the include file search
path, and the target directory. */
- cmDependsFortran(cmLocalGenerator* lg);
+ cmDependsFortran(cmLocalUnixMakefileGenerator3* lg);
/** Virtual destructor to cleanup subclasses properly. */
~cmDependsFortran() override;
diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx
index a2b4d60..0ee1259 100644
--- a/Source/cmExportBuildAndroidMKGenerator.cxx
+++ b/Source/cmExportBuildAndroidMKGenerator.cxx
@@ -5,7 +5,8 @@
#include <sstream>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmGeneratorTarget.h"
#include "cmLinkItem.h"
#include "cmMakefile.h"
@@ -165,7 +166,7 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
// Tell the NDK build system if prebuilt static libraries use C++.
if (target->GetType() == cmStateEnums::STATIC_LIBRARY) {
cmLinkImplementation const* li = target->GetLinkImplementation(config);
- if (cmContains(li->Languages, "CXX")) {
+ if (cm::contains(li->Languages, "CXX")) {
os << "LOCAL_HAS_CPP := true\n";
}
}
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index d22bd48..dd700c5 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -8,7 +8,8 @@
#include <sstream>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmExportSet.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -307,7 +308,7 @@ cmExportBuildFileGenerator::FindBuildExportInfo(cmGlobalGenerator* gg,
const auto& exportSet = exp.second;
std::vector<std::string> targets;
exportSet->GetTargets(targets);
- if (cmContains(targets, name)) {
+ if (cm::contains(targets, name)) {
exportFiles.push_back(exp.first);
ns = exportSet->GetNamespace();
}
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index f31759d..ad632ee 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -7,12 +7,12 @@
#include <utility>
#include <cm/memory>
+#include <cmext/algorithm>
#include "cmsys/RegularExpression.hxx"
#include "cm_static_string_view.hxx"
-#include "cmAlgorithms.h"
#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
#include "cmExportBuildAndroidMKGenerator.h"
@@ -147,7 +147,7 @@ bool cmExportCommand(std::vector<std::string> const& args,
}
exportSet = &it->second;
} else if (!arguments.Targets.empty() ||
- cmContains(keywordsMissingValue, "TARGETS")) {
+ cm::contains(keywordsMissingValue, "TARGETS")) {
for (std::string const& currentTarget : arguments.Targets) {
if (mf.IsAlias(currentTarget)) {
std::ostringstream e;
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index af3c554..4ec128e 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -2980,7 +2980,7 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
};
if (!parsedArgs.Format.empty() &&
- !cmContains(knownFormats, parsedArgs.Format)) {
+ !cm::contains(knownFormats, parsedArgs.Format)) {
status.SetError(
cmStrCat("archive format ", parsedArgs.Format, " not supported"));
cmSystemTools::SetFatalErrorOccured();
@@ -2989,7 +2989,7 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
const char* zipFileFormats[] = { "7zip", "zip" };
if (!parsedArgs.Type.empty() &&
- cmContains(zipFileFormats, parsedArgs.Format)) {
+ cm::contains(zipFileFormats, parsedArgs.Format)) {
status.SetError(cmStrCat("archive format ", parsedArgs.Format,
" does not support TYPE arguments"));
cmSystemTools::SetFatalErrorOccured();
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index dfc354d..754a446 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -15,6 +15,7 @@
#include <cm/iterator>
#include <cm/string_view>
+#include <cmext/algorithm>
#include "cmsys/RegularExpression.hxx"
#include "cmsys/String.h"
@@ -313,7 +314,7 @@ static const struct InListNode : public cmGeneratorExpressionNode
break;
}
- return cmContains(values, parameters.front()) ? "1" : "0";
+ return cm::contains(values, parameters.front()) ? "1" : "0";
}
} inListNode;
@@ -921,8 +922,8 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
if (const char* mapValue =
context->CurrentTarget->GetProperty(mapProp)) {
cmExpandList(cmSystemTools::UpperCase(mapValue), mappedConfigs);
- return cmContains(mappedConfigs,
- cmSystemTools::UpperCase(parameters.front()))
+ return cm::contains(mappedConfigs,
+ cmSystemTools::UpperCase(parameters.front()))
? "1"
: "0";
}
@@ -1659,7 +1660,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
const char* standardDefault = context->LG->GetMakefile()->GetDefinition(
"CMAKE_" + lit.first + "_STANDARD_DEFAULT");
for (std::string const& it : lit.second) {
- if (!cmContains(langAvailable, it)) {
+ if (!cm::contains(langAvailable, it)) {
return "0";
}
if (standardDefault && !*standardDefault) {
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 55157b4..db25ddf 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1309,7 +1309,8 @@ std::string AddSwiftInterfaceIncludeDirectories(
target->GetLinkInterfaceLibraries(config, root, true)) {
for (const cmLinkItem& library : interface->Libraries) {
if (const cmGeneratorTarget* dependency = library.Target) {
- if (cmContains(dependency->GetAllConfigCompileLanguages(), "Swift")) {
+ if (cm::contains(dependency->GetAllConfigCompileLanguages(),
+ "Swift")) {
std::string value =
dependency->GetSafeProperty("Swift_MODULE_DIRECTORY");
if (value.empty()) {
@@ -1339,7 +1340,8 @@ void AddSwiftImplicitIncludeDirectories(
for (const cmLinkImplItem& library : libraries->Libraries) {
if (const cmGeneratorTarget* dependency = library.Target) {
- if (cmContains(dependency->GetAllConfigCompileLanguages(), "Swift")) {
+ if (cm::contains(dependency->GetAllConfigCompileLanguages(),
+ "Swift")) {
EvaluatedTargetPropertyEntry entry{ library, library.Backtrace };
if (const char* val =
@@ -1522,7 +1524,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
}
bool debugSources =
- !this->DebugSourcesDone && cmContains(debugProperties, "SOURCES");
+ !this->DebugSourcesDone && cm::contains(debugProperties, "SOURCES");
if (this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026()) {
this->DebugSourcesDone = true;
@@ -2806,7 +2808,7 @@ cmTargetTraceDependencies::cmTargetTraceDependencies(cmGeneratorTarget* target)
for (cmSourceFile* sf : sources) {
const std::set<cmGeneratorTarget const*> tgts =
this->GlobalGenerator->GetFilenameTargetDepends(sf);
- if (cmContains(tgts, this->GeneratorTarget)) {
+ if (cm::contains(tgts, this->GeneratorTarget)) {
std::ostringstream e;
e << "Evaluation output file\n \"" << sf->ResolveFullPath()
<< "\"\ndepends on the sources of a target it is used in. This "
@@ -3085,6 +3087,95 @@ void cmGeneratorTarget::GetAppleArchs(const std::string& config,
}
}
+void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
+{
+ struct CudaArchitecture
+ {
+ std::string name;
+ bool real{ true };
+ bool virtual_{ true };
+ };
+ std::vector<CudaArchitecture> architectures;
+
+ {
+ std::vector<std::string> options;
+ cmExpandList(this->GetSafeProperty("CUDA_ARCHITECTURES"), options);
+
+ if (options.empty()) {
+ switch (this->GetPolicyStatusCMP0104()) {
+ case cmPolicies::WARN:
+ if (!this->LocalGenerator->GetCMakeInstance()->GetIsInTryCompile()) {
+ this->Makefile->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0104) +
+ "\nCUDA_ARCHITECTURES is empty for target \"" +
+ this->GetName() + "\".");
+ }
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ break;
+ default:
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "CUDA_ARCHITECTURES is empty for target \"" + this->GetName() +
+ "\".");
+ }
+ }
+
+ for (std::string& option : options) {
+ CudaArchitecture architecture;
+
+ // Architecture name is up to the first specifier.
+ std::size_t pos = option.find_first_of('-');
+ architecture.name = option.substr(0, pos);
+
+ if (pos != std::string::npos) {
+ cm::string_view specifier{ option.c_str() + pos + 1,
+ option.length() - pos - 1 };
+
+ if (specifier == "real") {
+ architecture.real = true;
+ architecture.virtual_ = false;
+ } else if (specifier == "virtual") {
+ architecture.real = false;
+ architecture.virtual_ = true;
+ } else {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "Uknown CUDA architecture specifier \"" + std::string(specifier) +
+ "\".");
+ }
+ }
+
+ architectures.emplace_back(architecture);
+ }
+ }
+
+ std::string const& compiler =
+ this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID");
+
+ if (compiler == "NVIDIA") {
+ for (CudaArchitecture& architecture : architectures) {
+ flags +=
+ " --generate-code=arch=compute_" + architecture.name + ",code=[";
+
+ if (architecture.virtual_) {
+ flags += "compute_" + architecture.name;
+
+ if (architecture.real) {
+ flags += ",";
+ }
+ }
+
+ if (architecture.real) {
+ flags += "sm_" + architecture.name;
+ }
+
+ flags += "]";
+ }
+ }
+}
+
//----------------------------------------------------------------------------
std::string cmGeneratorTarget::GetFeatureSpecificLinkRuleVariable(
std::string const& var, std::string const& lang,
@@ -3250,7 +3341,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
}
bool debugIncludes = !this->DebugIncludesDone &&
- cmContains(debugProperties, "INCLUDE_DIRECTORIES");
+ cm::contains(debugProperties, "INCLUDE_DIRECTORIES");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugIncludesDone = true;
@@ -3365,7 +3456,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions(
}
bool debugOptions = !this->DebugCompileOptionsDone &&
- cmContains(debugProperties, "COMPILE_OPTIONS");
+ cm::contains(debugProperties, "COMPILE_OPTIONS");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompileOptionsDone = true;
@@ -3411,7 +3502,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileFeatures(
}
bool debugFeatures = !this->DebugCompileFeaturesDone &&
- cmContains(debugProperties, "COMPILE_FEATURES");
+ cm::contains(debugProperties, "COMPILE_FEATURES");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompileFeaturesDone = true;
@@ -3459,7 +3550,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
}
bool debugDefines = !this->DebugCompileDefinitionsDone &&
- cmContains(debugProperties, "COMPILE_DEFINITIONS");
+ cm::contains(debugProperties, "COMPILE_DEFINITIONS");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompileDefinitionsDone = true;
@@ -3890,8 +3981,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
cmExpandList(debugProp, debugProperties);
}
- bool debugOptions =
- !this->DebugLinkOptionsDone && cmContains(debugProperties, "LINK_OPTIONS");
+ bool debugOptions = !this->DebugLinkOptionsDone &&
+ cm::contains(debugProperties, "LINK_OPTIONS");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugLinkOptionsDone = true;
@@ -4147,7 +4238,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
}
bool debugDirectories = !this->DebugLinkDirectoriesDone &&
- cmContains(debugProperties, "LINK_DIRECTORIES");
+ cm::contains(debugProperties, "LINK_DIRECTORIES");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugLinkDirectoriesDone = true;
@@ -5308,7 +5399,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
PropertyType propContent = getTypedProperty<PropertyType>(tgt, p);
std::vector<std::string> headPropKeys = tgt->GetPropertyKeys();
- const bool explicitlySet = cmContains(headPropKeys, p);
+ const bool explicitlySet = cm::contains(headPropKeys, p);
const bool impliedByUse = tgt->IsNullImpliedByLinkLibraries(p);
assert((impliedByUse ^ explicitlySet) || (!impliedByUse && !explicitlySet));
@@ -5348,7 +5439,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
std::vector<std::string> propKeys = theTarget->GetPropertyKeys();
- const bool ifaceIsSet = cmContains(propKeys, interfaceProperty);
+ const bool ifaceIsSet = cm::contains(propKeys, interfaceProperty);
PropertyType ifacePropContent = getTypedProperty<PropertyType>(
theTarget, interfaceProperty, genexInterpreter.get());
@@ -5639,8 +5730,8 @@ void cmGeneratorTarget::ReportPropertyOrigin(
cmExpandList(debugProp, debugProperties);
}
- bool debugOrigin =
- !this->DebugCompatiblePropertiesDone[p] && cmContains(debugProperties, p);
+ bool debugOrigin = !this->DebugCompatiblePropertiesDone[p] &&
+ cm::contains(debugProperties, p);
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompatiblePropertiesDone[p] = true;
@@ -6806,7 +6897,7 @@ cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
bool cmGeneratorTarget::IsNullImpliedByLinkLibraries(
const std::string& p) const
{
- return cmContains(this->LinkImplicitNullProperties, p);
+ return cm::contains(this->LinkImplicitNullProperties, p);
}
void cmGeneratorTarget::ComputeLinkImplementationLibraries(
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 9136928..7cd253d 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -421,6 +421,8 @@ public:
void GetAppleArchs(const std::string& config,
std::vector<std::string>& archVec) const;
+ void AddCUDAArchitectureFlags(std::string& flags) const;
+
std::string GetFeatureSpecificLinkRuleVariable(
std::string const& var, std::string const& lang,
std::string const& config) const;
diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h
index 9af0eac..3c97955 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.h
+++ b/Source/cmGlobalBorlandMakefileGenerator.h
@@ -46,6 +46,7 @@ public:
bool AllowNotParallel() const override { return false; }
bool AllowDeleteOnError() const override { return false; }
+ bool CanEscapeOctothorpe() const override { return true; }
protected:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 8505d43..a6ca75f 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -14,6 +14,7 @@
#include <utility>
#include <cm/memory>
+#include <cmext/algorithm>
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
@@ -403,7 +404,7 @@ bool cmGlobalGenerator::IsExportedTargetsFile(
if (it == this->BuildExportSets.end()) {
return false;
}
- return !cmContains(this->BuildExportExportSets, filename);
+ return !cm::contains(this->BuildExportExportSets, filename);
}
// Find the make program for the generator, required for try compiles
@@ -529,7 +530,7 @@ void cmGlobalGenerator::EnableLanguage(
if (lang == "NONE") {
this->SetLanguageEnabled("NONE", mf);
} else {
- if (!cmContains(this->LanguagesReady, lang)) {
+ if (!cm::contains(this->LanguagesReady, lang)) {
std::ostringstream e;
e << "The test project needs language " << lang
<< " which is not enabled.";
@@ -1094,7 +1095,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l,
{
// use LanguageToLinkerPreference to detect whether this functions has
// run before
- if (cmContains(this->LanguageToLinkerPreference, l)) {
+ if (cm::contains(this->LanguageToLinkerPreference, l)) {
return;
}
@@ -2227,7 +2228,7 @@ void cmGlobalGenerator::AddAlias(const std::string& name,
bool cmGlobalGenerator::IsAlias(const std::string& name) const
{
- return cmContains(this->AliasTargets, name);
+ return cm::contains(this->AliasTargets, name);
}
void cmGlobalGenerator::IndexTarget(cmTarget* t)
@@ -2792,7 +2793,7 @@ bool cmGlobalGenerator::IsReservedTarget(std::string const& name)
"clean", "edit_cache", "rebuild_cache",
"ZERO_CHECK" };
- return cmContains(reservedTargets, name);
+ return cm::contains(reservedTargets, name);
}
void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 289a035..24559e6 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -10,8 +10,8 @@
#include <cm/memory>
#include <cm/string>
+#include <cmext/algorithm>
-#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
@@ -585,14 +585,14 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand(
/* if multiple top-projects are found in build directory
* then prefer projectName top-project.
*/
- if (!cmContains(files, proj)) {
+ if (!cm::contains(files, proj)) {
proj = files.at(0);
}
}
makeCommand.Add("-top", proj);
if (!targetNames.empty()) {
- if (cmContains(targetNames, "clean")) {
+ if (cm::contains(targetNames, "clean")) {
makeCommand.Add("-clean");
} else {
for (const auto& tname : targetNames) {
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 5a31ab2..716d7df 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -18,7 +18,6 @@
#include "cm_jsoncpp_value.h"
#include "cm_jsoncpp_writer.h"
-#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmFortranParser.h"
#include "cmGeneratedFileStream.h"
@@ -436,8 +435,6 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
#ifdef _WIN32
cm->GetState()->SetWindowsShell(true);
#endif
- // // Ninja is not ported to non-Unix OS yet.
- // this->ForceUnixPaths = true;
this->FindMakeProgramFile = "CMakeNinjaFindMake.cmake";
}
@@ -687,10 +684,10 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures()
bool cmGlobalNinjaGenerator::CheckLanguages(
std::vector<std::string> const& languages, cmMakefile* mf) const
{
- if (cmContains(languages, "Fortran")) {
+ if (cm::contains(languages, "Fortran")) {
return this->CheckFortran(mf);
}
- if (cmContains(languages, "Swift")) {
+ if (cm::contains(languages, "Swift")) {
const std::string architectures =
mf->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES");
if (architectures.find_first_of(';') != std::string::npos) {
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 582877f..5363ea5 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -117,6 +117,12 @@ void cmGlobalUnixMakefileGenerator3::ComputeTargetObjectDirectory(
gt->ObjectDirectory = dir;
}
+bool cmGlobalUnixMakefileGenerator3::CanEscapeOctothorpe() const
+{
+ // Make tools that use UNIX-style '/' paths also support '\' escaping.
+ return this->ForceUnixPaths;
+}
+
void cmGlobalUnixMakefileGenerator3::Configure()
{
// Initialize CMAKE_EDIT_COMMAND cache entry.
@@ -480,6 +486,78 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2(
}
}
+namespace {
+std::string ConvertToMakefilePathForUnix(std::string const& path)
+{
+ std::string result;
+ result.reserve(path.size());
+ for (char c : path) {
+ switch (c) {
+ case '=':
+ // We provide 'EQUALS = =' to encode '=' in a non-assignment case.
+ result.append("$(EQUALS)");
+ break;
+ case '$':
+ result.append("$$");
+ break;
+ case '\\':
+ case ' ':
+ case '#':
+ result.push_back('\\');
+ CM_FALLTHROUGH;
+ default:
+ result.push_back(c);
+ break;
+ }
+ }
+ return result;
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+std::string ConvertToMakefilePathForWindows(std::string const& path)
+{
+ bool const quote = path.find_first_of(" #") != std::string::npos;
+ std::string result;
+ result.reserve(path.size() + (quote ? 2 : 0));
+ if (quote) {
+ result.push_back('"');
+ }
+ for (char c : path) {
+ switch (c) {
+ case '=':
+ // We provide 'EQUALS = =' to encode '=' in a non-assignment case.
+ result.append("$(EQUALS)");
+ break;
+ case '$':
+ result.append("$$");
+ break;
+ case '/':
+ result.push_back('\\');
+ break;
+ default:
+ result.push_back(c);
+ break;
+ }
+ }
+ if (quote) {
+ result.push_back('"');
+ }
+ return result;
+}
+#endif
+}
+
+std::string cmGlobalUnixMakefileGenerator3::ConvertToMakefilePath(
+ std::string const& path) const
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (!this->ForceUnixPaths) {
+ return ConvertToMakefilePathForWindows(path);
+ }
+#endif
+ return ConvertToMakefilePathForUnix(path);
+}
+
std::vector<cmGlobalGenerator::GeneratedMakeCommand>
cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
const std::string& makeProgram, const std::string& /*projectName*/,
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 19b2b85..1caa4b7 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -136,6 +136,12 @@ public:
or dependencies. */
std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; }
+ /**
+ * Convert a file path to a Makefile target or dependency with
+ * escaping and quoting suitable for the generator's make tool.
+ */
+ std::string ConvertToMakefilePath(std::string const& path) const;
+
// change the build command for speed
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
@@ -157,6 +163,9 @@ public:
/** Does the make tool tolerate .DELETE_ON_ERROR? */
virtual bool AllowDeleteOnError() const { return true; }
+ /** Does the make tool interpret '\#' as '#'? */
+ virtual bool CanEscapeOctothorpe() const;
+
bool IsIPOSupported() const override { return true; }
void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index c0068b4..1a753e2 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -15,7 +15,6 @@
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -363,7 +362,7 @@ cmGlobalXCodeGenerator::GenerateBuildCommand(
std::string projectArg = cmStrCat(projectName, ".xcodeproj");
makeCommand.Add(projectArg);
}
- if (cmContains(targetNames, "clean")) {
+ if (cm::contains(targetNames, "clean")) {
makeCommand.Add("clean");
makeCommand.Add("-target", "ALL_BUILD");
} else {
@@ -911,7 +910,7 @@ void cmGlobalXCodeGenerator::AddXCodeProjBuildRule(
"/CMakeLists.txt");
cmSourceFile* srcCMakeLists = target->Makefile->GetOrCreateSource(
listfile, false, cmSourceFileLocationKind::Known);
- if (!cmContains(sources, srcCMakeLists)) {
+ if (!cm::contains(sources, srcCMakeLists)) {
sources.push_back(srcCMakeLists);
}
}
@@ -1427,8 +1426,8 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmGeneratorTarget* gtgt)
bool cmGlobalXCodeGenerator::IsHeaderFile(cmSourceFile* sf)
{
- return cmContains(this->CMakeInstance->GetHeaderExtensions(),
- sf->GetExtension());
+ return cm::contains(this->CMakeInstance->GetHeaderExtensions(),
+ sf->GetExtension());
}
cmXCodeObject* cmGlobalXCodeGenerator::CreateBuildPhase(
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index ae87e45..f27648c 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -10,7 +10,8 @@
#include <string>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmListFileCache.h"
#include "cmSystemTools.h"
#include "cmTargetLinkLibraryType.h"
@@ -127,7 +128,7 @@ inline cmTargetLinkLibraryType CMP0003_ComputeLinkType(
// Check if any entry in the list matches this configuration.
std::string configUpper = cmSystemTools::UpperCase(config);
- if (cmContains(debugConfigs, configUpper)) {
+ if (cm::contains(debugConfigs, configUpper)) {
return DEBUG_LibraryType;
}
// The current configuration is not a debug configuration.
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index 65ed34c..b9a73b0 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -6,7 +6,8 @@
#include <set>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmComputeLinkInformation.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -188,7 +189,7 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg,
cmGeneratorTarget::LinkClosure const* closure =
target.GetLinkClosure(config);
- if (cmContains(closure->Languages, "CUDA")) {
+ if (cm::contains(closure->Languages, "CUDA")) {
if (const char* separableCompilation =
target.GetProperty("CUDA_SEPARABLE_COMPILATION")) {
if (cmIsOn(separableCompilation)) {
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index 860b4da..1d82dfc 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -16,6 +16,7 @@
#include <vector>
#include <cm/memory>
+#include <cmext/algorithm>
#include "cmsys/RegularExpression.hxx"
@@ -66,7 +67,7 @@ bool GetList(std::vector<std::string>& list, const std::string& var,
// expand the variable into a list
cmExpandList(listString, list, true);
// if no empty elements then just return
- if (!cmContains(list, std::string())) {
+ if (!cm::contains(list, std::string())) {
return true;
}
// if we have empty elements we need to check policy CMP0007
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index a55e094..e07cbb0 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -20,7 +20,6 @@
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -1255,7 +1254,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
// directly. In this case adding -I/usr/include can hide SDK headers so we
// must still exclude it.
if ((lang == "C" || lang == "CXX" || lang == "CUDA") &&
- !cmContains(impDirVec, "/usr/include") &&
+ !cm::contains(impDirVec, "/usr/include") &&
std::find_if(impDirVec.begin(), impDirVec.end(),
[](std::string const& d) {
return cmHasLiteralSuffix(d, "/usr/include");
@@ -1276,13 +1275,14 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
&lang](std::string const& dir) {
return (
// Do not exclude directories that are not in an excluded set.
- ((!cmContains(implicitSet, this->GlobalGenerator->GetRealPath(dir))) &&
- (!cmContains(implicitExclude, dir)))
+ ((!cm::contains(implicitSet, this->GlobalGenerator->GetRealPath(dir))) &&
+ (!cm::contains(implicitExclude, dir)))
// Do not exclude entries of the CPATH environment variable even though
// they are implicitly searched by the compiler. They are meant to be
// user-specified directories that can be re-ordered or converted to
// -isystem without breaking real compiler builtin headers.
- || ((lang == "C" || lang == "CXX") && cmContains(this->EnvCPATH, dir)));
+ ||
+ ((lang == "C" || lang == "CXX") && cm::contains(this->EnvCPATH, dir)));
};
// Get the target-specific include directories.
@@ -1329,7 +1329,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
if (!stripImplicitDirs) {
// Append implicit directories that were requested by the user only
for (BT<std::string> const& udr : userDirs) {
- if (cmContains(implicitSet, cmSystemTools::GetRealPath(udr.Value))) {
+ if (cm::contains(implicitSet, cmSystemTools::GetRealPath(udr.Value))) {
emitBT(udr);
}
}
@@ -1945,6 +1945,8 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
this->AppendFlags(flags, "-swift-version " + std::string(v));
}
}
+ } else if (lang == "CUDA") {
+ target->AddCUDAArchitectureFlags(flags);
}
// Add MSVC runtime library flags. This is activated by the presence
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 99428bc..aa8912e 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -48,37 +48,6 @@
# include "cmDependsJava.h"
#endif
-// Escape special characters in Makefile dependency lines
-class cmMakeSafe
-{
-public:
- cmMakeSafe(const char* s)
- : Data(s)
- {
- }
- cmMakeSafe(std::string const& s)
- : Data(s.c_str())
- {
- }
-
-private:
- const char* Data;
- friend std::ostream& operator<<(std::ostream& os, cmMakeSafe const& self)
- {
- for (const char* c = self.Data; *c; ++c) {
- switch (*c) {
- case '=':
- os << "$(EQUALS)";
- break;
- default:
- os << *c;
- break;
- }
- }
- return os;
- }
-};
-
// Helper function used below.
static std::string cmSplitExtension(std::string const& in, std::string& base)
{
@@ -498,6 +467,14 @@ const std::string& cmLocalUnixMakefileGenerator3::GetHomeRelativeOutputPath()
return this->HomeRelativeOutputPath;
}
+std::string cmLocalUnixMakefileGenerator3::ConvertToMakefilePath(
+ std::string const& path) const
+{
+ cmGlobalUnixMakefileGenerator3* gg =
+ static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
+ return gg->ConvertToMakefilePath(path);
+}
+
void cmLocalUnixMakefileGenerator3::WriteMakeRule(
std::ostream& os, const char* comment, const std::string& target,
const std::vector<std::string>& depends,
@@ -528,7 +505,7 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule(
}
// Construct the left hand side of the rule.
- std::string tgt = cmSystemTools::ConvertToOutputPath(
+ std::string tgt = this->ConvertToMakefilePath(
this->MaybeConvertToRelativePath(this->GetBinaryDirectory(), target));
const char* space = "";
@@ -542,30 +519,30 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule(
if (symbolic) {
if (const char* sym =
this->Makefile->GetDefinition("CMAKE_MAKE_SYMBOLIC_RULE")) {
- os << cmMakeSafe(tgt) << space << ": " << sym << "\n";
+ os << tgt << space << ": " << sym << "\n";
}
}
// Write the rule.
if (depends.empty()) {
// No dependencies. The commands will always run.
- os << cmMakeSafe(tgt) << space << ":\n";
+ os << tgt << space << ":\n";
} else {
// Split dependencies into multiple rule lines. This allows for
// very long dependency lists even on older make implementations.
std::string binDir = this->GetBinaryDirectory();
for (std::string const& depend : depends) {
- replace = depend;
- replace = cmSystemTools::ConvertToOutputPath(
- this->MaybeConvertToRelativePath(binDir, replace));
- os << cmMakeSafe(tgt) << space << ": " << cmMakeSafe(replace) << "\n";
+ os << tgt << space << ": "
+ << this->ConvertToMakefilePath(
+ this->MaybeConvertToRelativePath(binDir, depend))
+ << '\n';
}
}
// Write the list of commands.
os << cmWrap("\t", commands, "", "\n") << "\n";
if (symbolic && !this->IsWatcomWMake()) {
- os << ".PHONY : " << cmMakeSafe(tgt) << "\n";
+ os << ".PHONY : " << tgt << "\n";
}
os << "\n";
// Add the output to the local help if requested.
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index 68eeb29..2b07952 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -46,6 +46,12 @@ public:
// local generators StartOutputDirectory
const std::string& GetHomeRelativeOutputPath();
+ /**
+ * Convert a file path to a Makefile target or dependency with
+ * escaping and quoting suitable for the generator's make tool.
+ */
+ std::string ConvertToMakefilePath(std::string const& path) const;
+
// Write out a make rule
void WriteMakeRule(std::ostream& os, const char* comment,
const std::string& target,
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 2dfdd1f..95c798b 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -3,6 +3,7 @@
#include "cmLocalVisualStudio7Generator.h"
#include <cm/memory>
+#include <cmext/algorithm>
#include <windows.h>
@@ -1522,7 +1523,7 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
// If HEADER_FILE_ONLY is set, we must suppress this generation in
// the project file
fc.ExcludedFromBuild = sf.GetPropertyAsBool("HEADER_FILE_ONLY") ||
- !cmContains(acs.Configs, ci) ||
+ !cm::contains(acs.Configs, ci) ||
(gt->GetPropertyAsBool("UNITY_BUILD") &&
sf.GetProperty("UNITY_SOURCE_FILE") &&
!sf.GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION"));
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 85e7df1..028b0f5 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -27,7 +27,6 @@
#include "cm_static_string_view.hxx"
#include "cm_sys_stat.h"
-#include "cmAlgorithms.h"
#include "cmCommandArgumentParserHelper.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
@@ -1645,7 +1644,7 @@ void cmMakefile::Configure()
allowedCommands.insert("message");
isProblem = false;
for (cmListFileFunction const& func : listFile.Functions) {
- if (!cmContains(allowedCommands, func.Name.Lower)) {
+ if (!cm::contains(allowedCommands, func.Name.Lower)) {
isProblem = true;
break;
}
@@ -4294,7 +4293,7 @@ cmTarget* cmMakefile::FindTargetToUse(const std::string& name,
bool cmMakefile::IsAlias(const std::string& name) const
{
- if (cmContains(this->AliasTargets, name)) {
+ if (cm::contains(this->AliasTargets, name)) {
return true;
}
return this->GetGlobalGenerator()->IsAlias(name);
@@ -4664,7 +4663,7 @@ bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
}
std::vector<std::string> availableFeatures = cmExpandedList(features);
- if (!cmContains(availableFeatures, feature)) {
+ if (!cm::contains(availableFeatures, feature)) {
std::ostringstream e;
e << "The compiler feature \"" << feature << "\" is not known to " << lang
<< " compiler\n\""
@@ -4961,27 +4960,27 @@ void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
if (const char* propCxx98 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "98_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx98);
- needCxx98 = cmContains(props, feature);
+ needCxx98 = cm::contains(props, feature);
}
if (const char* propCxx11 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx11);
- needCxx11 = cmContains(props, feature);
+ needCxx11 = cm::contains(props, feature);
}
if (const char* propCxx14 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "14_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx14);
- needCxx14 = cmContains(props, feature);
+ needCxx14 = cm::contains(props, feature);
}
if (const char* propCxx17 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "17_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx17);
- needCxx17 = cmContains(props, feature);
+ needCxx17 = cm::contains(props, feature);
}
if (const char* propCxx20 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "20_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx20);
- needCxx20 = cmContains(props, feature);
+ needCxx20 = cm::contains(props, feature);
}
}
@@ -5120,27 +5119,27 @@ void cmMakefile::CheckNeededCudaLanguage(const std::string& feature,
if (const char* propCuda03 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "03_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCuda03);
- needCuda03 = cmContains(props, feature);
+ needCuda03 = cm::contains(props, feature);
}
if (const char* propCuda11 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCuda11);
- needCuda11 = cmContains(props, feature);
+ needCuda11 = cm::contains(props, feature);
}
if (const char* propCuda14 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "14_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCuda14);
- needCuda14 = cmContains(props, feature);
+ needCuda14 = cm::contains(props, feature);
}
if (const char* propCuda17 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "17_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCuda17);
- needCuda17 = cmContains(props, feature);
+ needCuda17 = cm::contains(props, feature);
}
if (const char* propCuda20 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "20_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCuda20);
- needCuda20 = cmContains(props, feature);
+ needCuda20 = cm::contains(props, feature);
}
}
@@ -5214,17 +5213,17 @@ void cmMakefile::CheckNeededCLanguage(const std::string& feature,
if (const char* propC90 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "90_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propC90);
- needC90 = cmContains(props, feature);
+ needC90 = cm::contains(props, feature);
}
if (const char* propC99 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "99_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propC99);
- needC99 = cmContains(props, feature);
+ needC99 = cm::contains(props, feature);
}
if (const char* propC11 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propC11);
- needC11 = cmContains(props, feature);
+ needC11 = cm::contains(props, feature);
}
}
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 2d8f8d6..ee87044 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -341,12 +341,16 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
<< "\n";
}
+ bool const escapeOctothorpe = this->GlobalGenerator->CanEscapeOctothorpe();
+
for (std::string const& language : languages) {
std::string defines = this->GetDefines(language, this->GetConfigName());
std::string includes = this->GetIncludes(language, this->GetConfigName());
- // Escape comment characters so they do not terminate assignment.
- cmSystemTools::ReplaceString(defines, "#", "\\#");
- cmSystemTools::ReplaceString(includes, "#", "\\#");
+ if (escapeOctothorpe) {
+ // Escape comment characters so they do not terminate assignment.
+ cmSystemTools::ReplaceString(defines, "#", "\\#");
+ cmSystemTools::ReplaceString(includes, "#", "\\#");
+ }
*this->FlagFileStream << language << "_DEFINES = " << defines << "\n\n";
*this->FlagFileStream << language << "_INCLUDES = " << includes << "\n\n";
@@ -357,7 +361,9 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
for (const std::string& arch : architectures) {
std::string flags =
this->GetFlags(language, this->GetConfigName(), arch);
- cmSystemTools::ReplaceString(flags, "#", "\\#");
+ if (escapeOctothorpe) {
+ cmSystemTools::ReplaceString(flags, "#", "\\#");
+ }
*this->FlagFileStream << language << "_FLAGS" << arch << " = " << flags
<< "\n\n";
}
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index 1c6fad1..68bf3af 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -26,7 +26,7 @@ std::string cmOutputConverter::ConvertToOutputForExisting(
// already exists, we can use a short-path to reference it without a
// space.
if (this->GetState()->UseWindowsShell() &&
- remote.find(' ') != std::string::npos &&
+ remote.find_first_of(" #") != std::string::npos &&
cmSystemTools::FileExists(remote)) {
std::string tmp;
if (cmSystemTools::GetShortPath(remote, tmp)) {
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index d3daad8..0eb42bf 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -308,6 +308,10 @@ class cmMakefile;
3, 17, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0103, \
"multiple export() with same FILE without APPEND is not allowed.", \
+ 3, 18, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0104, \
+ "CMAKE_CUDA_ARCHITECTURES now detected for NVCC, empty " \
+ "CUDA_ARCHITECTURES not allowed.", \
3, 18, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
@@ -338,7 +342,8 @@ class cmMakefile;
F(CMP0081) \
F(CMP0083) \
F(CMP0095) \
- F(CMP0099)
+ F(CMP0099) \
+ F(CMP0104)
/** \class cmPolicies
* \brief Handles changes in CMake behavior and policies
diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx
index d5891c4..57fcd2d 100644
--- a/Source/cmQtAutoGen.cxx
+++ b/Source/cmQtAutoGen.cxx
@@ -13,7 +13,6 @@
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmDuration.h"
#include "cmProcessOutput.h"
#include "cmStringAlgorithms.h"
@@ -55,7 +54,7 @@ void MergeOptions(std::vector<std::string>& baseOpts,
}
}
// Test if this is a value option and change the existing value
- if (!optName.empty() && cmContains(valueOpts, optName)) {
+ if (!optName.empty() && cm::contains(valueOpts, optName)) {
const auto existItNext(existIt + 1);
const auto fitNext(fit + 1);
if ((existItNext != baseOpts.end()) && (fitNext != fitEnd)) {
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 87f4656..b0a7c30 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -16,13 +16,13 @@
#include <cm/algorithm>
#include <cm/iterator>
#include <cm/memory>
+#include <cmext/algorithm>
#include "cmsys/SystemInformation.hxx"
#include "cm_jsoncpp_value.h"
#include "cm_jsoncpp_writer.h"
-#include "cmAlgorithms.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmGeneratedFileStream.h"
@@ -850,7 +850,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
this->Makefile->GetSource(fullPath, locationKind);
if (sf != nullptr) {
// Check if we know about this header already
- if (cmContains(this->AutogenTarget.Headers, sf)) {
+ if (cm::contains(this->AutogenTarget.Headers, sf)) {
continue;
}
// We only accept not-GENERATED files that do exist.
@@ -898,14 +898,14 @@ bool cmQtAutoGenInitializer::InitScanFiles()
cmSystemTools::LowerCase(sf->GetExtension());
if (cm->IsHeaderExtension(extLower)) {
- if (!cmContains(this->AutogenTarget.Headers, sf.get())) {
+ if (!cm::contains(this->AutogenTarget.Headers, sf.get())) {
auto muf = makeMUFile(sf.get(), fullPath, false);
if (muf->SkipMoc || muf->SkipUic) {
addMUHeader(std::move(muf), extLower);
}
}
} else if (cm->IsSourceExtension(extLower)) {
- if (!cmContains(this->AutogenTarget.Sources, sf.get())) {
+ if (!cm::contains(this->AutogenTarget.Sources, sf.get())) {
auto muf = makeMUFile(sf.get(), fullPath, false);
if (muf->SkipMoc || muf->SkipUic) {
addMUSource(std::move(muf));
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index c5f3463..10e6317 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -10,10 +10,10 @@
#include <vector>
#include <cm/memory>
+#include <cmext/algorithm>
#include "cm_uv.h"
-#include "cmAlgorithms.h"
#include "cmExternalMakefileProjectGenerator.h"
#include "cmFileMonitor.h"
#include "cmGlobalGenerator.h"
@@ -433,7 +433,7 @@ cmServerResponse cmServerProtocol1::ProcessCache(
keys = allKeys;
} else {
for (auto const& i : keys) {
- if (!cmContains(allKeys, i)) {
+ if (!cm::contains(allKeys, i)) {
return request.ReportError("Key \"" + i + "\" not found in cache.");
}
}
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index 8350410..bb75a14 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -7,7 +7,8 @@
#include <set>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmSourceGroup.h"
@@ -136,7 +137,7 @@ ExpectedOptions getExpectedOptions()
bool isExpectedOption(const std::string& argument,
const ExpectedOptions& expectedOptions)
{
- return cmContains(expectedOptions, argument);
+ return cm::contains(expectedOptions, argument);
}
void parseArguments(const std::vector<std::string>& args,
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 0c4311d..955a5cc 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -363,6 +363,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("CUDA_SEPARABLE_COMPILATION");
initProp("CUDA_RESOLVE_DEVICE_SYMBOLS");
initProp("CUDA_RUNTIME_LIBRARY");
+ initProp("CUDA_ARCHITECTURES");
initProp("LINK_SEARCH_START_STATIC");
initProp("LINK_SEARCH_END_STATIC");
initProp("Swift_LANGUAGE_VERSION");
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 6cd8edd..e01e090 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -8,10 +8,10 @@
#include <cm/memory>
#include <cm/string_view>
#include <cm/vector>
+#include <cmext/algorithm>
#include "windows.h"
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -2718,7 +2718,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
std::string langForClCompile;
if (this->ProjectType == csproj) {
langForClCompile = "CSharp";
- } else if (cmContains(clLangs, linkLanguage)) {
+ } else if (cm::contains(clLangs, linkLanguage)) {
langForClCompile = linkLanguage;
} else {
std::set<std::string> languages;
@@ -3651,7 +3651,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
std::vector<std::string> libVec;
std::vector<std::string> vsTargetVec;
this->AddLibraries(cli, libVec, vsTargetVec, config);
- if (cmContains(linkClosure->Languages, "CUDA") &&
+ if (cm::contains(linkClosure->Languages, "CUDA") &&
this->CudaOptions[config] != nullptr) {
this->CudaOptions[config]->FixCudaRuntime(this->GeneratorTarget);
}
@@ -3925,7 +3925,7 @@ void cmVisualStudio10TargetGenerator::AddTargetsFileAndConfigPair(
{
for (TargetsFileAndConfigs& i : this->TargetsFileAndConfigsVec) {
if (cmSystemTools::ComparePath(targetsFile, i.File)) {
- if (!cmContains(i.Configs, config)) {
+ if (!cm::contains(i.Configs, config)) {
i.Configs.push_back(config);
}
return;
diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h
index d9be3d2..24ecaa2 100644
--- a/Source/cmXCodeObject.h
+++ b/Source/cmXCodeObject.h
@@ -12,7 +12,7 @@
#include <utility>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
class cmGeneratorTarget;
@@ -82,10 +82,13 @@ public:
void SetObject(cmXCodeObject* value) { this->Object = value; }
cmXCodeObject* GetObject() { return this->Object; }
void AddObject(cmXCodeObject* value) { this->List.push_back(value); }
- bool HasObject(cmXCodeObject* o) const { return cmContains(this->List, o); }
+ bool HasObject(cmXCodeObject* o) const
+ {
+ return cm::contains(this->List, o);
+ }
void AddUniqueObject(cmXCodeObject* value)
{
- if (!cmContains(this->List, value)) {
+ if (!cm::contains(this->List, value)) {
this->List.push_back(value);
}
}
diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx
index b34c2f6..1b437e9 100644
--- a/Source/cmXCodeScheme.cxx
+++ b/Source/cmXCodeScheme.cxx
@@ -7,6 +7,8 @@
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -427,7 +429,7 @@ std::string cmXCodeScheme::FindConfiguration(const std::string& name)
// Try to find the desired configuration by name,
// and if it's not found return first from the list
//
- if (!cmContains(this->ConfigList, name) && !this->ConfigList.empty()) {
+ if (!cm::contains(this->ConfigList, name) && !this->ConfigList.empty()) {
return this->ConfigList[0];
}
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index ea1d8ca..c619e1e 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -27,7 +27,6 @@
#include "cm_static_string_view.hxx"
#include "cm_sys_stat.h"
-#include "cmAlgorithms.h"
#include "cmCommands.h"
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h"
@@ -2863,7 +2862,7 @@ void cmake::WatchUnusedCli(const std::string& var)
{
#ifndef CMAKE_BOOTSTRAP
this->VariableWatch->AddWatch(var, cmWarnUnusedCliWarning, this);
- if (!cmContains(this->UsedCliVariables, var)) {
+ if (!cm::contains(this->UsedCliVariables, var)) {
this->UsedCliVariables[var] = false;
}
#endif
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 49d04a6..a663087 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -8,7 +8,6 @@
#include "cm_uv.h"
-#include "cmAlgorithms.h"
#include "cmDuration.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
@@ -90,6 +89,7 @@ void CMakeCommandUsage(const char* program)
<< "Available commands: \n"
<< " capabilities - Report capabilities built into cmake "
"in JSON format\n"
+ << " cat <files>... - concat the files and print them to the standard output\n"
<< " chdir dir cmd [args...] - run command in a given directory\n"
<< " compare_files [--ignore-eol] file1 file2\n"
<< " - check if file1 is same as file2\n"
@@ -180,6 +180,13 @@ static bool cmTarFilesFrom(std::string const& file,
return true;
}
+static void cmCatFile(const std::string& fileToAppend)
+{
+ cmsys::ifstream source(fileToAppend.c_str(),
+ (std::ios::binary | std::ios::in));
+ std::cout << source.rdbuf();
+}
+
static bool cmRemoveDirectory(const std::string& dir, bool recursive = true)
{
if (cmSystemTools::FileIsSymlink(dir)) {
@@ -927,6 +934,33 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return HashSumFile(args, cmCryptoHash::AlgoSHA512);
}
+ // Command to concat files into one
+ if (args[1] == "cat" && args.size() >= 3) {
+ int return_value = 0;
+ for (auto const& arg : cmMakeRange(args).advance(2)) {
+ if (cmHasLiteralPrefix(arg, "-")) {
+ if (arg != "--") {
+ cmSystemTools::Error(arg + ": option not handled");
+ return_value = 1;
+ }
+ } else if (!cmSystemTools::TestFileAccess(arg,
+ cmsys::TEST_FILE_READ) &&
+ cmSystemTools::TestFileAccess(arg, cmsys::TEST_FILE_OK)) {
+ cmSystemTools::Error(arg + ": permission denied (ignoring)");
+ return_value = 1;
+ } else if (cmSystemTools::FileIsDirectory(arg)) {
+ cmSystemTools::Error(arg + ": is a directory (ignoring)");
+ return_value = 1;
+ } else if (!cmSystemTools::FileExists(arg)) {
+ cmSystemTools::Error(arg + ": no such file or directory (ignoring)");
+ return_value = 1;
+ } else {
+ cmCatFile(arg);
+ }
+ }
+ return return_value;
+ }
+
// Command to change directory and run a program.
if (args[1] == "chdir" && args.size() >= 4) {
std::string const& directory = args[2];
@@ -1185,7 +1219,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
}
} else if (cmHasLiteralPrefix(arg, "--format=")) {
format = arg.substr(9);
- if (!cmContains(knownFormats, format)) {
+ if (!cm::contains(knownFormats, format)) {
cmSystemTools::Error("Unknown -E tar --format= argument: " +
format);
return 1;
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 6428235..cc2931b 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -3477,6 +3477,8 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
--build-two-config
${build_generator_args}
--build-project IncludeDirectories
+ --build-options
+ -DMAKE_SUPPORTS_SPACES=${MAKE_SUPPORTS_SPACES}
--test-command IncludeDirectories)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/IncludeDirectories")
diff --git a/Tests/Cuda/CXXStandardSetTwice/CMakeLists.txt b/Tests/Cuda/CXXStandardSetTwice/CMakeLists.txt
index 1941c49..f4ad83a 100644
--- a/Tests/Cuda/CXXStandardSetTwice/CMakeLists.txt
+++ b/Tests/Cuda/CXXStandardSetTwice/CMakeLists.txt
@@ -1,9 +1,8 @@
cmake_minimum_required(VERSION 3.7)
project(CXXStandardSetTwice CXX CUDA)
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
-
set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30)
add_executable(CXXStandardSetTwice main.cu)
target_compile_features(CXXStandardSetTwice PUBLIC cxx_std_11)
diff --git a/Tests/Cuda/Complex/CMakeLists.txt b/Tests/Cuda/Complex/CMakeLists.txt
index 08d1e16..265bd85 100644
--- a/Tests/Cuda/Complex/CMakeLists.txt
+++ b/Tests/Cuda/Complex/CMakeLists.txt
@@ -15,7 +15,7 @@ project (Complex CXX CUDA)
#and also building cpp targets that need cuda implicit libraries
#verify that we can pass explicit cuda arch flags
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
+set(CMAKE_CUDA_ARCHITECTURES 30)
set(CMAKE_CUDA_STANDARD 11)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CUDA_STANDARD_REQUIRED TRUE)
diff --git a/Tests/Cuda/MixedStandardLevels1/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels1/CMakeLists.txt
index b03e51e..e40ffa6 100644
--- a/Tests/Cuda/MixedStandardLevels1/CMakeLists.txt
+++ b/Tests/Cuda/MixedStandardLevels1/CMakeLists.txt
@@ -1,10 +1,9 @@
cmake_minimum_required(VERSION 3.7)
project(MixedStandardLevels1 CXX CUDA)
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
-
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30)
add_executable(MixedStandardLevels1 main.cu lib.cpp)
diff --git a/Tests/Cuda/MixedStandardLevels2/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels2/CMakeLists.txt
index 12dd328..7af8081 100644
--- a/Tests/Cuda/MixedStandardLevels2/CMakeLists.txt
+++ b/Tests/Cuda/MixedStandardLevels2/CMakeLists.txt
@@ -1,9 +1,8 @@
cmake_minimum_required(VERSION 3.7)
project(MixedStandardLevels2 CXX CUDA)
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
-
set(CMAKE_CXX_STANDARD 17) #this can decay
+set(CMAKE_CUDA_ARCHITECTURES 30)
add_executable(MixedStandardLevels2 main.cu lib.cpp)
target_compile_features(MixedStandardLevels2 PUBLIC cuda_std_11)
diff --git a/Tests/Cuda/MixedStandardLevels3/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels3/CMakeLists.txt
index 2b611be..2c42003 100644
--- a/Tests/Cuda/MixedStandardLevels3/CMakeLists.txt
+++ b/Tests/Cuda/MixedStandardLevels3/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.7)
project(MixedStandardLevels3 CXX CUDA)
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
+set(CMAKE_CUDA_ARCHITECTURES 30)
add_executable(MixedStandardLevels3 main.cu lib.cpp)
target_compile_features(MixedStandardLevels3 PUBLIC cuda_std_03 cxx_std_14)
diff --git a/Tests/Cuda/MixedStandardLevels4/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels4/CMakeLists.txt
index faf6869..230230d 100644
--- a/Tests/Cuda/MixedStandardLevels4/CMakeLists.txt
+++ b/Tests/Cuda/MixedStandardLevels4/CMakeLists.txt
@@ -1,9 +1,8 @@
cmake_minimum_required(VERSION 3.7)
project(MixedStandardLevels4 CXX CUDA)
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
-
set(CMAKE_CUDA_STANDARD 03)
+set(CMAKE_CUDA_ARCHITECTURES 30)
add_executable(MixedStandardLevels4 main.cu lib.cpp)
target_compile_features(MixedStandardLevels4 PUBLIC cxx_std_14)
diff --git a/Tests/Cuda/MixedStandardLevels5/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels5/CMakeLists.txt
index 7209f60..5f5ee06 100644
--- a/Tests/Cuda/MixedStandardLevels5/CMakeLists.txt
+++ b/Tests/Cuda/MixedStandardLevels5/CMakeLists.txt
@@ -1,9 +1,8 @@
cmake_minimum_required(VERSION 3.7)
project(MixedStandardLevels5 CXX CUDA)
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
-
set(CMAKE_CXX_STANDARD 98)
+set(CMAKE_CUDA_ARCHITECTURES 30)
add_executable(MixedStandardLevels5 main.cu lib.cpp)
diff --git a/Tests/Cuda/ProperDeviceLibraries/CMakeLists.txt b/Tests/Cuda/ProperDeviceLibraries/CMakeLists.txt
index cb47b09..fe28c3e 100644
--- a/Tests/Cuda/ProperDeviceLibraries/CMakeLists.txt
+++ b/Tests/Cuda/ProperDeviceLibraries/CMakeLists.txt
@@ -1,8 +1,8 @@
cmake_minimum_required(VERSION 3.13)
project(ProperDeviceLibraries CXX CUDA)
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_35,code=compute_35 -gencode arch=compute_35,code=sm_35")
set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 35)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)
diff --git a/Tests/Cuda/WithC/CMakeLists.txt b/Tests/Cuda/WithC/CMakeLists.txt
index 69aa3f9..049cbce 100644
--- a/Tests/Cuda/WithC/CMakeLists.txt
+++ b/Tests/Cuda/WithC/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.7)
project(WithC CUDA C)
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
+set(CMAKE_CUDA_ARCHITECTURES 30)
add_executable(CudaWithC main.c cuda.cu)
diff --git a/Tests/CudaOnly/Architecture/CMakeLists.txt b/Tests/CudaOnly/Architecture/CMakeLists.txt
new file mode 100644
index 0000000..7270b56
--- /dev/null
+++ b/Tests/CudaOnly/Architecture/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.17)
+project(Architecture CUDA)
+
+set(CMAKE_CUDA_ARCHITECTURES 52)
+add_executable(Architecture main.cu)
diff --git a/Tests/CudaOnly/Architecture/main.cu b/Tests/CudaOnly/Architecture/main.cu
new file mode 100644
index 0000000..8c817d5
--- /dev/null
+++ b/Tests/CudaOnly/Architecture/main.cu
@@ -0,0 +1,9 @@
+#ifdef __CUDA_ARCH__
+# if __CUDA_ARCH__ != 520
+# error "Passed architecture 52, but got something else."
+# endif
+#endif
+
+int main()
+{
+}
diff --git a/Tests/CudaOnly/CMakeLists.txt b/Tests/CudaOnly/CMakeLists.txt
index cc1ee1a..d74e810 100644
--- a/Tests/CudaOnly/CMakeLists.txt
+++ b/Tests/CudaOnly/CMakeLists.txt
@@ -1,5 +1,7 @@
+ADD_TEST_MACRO(CudaOnly.Architecture Architecture)
ADD_TEST_MACRO(CudaOnly.CircularLinkLine CudaOnlyCircularLinkLine)
+ADD_TEST_MACRO(CudaOnly.CompileFlags CudaOnlyCompileFlags)
ADD_TEST_MACRO(CudaOnly.EnableStandard CudaOnlyEnableStandard)
ADD_TEST_MACRO(CudaOnly.ExportPTX CudaOnlyExportPTX)
ADD_TEST_MACRO(CudaOnly.GPUDebugFlag CudaOnlyGPUDebugFlag)
diff --git a/Tests/CudaOnly/CircularLinkLine/CMakeLists.txt b/Tests/CudaOnly/CircularLinkLine/CMakeLists.txt
index 5e6f7ab..e10a348 100644
--- a/Tests/CudaOnly/CircularLinkLine/CMakeLists.txt
+++ b/Tests/CudaOnly/CircularLinkLine/CMakeLists.txt
@@ -5,9 +5,9 @@ project (CircularLinkLine CUDA)
# Verify that we de-duplicate the device link line
# Verify that a de-duplicated link line still works with circular static libraries
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[compute_30]")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30)
add_library(CUDACircularDeviceLinking1 STATIC file1.cu)
add_library(CUDACircularDeviceLinking2 STATIC file2.cu)
diff --git a/Tests/CudaOnly/CompileFlags/CMakeLists.txt b/Tests/CudaOnly/CompileFlags/CMakeLists.txt
new file mode 100644
index 0000000..cbce7d6
--- /dev/null
+++ b/Tests/CudaOnly/CompileFlags/CMakeLists.txt
@@ -0,0 +1,16 @@
+cmake_minimum_required(VERSION 3.17)
+cmake_policy(SET CMP0104 OLD)
+project(CompileFlags CUDA)
+
+# Clear defaults.
+set(CMAKE_CUDA_ARCHITECTURES)
+
+add_executable(CudaOnlyCompileFlags main.cu)
+
+# Try passing CUDA architecture flags explicitly.
+if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
+ target_compile_options(CudaOnlyCompileFlags PRIVATE
+ -gencode arch=compute_50,code=compute_50
+ --compiler-options=-DHOST_DEFINE
+ )
+endif()
diff --git a/Tests/CudaOnly/CompileFlags/main.cu b/Tests/CudaOnly/CompileFlags/main.cu
new file mode 100644
index 0000000..573d230
--- /dev/null
+++ b/Tests/CudaOnly/CompileFlags/main.cu
@@ -0,0 +1,16 @@
+#ifdef __CUDA_ARCH__
+# if __CUDA_ARCH__ != 500
+# error "Passed architecture 50, but got something else."
+# endif
+#endif
+
+// Check HOST_DEFINE only for nvcc
+#ifndef __CUDA__
+# ifndef HOST_DEFINE
+# error "HOST_DEFINE not defined!"
+# endif
+#endif
+
+int main()
+{
+}
diff --git a/Tests/CudaOnly/DontResolveDeviceSymbols/CMakeLists.txt b/Tests/CudaOnly/DontResolveDeviceSymbols/CMakeLists.txt
index 6e3697f..1265660 100644
--- a/Tests/CudaOnly/DontResolveDeviceSymbols/CMakeLists.txt
+++ b/Tests/CudaOnly/DontResolveDeviceSymbols/CMakeLists.txt
@@ -24,9 +24,9 @@ endif()
# Don't resolve the device symbols in the static library
# Don't resolve the device symbols in the executable library
# Verify that we can't use those device symbols from anything
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[compute_30] -gencode arch=compute_50,code=\\\"compute_50\\\"")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30 50)
set(CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS OFF)
add_library(CUDANoDeviceResolve SHARED file1.cu)
diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt
index 57aa0b9..bd94ec8 100644
--- a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt
+++ b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt
@@ -21,7 +21,7 @@ endif()
# confirming that the first static library is on the device link line
# 3. Verify that we can't use those device symbols from anything that links
# to the static library
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[sm_30] -gencode arch=compute_50,code=\\\"compute_50\\\"")
+set(CMAKE_CUDA_ARCHITECTURES 30 50)
add_library(CUDAResolveDeviceDepsA STATIC file1.cu)
add_library(CUDAResolveDeviceDepsB STATIC file2.cu)
diff --git a/Tests/CudaOnly/RuntimeControls/CMakeLists.txt b/Tests/CudaOnly/RuntimeControls/CMakeLists.txt
index 8b58fec..0da5739 100644
--- a/Tests/CudaOnly/RuntimeControls/CMakeLists.txt
+++ b/Tests/CudaOnly/RuntimeControls/CMakeLists.txt
@@ -15,9 +15,8 @@ else()
endif()
endif()
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[compute_30]")
-
set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30)
set(CMAKE_CUDA_RUNTIME_LIBRARY static)
if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
diff --git a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt
index c1bd64a..586be81 100644
--- a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt
+++ b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt
@@ -9,9 +9,7 @@ project (SeparateCompilation CUDA)
#and executables.
#We complicate the matter by also testing that multiple static libraries
#all containing cuda separable compilation code links properly
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=\\\"compute_30,sm_30,sm_35\\\"")
-string(APPEND CMAKE_CUDA_FLAGS " --generate-code=arch=compute_50,code=[compute_50,sm_50,sm_52]")
-
+set(CMAKE_CUDA_ARCHITECTURES 30 35 50 52)
set(CMAKE_CUDA_SEPARABLE_COMPILATION ON)
add_library(CUDASeparateLibA STATIC file1.cu file2.cu file3.cu)
target_compile_features(CUDASeparateLibA PRIVATE cuda_std_11)
diff --git a/Tests/CudaOnly/Standard98/CMakeLists.txt b/Tests/CudaOnly/Standard98/CMakeLists.txt
index ef9a685..3ba0360 100644
--- a/Tests/CudaOnly/Standard98/CMakeLists.txt
+++ b/Tests/CudaOnly/Standard98/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.7)
project(CudaOnlyStandard98 CUDA)
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
+set(CMAKE_CUDA_ARCHITECTURES 30)
# Support setting CUDA Standard to 98 which internally gets transformed to
# CUDA03
diff --git a/Tests/CudaOnly/WithDefs/CMakeLists.txt b/Tests/CudaOnly/WithDefs/CMakeLists.txt
index ba9bf04..add8131 100644
--- a/Tests/CudaOnly/WithDefs/CMakeLists.txt
+++ b/Tests/CudaOnly/WithDefs/CMakeLists.txt
@@ -3,17 +3,7 @@ cmake_minimum_required(VERSION 3.7)
project (WithDefs CUDA)
#verify that we can pass explicit cuda arch flags
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
-if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 9)
- set(debug_compile_flags --generate-code arch=compute_32,code=sm_32)
-else()
- set(debug_compile_flags --generate-code arch=compute_20,code=sm_20)
-endif()
-if(CMAKE_CUDA_SIMULATE_ID STREQUAL "MSVC")
- list(APPEND debug_compile_flags -Xcompiler=-WX)
-else()
- list(APPEND debug_compile_flags -Xcompiler=-Werror)
-endif()
+set(CMAKE_CUDA_ARCHITECTURES 30)
set(release_compile_defs DEFREL)
#Goal for this example:
@@ -29,7 +19,6 @@ target_compile_options(CudaOnlyWithDefs
-DFLAG_COMPILE_LANG_$<COMPILE_LANGUAGE>
-DFLAG_LANG_IS_CUDA=$<COMPILE_LANGUAGE:CUDA>
--compiler-options=-DHOST_DEFINE
- $<$<CONFIG:DEBUG>:$<BUILD_INTERFACE:${debug_compile_flags}>>
)
target_compile_definitions(CudaOnlyWithDefs
diff --git a/Tests/FindPython/CMakeLists.txt b/Tests/FindPython/CMakeLists.txt
index d2326e4..8ed59d1 100644
--- a/Tests/FindPython/CMakeLists.txt
+++ b/Tests/FindPython/CMakeLists.txt
@@ -20,6 +20,17 @@ if(CMake_TEST_FindPython)
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+ add_test(NAME FindPython.Python2.Development.Module COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python2Module"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python2Module"
+ ${build_generator_args}
+ --build-project TestPython2Module
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
add_test(NAME FindPython.Python2Fail COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -54,6 +65,17 @@ if(CMake_TEST_FindPython)
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+ add_test(NAME FindPython.Python3.Development.Module COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python3Module"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python3Module"
+ ${build_generator_args}
+ --build-project TestPython3Module
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
add_test(NAME FindPython.Python3Fail COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -276,7 +298,6 @@ if(CMake_TEST_FindPython_NumPy)
${build_generator_args}
--build-project TestNumPyOnly
--build-options ${build_options}
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
endif()
diff --git a/Tests/FindPython/Python/CMakeLists.txt b/Tests/FindPython/Python/CMakeLists.txt
index 3ee38e3..e8828a2 100644
--- a/Tests/FindPython/Python/CMakeLists.txt
+++ b/Tests/FindPython/Python/CMakeLists.txt
@@ -8,6 +8,12 @@ find_package(Python ${Python_REQUESTED_VERSION} REQUIRED COMPONENTS Interpreter
if (NOT Python_FOUND)
message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION}")
endif()
+if (NOT Python_Development.Module_FOUND)
+ message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION}, COMPONENT 'Development.Module'")
+endif()
+if (NOT Python_Development.Embed_FOUND)
+ message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION}, COMPOENENT 'Development.Embed'")
+endif()
if(NOT TARGET Python::Interpreter)
message(SEND_ERROR "Python::Interpreter not found")
diff --git a/Tests/FindPython/Python2/CMakeLists.txt b/Tests/FindPython/Python2/CMakeLists.txt
index cf77ca2..609d80f 100644
--- a/Tests/FindPython/Python2/CMakeLists.txt
+++ b/Tests/FindPython/Python2/CMakeLists.txt
@@ -13,6 +13,15 @@ find_package(Python2 REQUIRED COMPONENTS Interpreter Development)
if (NOT Python2_FOUND)
message (FATAL_ERROR "Fail to found Python 2")
endif()
+if (NOT Python2_Development_FOUND)
+ message (FATAL_ERROR "Fail to found Python 2 'Development' component")
+endif()
+if (NOT Python2_Development.Module_FOUND)
+ message (FATAL_ERROR "Fail to found Python 2 'Development.Module' component")
+endif()
+if (NOT Python2_Development.Embed_FOUND)
+ message (FATAL_ERROR "Fail to found Python 2 'Development.Embed' component")
+endif()
if(NOT TARGET Python2::Interpreter)
message(SEND_ERROR "Python2::Interpreter not found")
diff --git a/Tests/FindPython/Python2Embedded/CMakeLists.txt b/Tests/FindPython/Python2Embedded/CMakeLists.txt
index 0115dea..1cf6034 100644
--- a/Tests/FindPython/Python2Embedded/CMakeLists.txt
+++ b/Tests/FindPython/Python2Embedded/CMakeLists.txt
@@ -4,10 +4,23 @@ project(TestPython2Embedded C)
include(CTest)
-find_package(Python2 REQUIRED COMPONENTS Development)
+find_package(Python2 REQUIRED COMPONENTS Development.Embed)
if (NOT Python2_FOUND)
message (FATAL_ERROR "Fail to found Python 2")
endif()
+if (Python2_Development_FOUND)
+ message (FATAL_ERROR "Python 2, COMPONENT 'Development' unexpectedly found")
+endif()
+if (Python2_Development.Module_FOUND)
+ message (FATAL_ERROR "Python 2, COMPONENT 'Development.Module' unexpectedly found")
+endif()
+if (NOT Python2_Development.Embed_FOUND)
+ message (FATAL_ERROR "Python 2, COMPONENT 'Development.Embed' not found")
+endif()
+
+if(TARGET Python2::Module)
+ message(SEND_ERROR "Python2::Module unexpectedly found")
+endif()
if(NOT TARGET Python2::Python)
message(SEND_ERROR "Python2::Python not found")
diff --git a/Tests/FindPython/Python2Module/CMakeLists.txt b/Tests/FindPython/Python2Module/CMakeLists.txt
new file mode 100644
index 0000000..0bc3390
--- /dev/null
+++ b/Tests/FindPython/Python2Module/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPython2Module C)
+
+include(CTest)
+
+find_package(Python2 REQUIRED COMPONENTS Interpreter Development.Module)
+if (NOT Python2_FOUND)
+ message (FATAL_ERROR "Fail to found Python 2")
+endif()
+if (Python2_Development_FOUND)
+ message (FATAL_ERROR "Python 2, COMPONENT 'Development' unexpectedly found")
+endif()
+if (Python2_Development.Embed_FOUND)
+ message (FATAL_ERROR "Python 2, COMPONENT 'Development.Embed' unexpectedly found")
+endif()
+if (NOT Python2_Development.Module_FOUND)
+ message (FATAL_ERROR "Python 2, COMPONENT 'Development.Module' not found")
+endif()
+
+if(NOT TARGET Python2::Interpreter)
+ message(SEND_ERROR "Python2::Interpreter not found")
+endif()
+
+if(TARGET Python2::Python)
+ message(SEND_ERROR "Python2::Python unexpectedly found")
+endif()
+if(NOT TARGET Python2::Module)
+ message(SEND_ERROR "Python2::Module not found")
+endif()
+
+Python2_add_library (spam2 MODULE ../spam.c)
+target_compile_definitions (spam2 PRIVATE PYTHON2)
+
+add_test (NAME python2_spam2
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:spam2>"
+ "${Python2_EXECUTABLE}" -c "import spam2; spam2.system(\"cd\")")
diff --git a/Tests/FindPython/Python3/CMakeLists.txt b/Tests/FindPython/Python3/CMakeLists.txt
index 34ebd2c..d6e5fdb 100644
--- a/Tests/FindPython/Python3/CMakeLists.txt
+++ b/Tests/FindPython/Python3/CMakeLists.txt
@@ -13,6 +13,15 @@ find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
if (NOT Python3_FOUND)
message (FATAL_ERROR "Fail to found Python 3")
endif()
+if (NOT Python3_Development_FOUND)
+ message (FATAL_ERROR "Fail to found Python 3 'Development' component")
+endif()
+if (NOT Python3_Development.Module_FOUND)
+ message (FATAL_ERROR "Fail to found Python 3 'Development.Module' component")
+endif()
+if (NOT Python3_Development.Embed_FOUND)
+ message (FATAL_ERROR "Fail to found Python 3 'Development.Embed' component")
+endif()
if(NOT TARGET Python3::Interpreter)
message(SEND_ERROR "Python3::Interpreter not found")
diff --git a/Tests/FindPython/Python3Embedded/CMakeLists.txt b/Tests/FindPython/Python3Embedded/CMakeLists.txt
index 4eb7ebc..184c0b4 100644
--- a/Tests/FindPython/Python3Embedded/CMakeLists.txt
+++ b/Tests/FindPython/Python3Embedded/CMakeLists.txt
@@ -4,10 +4,23 @@ project(TestPython3Embedded C)
include(CTest)
-find_package(Python3 REQUIRED COMPONENTS Development)
+find_package(Python3 REQUIRED COMPONENTS Development.Embed)
if (NOT Python3_FOUND)
message (FATAL_ERROR "Fail to found Python 3")
endif()
+if (Python3_Development_FOUND)
+ message (FATAL_ERROR "Python 3, COMPONENT 'Development' unexpectedly found")
+endif()
+if (Python3_Development.Module_FOUND)
+ message (FATAL_ERROR "Python 3, COMPONENT 'Development.Module' unexpectedly found")
+endif()
+if (NOT Python3_Development.Embed_FOUND)
+ message (FATAL_ERROR "Python 3, COMPONENT 'Development.Embed' not found")
+endif()
+
+if(TARGET Python3::Module)
+ message(SEND_ERROR "Python3::Module unexpectedly found")
+endif()
if(NOT TARGET Python3::Python)
message(SEND_ERROR "Python3::Python not found")
diff --git a/Tests/FindPython/Python3Module/CMakeLists.txt b/Tests/FindPython/Python3Module/CMakeLists.txt
new file mode 100644
index 0000000..676f4c8
--- /dev/null
+++ b/Tests/FindPython/Python3Module/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPython3Module C)
+
+include(CTest)
+
+find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module)
+if (NOT Python3_FOUND)
+ message (FATAL_ERROR "Fail to found Python 3")
+endif()
+if (Python3_Development_FOUND)
+ message (FATAL_ERROR "Python 3, COMPONENT 'Development' unexpectedly found")
+endif()
+if (Python3_Development.Embed_FOUND)
+ message (FATAL_ERROR "Python 3, COMPONENT 'Development.Embed' unexpectedly found")
+endif()
+if (NOT Python3_Development.Module_FOUND)
+ message (FATAL_ERROR "Python 3, COMPONENT 'Development.Module' not found")
+endif()
+
+if(NOT TARGET Python3::Interpreter)
+ message(SEND_ERROR "Python3::Interpreter not found")
+endif()
+
+if(TARGET Python3::Python)
+ message(SEND_ERROR "Python3::Python unexpectedly found")
+endif()
+if(NOT TARGET Python3::Module)
+ message(SEND_ERROR "Python3::Module not found")
+endif()
+
+Python3_add_library (spam3 MODULE ../spam.c)
+target_compile_definitions (spam3 PRIVATE PYTHON3)
+
+add_test (NAME python3_spam3
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:spam3>"
+ "${Python3_EXECUTABLE}" -c "import spam3; spam3.system(\"cd\")")
diff --git a/Tests/IncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/CMakeLists.txt
index 838a236..eb08676 100644
--- a/Tests/IncludeDirectories/CMakeLists.txt
+++ b/Tests/IncludeDirectories/CMakeLists.txt
@@ -66,21 +66,36 @@ else()
endif()
# Test escaping of special characters in include directory paths.
-# FIXME: Implement full support in Makefile generators
-if(NOT CMAKE_GENERATOR MATCHES "Make")
- set(special_chars "~@#$%^&=[]{}()!'")
- if(NOT CMAKE_GENERATOR STREQUAL "Visual Studio 9 2008")
- string(APPEND special_chars ",")
- endif()
- if(NOT WIN32 AND NOT CYGWIN)
- string(APPEND special_chars "*?<>")
- endif()
- set(special_dir "${CMAKE_CURRENT_BINARY_DIR}/special-${special_chars}-include")
- file(WRITE "${special_dir}/SpecialDir.h" "#define SPECIAL_DIR_H\n")
+set(special_chars "~@%&{}()!'")
+if(NOT CMAKE_GENERATOR STREQUAL "Watcom WMake")
+ # Watcom seems to have no way to encode these characters.
+ string(APPEND special_chars "#=[]")
+endif()
+if(NOT (MINGW AND CMAKE_GENERATOR MATCHES "(Unix|MSYS) Makefiles"))
+ # FIXME: Dependencies work but command-line generation does not handle '$'.
+ string(APPEND special_chars "$")
+endif()
+if(NOT CMAKE_GENERATOR MATCHES "(Borland|NMake) Makefiles")
+ # NMake and Borland seem to have no way to encode a single '^'.
+ string(APPEND special_chars "^")
+endif()
+if(NOT CMAKE_GENERATOR MATCHES "Visual Studio 9 2008|Watcom WMake")
+ # The vcproj format separates values with ','.
+ string(APPEND special_chars ",")
+endif()
+if(NOT WIN32 AND NOT CYGWIN)
+ string(APPEND special_chars "*?<>")
+endif()
+set(special_dir "${CMAKE_CURRENT_BINARY_DIR}/special-${special_chars}-include")
+file(WRITE "${special_dir}/SpecialDir.h" "#define SPECIAL_DIR_H\n")
+target_include_directories(IncludeDirectories PRIVATE "${special_dir}")
+target_compile_definitions(IncludeDirectories PRIVATE INCLUDE_SPECIAL_DIR)
+
+if(MAKE_SUPPORTS_SPACES)
set(special_space_dir "${CMAKE_CURRENT_BINARY_DIR}/special-space ${special_chars}-include")
file(WRITE "${special_space_dir}/SpecialSpaceDir.h" "#define SPECIAL_SPACE_DIR_H\n")
- target_include_directories(IncludeDirectories PRIVATE "${special_dir}" "${special_space_dir}")
- target_compile_definitions(IncludeDirectories PRIVATE INCLUDE_SPECIAL_DIR)
+ target_include_directories(IncludeDirectories PRIVATE "${special_space_dir}")
+ target_compile_definitions(IncludeDirectories PRIVATE INCLUDE_SPECIAL_SPACE_DIR)
endif()
add_library(ordertest ordertest.cpp)
diff --git a/Tests/IncludeDirectories/main.cpp b/Tests/IncludeDirectories/main.cpp
index 7368ee9..6dc88e2 100644
--- a/Tests/IncludeDirectories/main.cpp
+++ b/Tests/IncludeDirectories/main.cpp
@@ -8,6 +8,9 @@
# ifndef SPECIAL_DIR_H
# error "SPECIAL_DIR_H not defined"
# endif
+#endif
+
+#ifdef INCLUDE_SPECIAL_SPACE_DIR
# include "SpecialSpaceDir.h"
# ifndef SPECIAL_SPACE_DIR_H
# error "SPECIAL_SPACE_DIR_H not defined"
diff --git a/Tests/RunCMake/CMP0104/CMP0104-Common.cmake b/Tests/RunCMake/CMP0104/CMP0104-Common.cmake
new file mode 100644
index 0000000..b3568f1
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-Common.cmake
@@ -0,0 +1,2 @@
+enable_language(CUDA)
+add_library(cuda main.cu)
diff --git a/Tests/RunCMake/CMP0104/CMP0104-NEW.cmake b/Tests/RunCMake/CMP0104/CMP0104-NEW.cmake
new file mode 100644
index 0000000..732ab77
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-NEW.cmake
@@ -0,0 +1,6 @@
+cmake_policy(SET CMP0104 NEW)
+include(CMP0104-Common.cmake)
+
+if(NOT CMAKE_CUDA_ARCHITECTURES)
+ message(FATAL_ERROR "CMAKE_CUDA_ARCHITECTURES is empty with CMP0104 enabled.")
+endif()
diff --git a/Tests/RunCMake/CMP0104/CMP0104-OLD.cmake b/Tests/RunCMake/CMP0104/CMP0104-OLD.cmake
new file mode 100644
index 0000000..415eecc
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-OLD.cmake
@@ -0,0 +1,12 @@
+cmake_policy(SET CMP0104 OLD)
+include(CMP0104-Common.cmake)
+
+if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
+ if(CMAKE_CUDA_ARCHITECTURES)
+ message(FATAL_ERROR "CMAKE_CUDA_ARCHITECTURES isn't empty for NVIDIA with CMP0104 OLD.")
+ endif()
+else(NOT CMAKE_CUDA_COMPILER_ID STREQUAL "Unknown")
+ if(NOT CMAKE_CUDA_ARCHITECTURES)
+ message(FATAL_ERROR "CMAKE_CUDA_ARCHITECTURES isn't non-empty for non-NVIDIA with CMP0104 OLD.")
+ endif()
+endif()
diff --git a/Tests/RunCMake/CMP0104/CMP0104-WARN-stderr.txt b/Tests/RunCMake/CMP0104/CMP0104-WARN-stderr.txt
new file mode 100644
index 0000000..2c9b7d7
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-WARN-stderr.txt
@@ -0,0 +1,8 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+ Policy CMP0104 is not set: CMAKE_CUDA_ARCHITECTURES now detected for NVCC,
+ empty CUDA_ARCHITECTURES not allowed. Run "cmake --help-policy CMP0104"
+ for policy details. Use the cmake_policy command to set the policy and
+ suppress this warning.
+
+ CUDA_ARCHITECTURES is empty for target "cuda".
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0104/CMP0104-WARN.cmake b/Tests/RunCMake/CMP0104/CMP0104-WARN.cmake
new file mode 100644
index 0000000..841d0a8
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-WARN.cmake
@@ -0,0 +1 @@
+include(CMP0104-Common.cmake)
diff --git a/Tests/RunCMake/CMP0104/CMakeLists.txt b/Tests/RunCMake/CMP0104/CMakeLists.txt
new file mode 100644
index 0000000..2632ffa
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.16)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0104/RunCMakeTest.cmake b/Tests/RunCMake/CMP0104/RunCMakeTest.cmake
new file mode 100644
index 0000000..bc8e1b1
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0104-OLD)
+run_cmake(CMP0104-NEW)
+run_cmake(CMP0104-WARN)
diff --git a/Tests/RunCMake/CMP0104/main.cu b/Tests/RunCMake/CMP0104/main.cu
new file mode 100644
index 0000000..5047a34
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/main.cu
@@ -0,0 +1,3 @@
+int main()
+{
+}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 2a4af3e..34e1fbc 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -116,6 +116,9 @@ endif()
add_RunCMake_test(CMP0069)
add_RunCMake_test(CMP0081)
add_RunCMake_test(CMP0102)
+if(CMake_TEST_CUDA)
+ add_RunCMake_test(CMP0104)
+endif()
# The test for Policy 65 requires the use of the
# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
diff --git a/Tests/RunCMake/CommandLine/E_cat_directory-result.txt b/Tests/RunCMake/CommandLine/E_cat_directory-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_directory-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt b/Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt
new file mode 100644
index 0000000..c4d0d48
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: .* is a directory
diff --git a/Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt b/Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt
new file mode 100644
index 0000000..aae90e6
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt
@@ -0,0 +1,3 @@
+first file to append
+second file to append
+àéùç - 한국어
diff --git a/Tests/RunCMake/CommandLine/E_cat_non_existing_file-result.txt b/Tests/RunCMake/CommandLine/E_cat_non_existing_file-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_non_existing_file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt b/Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt
new file mode 100644
index 0000000..0d8fc4b
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: .*: no such file or directory \(ignoring\)
diff --git a/Tests/RunCMake/CommandLine/E_cat_non_readable_file-result.txt b/Tests/RunCMake/CommandLine/E_cat_non_readable_file-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_non_readable_file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt b/Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt
new file mode 100644
index 0000000..97ec822
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: .*: permission denied \(ignoring\)
diff --git a/Tests/RunCMake/CommandLine/E_cat_option_not_handled-result.txt b/Tests/RunCMake/CommandLine/E_cat_option_not_handled-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_option_not_handled-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt b/Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt
new file mode 100644
index 0000000..92f7acf
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: -f: option not handled
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index 839aec0..0f806bc 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -459,6 +459,44 @@ if(NOT WIN32 AND NOT CYGWIN)
endif()
unset(out)
+# cat tests
+set(out ${RunCMake_BINARY_DIR}/cat_tests)
+file(REMOVE_RECURSE "${out}")
+file(MAKE_DIRECTORY ${out})
+run_cmake_command(E_cat_non_existing_file
+ ${CMAKE_COMMAND} -E cat ${out}/non-existing-file.txt)
+
+if(UNIX)
+ # test non readable file only if not root
+ execute_process(
+ COMMAND id -u $ENV{USER}
+ OUTPUT_VARIABLE uid
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(NOT "${uid}" STREQUAL "0")
+ # Create non readable file
+ set(inside_folder "${out}/in")
+ file(MAKE_DIRECTORY ${inside_folder})
+ file(WRITE "${inside_folder}/non_readable_file.txt" "first file to append\n")
+ file(COPY "${inside_folder}/non_readable_file.txt" DESTINATION "${out}" FILE_PERMISSIONS OWNER_WRITE)
+ run_cmake_command(E_cat_non_readable_file
+ ${CMAKE_COMMAND} -E cat "${out}/non_readable_file.txt")
+ endif()
+endif()
+
+run_cmake_command(E_cat_option_not_handled
+ ${CMAKE_COMMAND} -E cat -f)
+
+run_cmake_command(E_cat_directory
+ ${CMAKE_COMMAND} -E cat ${out})
+
+file(WRITE "${out}/first_file.txt" "first file to append\n")
+file(WRITE "${out}/second_file.txt" "second file to append\n")
+file(WRITE "${out}/unicode_file.txt" "àéùç - 한국어") # Korean in Korean
+run_cmake_command(E_cat_good_cat
+ ${CMAKE_COMMAND} -E cat "${out}/first_file.txt" "${out}/second_file.txt" "${out}/unicode_file.txt")
+unset(out)
+
run_cmake_command(E_env-no-command0 ${CMAKE_COMMAND} -E env)
run_cmake_command(E_env-no-command1 ${CMAKE_COMMAND} -E env TEST_ENV=1)
run_cmake_command(E_env-bad-arg1 ${CMAKE_COMMAND} -E env -bad-arg1)
diff --git a/Tests/RunCMake/CompilerLauncher/CUDA-common.cmake b/Tests/RunCMake/CompilerLauncher/CUDA-common.cmake
index 6f7fc86..ca25b2a 100644
--- a/Tests/RunCMake/CompilerLauncher/CUDA-common.cmake
+++ b/Tests/RunCMake/CompilerLauncher/CUDA-common.cmake
@@ -1,3 +1,4 @@
+cmake_policy(SET CMP0104 NEW)
enable_language(CUDA)
set(CMAKE_VERBOSE_MAKEFILE TRUE)
add_executable(main main.cu)
diff --git a/Tests/RunCMake/NinjaMultiConfig/CudaSimple.cmake b/Tests/RunCMake/NinjaMultiConfig/CudaSimple.cmake
index 2e9b1cb..00d8a1b 100644
--- a/Tests/RunCMake/NinjaMultiConfig/CudaSimple.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/CudaSimple.cmake
@@ -1,3 +1,4 @@
+cmake_policy(SET CMP0104 NEW)
enable_language(CUDA)
file(TOUCH ${CMAKE_BINARY_DIR}/empty.cmake)
diff --git a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
index 9a1e027..7ffd522 100644
--- a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
+++ b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
@@ -29,6 +29,7 @@
\* CMP0083
\* CMP0095
\* CMP0099
+ \* CMP0104
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/TryCompile/CMakeLists.txt b/Tests/TryCompile/CMakeLists.txt
index 9ec9b70..df921d8 100644
--- a/Tests/TryCompile/CMakeLists.txt
+++ b/Tests/TryCompile/CMakeLists.txt
@@ -187,7 +187,7 @@ try_compile(SHOULD_FAIL_DUE_TO_BAD_SOURCE
if(SHOULD_FAIL_DUE_TO_BAD_SOURCE AND NOT CMAKE_GENERATOR MATCHES "Watcom WMake|NMake Makefiles")
string(REPLACE "\n" "\n " output " ${output}")
message(SEND_ERROR "try_compile with bad#source.c did not fail:\n${output}")
-elseif(NOT output MATCHES [[(bad#source\.c|bad\\)]])
+elseif(NOT output MATCHES [[(bad#source\.c|bad\.c|bad')]])
string(REPLACE "\n" "\n " output " ${output}")
message(SEND_ERROR "try_compile with bad#source.c failed without mentioning bad source:\n${output}")
else()
diff --git a/Utilities/GitSetup/setup-user b/Utilities/GitSetup/setup-user
index 0b98879..4cbd184 100755
--- a/Utilities/GitSetup/setup-user
+++ b/Utilities/GitSetup/setup-user
@@ -20,7 +20,14 @@
# Project configuration instructions: NONE
for (( ; ; )); do
- ident="$(git var GIT_AUTHOR_IDENT 2>/dev/null | rev | cut -d' ' -f3- | rev)"
+ if type -p rev >/dev/null && type -p cut >/dev/null; then
+ ident="$(git var GIT_AUTHOR_IDENT 2>/dev/null | rev | cut -d' ' -f3- | rev)"
+ elif user_name=$(git config --get user.name) &&
+ user_email=$(git config --get user.email); then
+ ident="$user_name <$user_email>"
+ else
+ ident=""
+ fi
if test -n "$ident"; then
echo 'Your commits will record as Author:
diff --git a/Utilities/std/cmext/algorithm b/Utilities/std/cmext/algorithm
index 44e61f4..251c89a 100644
--- a/Utilities/std/cmext/algorithm
+++ b/Utilities/std/cmext/algorithm
@@ -13,12 +13,11 @@
#include <cm/type_traits>
#include <cmext/iterator>
+#include <cmext/type_traits>
#if defined(__SUNPRO_CC) && defined(__sparc)
# include <list>
# include <vector>
-#else
-# include <cmext/type_traits>
#endif
namespace cm {
@@ -158,6 +157,95 @@ void append(T& v, U const& r)
# endif
#endif
+#if defined(__SUNPRO_CC)
+template <typename Iterator, typename Key>
+auto contains(Iterator first, Iterator last, Key const& key,
+ detail::overload_selector<1>) -> decltype(first->first == key)
+#else
+template <typename Iterator, typename Key,
+ cm::enable_if_t<
+ cm::is_input_iterator<Iterator>::value &&
+ std::is_convertible<Key,
+ typename std::iterator_traits<
+ Iterator>::value_type::first_type>::value,
+ int> = 0>
+bool contains(Iterator first, Iterator last, Key const& key)
+#endif
+{
+ return std::find_if(
+ first, last,
+ [&key](
+ typename std::iterator_traits<Iterator>::value_type const& item) {
+ return item.first == key;
+ }) != last;
+}
+
+#if defined(__SUNPRO_CC)
+template <typename Iterator, typename Key>
+bool contains(Iterator first, Iterator last, Key const& key,
+ detail::overload_selector<0>)
+#else
+template <
+ typename Iterator, typename Key,
+ cm::enable_if_t<
+ cm::is_input_iterator<Iterator>::value &&
+ std::is_convertible<
+ Key, typename std::iterator_traits<Iterator>::value_type>::value,
+ int> = 0>
+bool contains(Iterator first, Iterator last, Key const& key)
+#endif
+{
+ return std::find(first, last, key) != last;
+}
+
+#if defined(__SUNPRO_CC)
+template <typename Iterator, typename Key>
+bool contains(Iterator first, Iterator last, Key const& key)
+{
+ return contains(first, last, key, detail::overload_selector<1>{});
+}
+#endif
+
+#if defined(__SUNPRO_CC)
+template <typename Range, typename Key>
+auto contains(Range const& range, Key const& key, detail::overload_selector<1>)
+ -> decltype(range.find(key) != range.end())
+#else
+template <
+ typename Range, typename Key,
+ cm::enable_if_t<cm::is_associative_container<Range>::value ||
+ cm::is_unordered_associative_container<Range>::value,
+ int> = 0>
+bool contains(Range const& range, Key const& key)
+#endif
+{
+ return range.find(key) != range.end();
+}
+
+#if defined(__SUNPRO_CC)
+template <typename Range, typename Key>
+bool contains(Range const& range, Key const& key, detail::overload_selector<0>)
+#else
+template <
+ typename Range, typename Key,
+ cm::enable_if_t<cm::is_input_range<Range>::value &&
+ !(cm::is_associative_container<Range>::value ||
+ cm::is_unordered_associative_container<Range>::value),
+ int> = 0>
+bool contains(Range const& range, Key const& key)
+#endif
+{
+ return std::find(std::begin(range), std::end(range), key) != std::end(range);
+}
+
+#if defined(__SUNPRO_CC)
+template <typename Range, typename Key>
+bool contains(Range const& range, Key const& key)
+{
+ return contains(range, key, detail::overload_selector<1>{});
+}
+#endif
+
} // namespace cm
#endif
diff --git a/Utilities/std/cmext/iterator b/Utilities/std/cmext/iterator
index ffe94b1..ce9462f 100644
--- a/Utilities/std/cmext/iterator
+++ b/Utilities/std/cmext/iterator
@@ -23,25 +23,27 @@ using is_input_iterator =
std::is_base_of<std::input_iterator_tag,
typename std::iterator_traits<I>::iterator_category>;
-// checks if a type is a range type: must have a difference_type type
+// checks if a type is a range type: std::begin() and std::end() are supported
template <typename Range>
using is_range = cm::bool_constant<
- cm::is_iterator<decltype(std::declval<const Range>().begin())>::value &&
- cm::is_iterator<decltype(std::declval<const Range>().end())>::value>;
+ cm::is_iterator<decltype(std::begin(std::declval<const Range>()))>::value &&
+ cm::is_iterator<decltype(std::end(std::declval<const Range>()))>::value>;
-// checks if a type is an input range type: must have methods begin() and end()
+// checks if a type is an input range type: std::begin() and std::end() are
// returning an input iterator
template <typename Range>
using is_input_range =
#if defined(_MSC_VER) && _MSC_VER < 1920
// MS C++ is not able to evaluate complex type introspection,
// so use a simplified version
- cm::is_input_iterator<typename Range::const_iterator>;
+ cm::bool_constant<std::is_class<Range>::value ||
+ std::is_pointer<Range>::value ||
+ std::is_array<Range>::value>;
#else
- cm::bool_constant<
- cm::is_input_iterator<decltype(
- std::declval<const Range>().begin())>::value &&
- cm::is_input_iterator<decltype(std::declval<const Range>().end())>::value>;
+ cm::bool_constant<cm::is_input_iterator<decltype(
+ std::begin(std::declval<const Range>()))>::value &&
+ cm::is_input_iterator<decltype(
+ std::end(std::declval<const Range>()))>::value>;
#endif
} // namespace cm
diff --git a/Utilities/std/cmext/type_traits b/Utilities/std/cmext/type_traits
index 00984cb..f02b488 100644
--- a/Utilities/std/cmext/type_traits
+++ b/Utilities/std/cmext/type_traits
@@ -6,6 +6,8 @@
#ifndef cmext_type_traits
#define cmext_type_traits
+#include <memory>
+
#include <cm/type_traits>
namespace cm {