summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/command/FIND_XXX.txt29
-rw-r--r--Help/command/define_property.rst22
-rw-r--r--Help/command/find_file.rst3
-rw-r--r--Help/command/find_library.rst3
-rw-r--r--Help/command/find_package.rst24
-rw-r--r--Help/command/find_path.rst3
-rw-r--r--Help/command/find_program.rst2
-rw-r--r--Help/command/get_directory_property.rst15
-rw-r--r--Help/command/get_property.rst5
-rw-r--r--Help/command/get_source_file_property.rst14
-rw-r--r--Help/command/get_target_property.rst11
-rw-r--r--Help/command/get_test_property.rst12
-rw-r--r--Help/command/list.rst180
-rw-r--r--Help/command/project.rst23
-rw-r--r--Help/command/set_property.rst16
-rw-r--r--Help/command/set_target_properties.rst6
-rw-r--r--Help/command/string.rst4
-rw-r--r--Help/command/target_compile_definitions.rst10
-rw-r--r--Help/manual/cmake-compile-features.7.rst2
-rw-r--r--Help/manual/cmake-developer.7.rst2
-rw-r--r--Help/manual/cmake-modules.7.rst3
-rw-r--r--Help/manual/cmake-policies.7.rst1
-rw-r--r--Help/manual/cmake-properties.7.rst2
-rw-r--r--Help/manual/cmake-variables.7.rst4
-rw-r--r--Help/module/FindPython.rst1
-rw-r--r--Help/module/FindPython2.rst1
-rw-r--r--Help/module/FindPython3.rst1
-rw-r--r--Help/policy/CMP0074.rst22
-rw-r--r--Help/prop_tgt/EXPORT_PROPERTIES.rst14
-rw-r--r--Help/prop_tgt/INSTALL_NAME_DIR.rst4
-rw-r--r--Help/prop_tgt/VS_DEBUGGER_COMMAND.rst9
-rw-r--r--Help/release/dev/FindPython-new-implementation.rst5
-rw-r--r--Help/release/dev/export-properties.rst6
-rw-r--r--Help/release/dev/find-package_root-restore.rst8
-rw-r--r--Help/release/dev/list-join.rst5
-rw-r--r--Help/release/dev/project-homepage.rst7
-rw-r--r--Help/release/dev/vs-debugger-config.rst6
-rw-r--r--Help/variable/CMAKE_PROJECT_DESCRIPTION.rst2
-rw-r--r--Help/variable/CMAKE_PROJECT_HOMEPAGE_URL.rst35
-rw-r--r--Help/variable/PROJECT-NAME_DESCRIPTION.rst5
-rw-r--r--Help/variable/PROJECT-NAME_HOMEPAGE_URL.rst5
-rw-r--r--Help/variable/PROJECT_HOMEPAGE_URL.rst9
-rw-r--r--Modules/CPackDeb.cmake7
-rw-r--r--Modules/CPackFreeBSD.cmake4
-rw-r--r--Modules/CPackRPM.cmake6
-rw-r--r--Modules/Compiler/Intel-CXX-FeatureTests.cmake6
-rw-r--r--Modules/Compiler/SunPro-CXX-FeatureTests.cmake6
-rw-r--r--Modules/FindCUDA/select_compute_arch.cmake25
-rw-r--r--Modules/FindCxxTest.cmake8
-rw-r--r--Modules/FindPython.cmake180
-rw-r--r--Modules/FindPython/Support.cmake843
-rw-r--r--Modules/FindPython2.cmake146
-rw-r--r--Modules/FindPython3.cmake146
-rw-r--r--Modules/FindPythonInterp.cmake4
-rw-r--r--Modules/FindPythonLibs.cmake4
-rw-r--r--Modules/FindQt4.cmake13
-rw-r--r--Modules/FindwxWidgets.cmake12
-rw-r--r--Modules/WriteCompilerDetectionHeader.cmake13
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CursesDialog/cmCursesStandardIncludes.h13
-rw-r--r--Source/cmComputeLinkInformation.cxx2
-rw-r--r--Source/cmComputeLinkInformation.h2
-rw-r--r--Source/cmDependsC.cxx11
-rw-r--r--Source/cmExportBuildFileGenerator.cxx9
-rw-r--r--Source/cmExportFileGenerator.cxx40
-rw-r--r--Source/cmExportFileGenerator.h4
-rw-r--r--Source/cmExportInstallFileGenerator.cxx6
-rw-r--r--Source/cmExtraCodeLiteGenerator.cxx11
-rw-r--r--Source/cmFindBase.cxx18
-rw-r--r--Source/cmFindCommon.cxx7
-rw-r--r--Source/cmFindCommon.h3
-rw-r--r--Source/cmFindPackageCommand.cxx58
-rw-r--r--Source/cmListCommand.cxx31
-rw-r--r--Source/cmListCommand.h1
-rw-r--r--Source/cmMakefile.cxx26
-rw-r--r--Source/cmMakefile.h9
-rw-r--r--Source/cmPolicies.h4
-rw-r--r--Source/cmProjectCommand.cxx49
-rw-r--r--Source/cmSearchPath.h4
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx155
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h10
-rw-r--r--Tests/CMakeLists.txt4
-rw-r--r--Tests/CompileFeatures/cxx_generalized_initializers.cpp6
-rw-r--r--Tests/ExportImport/Export/CMakeLists.txt8
-rw-r--r--Tests/ExportImport/Import/A/CMakeLists.txt14
-rw-r--r--Tests/FindPython/CMakeLists.txt69
-rw-r--r--Tests/FindPython/MultiplePackages/CMakeLists.txt33
-rw-r--r--Tests/FindPython/Python/CMakeLists.txt17
-rw-r--r--Tests/FindPython/Python2/CMakeLists.txt22
-rw-r--r--Tests/FindPython/Python2Fail/CMakeLists.txt14
-rw-r--r--Tests/FindPython/Python3/CMakeLists.txt22
-rw-r--r--Tests/FindPython/Python3Fail/CMakeLists.txt14
-rw-r--r--Tests/FindPython/spam.c41
-rw-r--r--Tests/RunCMake/UseSWIG/BasicConfiguration.cmake7
-rw-r--r--Tests/RunCMake/UseSWIG/BasicPython.cmake2
-rw-r--r--Tests/RunCMake/UseSWIG/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/UseSWIG/MultiplePython.cmake26
-rw-r--r--Tests/RunCMake/UseSWIG/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/VS10Project/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/VS10Project/VsDebuggerCommand-check.cmake22
-rw-r--r--Tests/RunCMake/VS10Project/VsDebuggerCommand.cmake5
-rw-r--r--Tests/RunCMake/export/ForbiddenToExportImportedProperties-result.txt1
-rw-r--r--Tests/RunCMake/export/ForbiddenToExportImportedProperties-stderr.txt3
-rw-r--r--Tests/RunCMake/export/ForbiddenToExportImportedProperties.cmake12
-rw-r--r--Tests/RunCMake/export/ForbiddenToExportInterfaceProperties-result.txt1
-rw-r--r--Tests/RunCMake/export/ForbiddenToExportInterfaceProperties-stderr.txt3
-rw-r--r--Tests/RunCMake/export/ForbiddenToExportInterfaceProperties.cmake12
-rw-r--r--Tests/RunCMake/export/ForbiddenToExportPropertyWithGenExp-result.txt1
-rw-r--r--Tests/RunCMake/export/ForbiddenToExportPropertyWithGenExp-stderr.txt3
-rw-r--r--Tests/RunCMake/export/ForbiddenToExportPropertyWithGenExp.cmake12
-rw-r--r--Tests/RunCMake/export/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/export/empty.cpp7
-rw-r--r--Tests/RunCMake/find_package/CMP0074-OLD-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/CMP0074-OLD.cmake2
-rw-r--r--Tests/RunCMake/find_package/CMP0074-WARN-stderr.txt32
-rw-r--r--Tests/RunCMake/find_package/CMP0074-WARN.cmake2
-rw-r--r--Tests/RunCMake/find_package/CMP0074-common.cmake46
-rw-r--r--Tests/RunCMake/find_package/PackageRoot.cmake2
-rw-r--r--Tests/RunCMake/find_package/PackageRootNestedConfig.cmake2
-rw-r--r--Tests/RunCMake/find_package/PackageRootNestedModule.cmake2
-rw-r--r--Tests/RunCMake/find_package/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/list/JOIN-NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/JOIN-NoArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/JOIN-NoArguments.cmake1
-rw-r--r--Tests/RunCMake/list/JOIN-NoVariable-result.txt1
-rw-r--r--Tests/RunCMake/list/JOIN-NoVariable-stderr.txt4
-rw-r--r--Tests/RunCMake/list/JOIN-NoVariable.cmake1
-rw-r--r--Tests/RunCMake/list/JOIN-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/JOIN-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/JOIN-TooManyArguments.cmake1
-rw-r--r--Tests/RunCMake/list/JOIN.cmake18
-rw-r--r--Tests/RunCMake/list/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/project/ProjectDescriptionNoArg.cmake2
-rw-r--r--Tests/RunCMake/project/ProjectHomepage-stdout.txt3
-rw-r--r--Tests/RunCMake/project/ProjectHomepage.cmake14
-rw-r--r--Tests/RunCMake/project/ProjectHomepage2-result.txt1
-rw-r--r--Tests/RunCMake/project/ProjectHomepage2-stderr.txt4
-rw-r--r--Tests/RunCMake/project/ProjectHomepage2.cmake2
-rw-r--r--Tests/RunCMake/project/ProjectHomepageNoArg-stderr.txt5
-rw-r--r--Tests/RunCMake/project/ProjectHomepageNoArg.cmake2
-rw-r--r--Tests/RunCMake/project/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/project/VersionMissingLanguages-stderr.txt4
-rw-r--r--Tests/RunCMake/set_property/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/set_property/USER_PROP_INHERITED-stdout.txt29
-rw-r--r--Tests/RunCMake/set_property/USER_PROP_INHERITED.cmake83
-rw-r--r--Tests/RunCMake/set_property/USER_PROP_INHERITED/CMakeLists.txt21
-rw-r--r--Tests/Server/CMakeLists.txt4
147 files changed, 2881 insertions, 272 deletions
diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt
index 7db221c..13ea8ab 100644
--- a/Help/command/FIND_XXX.txt
+++ b/Help/command/FIND_XXX.txt
@@ -16,6 +16,7 @@ The general signature is:
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[DOC "cache documentation string"]
[NO_DEFAULT_PATH]
+ [NO_PACKAGE_ROOT_PATH]
[NO_CMAKE_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
@@ -60,6 +61,10 @@ If ``NO_DEFAULT_PATH`` is specified, then no additional paths are
added to the search.
If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
+.. |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX_SUBDIR| replace::
+ |prefix_XXX_SUBDIR| for each ``<prefix>`` in ``PackageName_ROOT`` if called
+ from within a find module
+
.. |CMAKE_PREFIX_PATH_XXX_SUBDIR| replace::
|prefix_XXX_SUBDIR| for each ``<prefix>`` in :variable:`CMAKE_PREFIX_PATH`
@@ -71,7 +76,19 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
|prefix_XXX_SUBDIR| for each ``<prefix>`` in
:variable:`CMAKE_SYSTEM_PREFIX_PATH`
-1. Search paths specified in cmake-specific cache variables.
+1. If called from within a find module, search prefix paths unique to the
+ current package being found. Specifically look in the ``PackageName_ROOT``
+ CMake and environment variables. The package root variables are maintained
+ as a stack so if called from nested find modules, root paths from the
+ parent's find module will be searchd after paths from the current module,
+ i.e. ``CurrentPackage_ROOT``, ``ENV{CurrentPackage_ROOT}``,
+ ``ParentPackage_ROOT``, ``ENV{ParentPacakge_ROOT}``, etc.
+ This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed.
+ See policy :policy:`CMP0074`.
+
+ * |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX|
+
+2. Search paths specified in cmake-specific cache variables.
These are intended to be used on the command line with a ``-DVAR=value``.
The values are interpreted as :ref:`;-lists <CMake Language Lists>`.
This can be skipped if ``NO_CMAKE_PATH`` is passed.
@@ -80,7 +97,7 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
* |CMAKE_XXX_PATH|
* |CMAKE_XXX_MAC_PATH|
-2. Search paths specified in cmake-specific environment variables.
+3. Search paths specified in cmake-specific environment variables.
These are intended to be set in the user's shell configuration,
and therefore use the host's native path separator
(``;`` on Windows and ``:`` on UNIX).
@@ -90,17 +107,17 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
* |CMAKE_XXX_PATH|
* |CMAKE_XXX_MAC_PATH|
-3. Search the paths specified by the ``HINTS`` option.
+4. Search the paths specified by the ``HINTS`` option.
These should be paths computed by system introspection, such as a
hint provided by the location of another item already found.
Hard-coded guesses should be specified with the ``PATHS`` option.
-4. Search the standard system environment variables.
+5. Search the standard system environment variables.
This can be skipped if ``NO_SYSTEM_ENVIRONMENT_PATH`` is an argument.
* |SYSTEM_ENVIRONMENT_PATH_XXX|
-5. Search cmake variables defined in the Platform files
+6. Search cmake variables defined in the Platform files
for the current system. This can be skipped if ``NO_CMAKE_SYSTEM_PATH``
is passed.
@@ -108,7 +125,7 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
* |CMAKE_SYSTEM_XXX_PATH|
* |CMAKE_SYSTEM_XXX_MAC_PATH|
-6. Search the paths specified by the PATHS option
+7. Search the paths specified by the PATHS option
or in the short-hand version of the command.
These are typically hard-coded guesses.
diff --git a/Help/command/define_property.rst b/Help/command/define_property.rst
index 873c6ca..da2631c 100644
--- a/Help/command/define_property.rst
+++ b/Help/command/define_property.rst
@@ -34,10 +34,24 @@ actual scope needs to be given; only the kind of scope is important.
The required ``PROPERTY`` option is immediately followed by the name of
the property being defined.
-If the ``INHERITED`` option then the :command:`get_property` command will
-chain up to the next higher scope when the requested property is not set
-in the scope given to the command. ``DIRECTORY`` scope chains to
-``GLOBAL``. ``TARGET``, ``SOURCE``, and ``TEST`` chain to ``DIRECTORY``.
+If the ``INHERITED`` option is given, then the :command:`get_property` command
+will chain up to the next higher scope when the requested property is not set
+in the scope given to the command.
+
+* ``DIRECTORY`` scope chains to its parent directory's scope, continuing the
+ walk up parent directories until a directory has the property set or there
+ are no more parents. If still not found at the top level directory, it
+ chains to the ``GLOBAL`` scope.
+* ``TARGET``, ``SOURCE`` and ``TEST`` properties chain to ``DIRECTORY`` scope,
+ including further chaining up the directories, etc. as needed.
+
+Note that this scope chaining behavior only applies to calls to
+:command:`get_property`, :command:`get_directory_property`,
+:command:`get_target_property`, :command:`get_source_file_property` and
+:command:`get_test_property`. There is no inheriting behavior when *setting*
+properties, so using ``APPEND`` or ``APPEND_STRING`` with the
+:command:`set_property` command will not consider inherited values when working
+out the contents to append to.
The ``BRIEF_DOCS`` and ``FULL_DOCS`` options are followed by strings to be
associated with the property as its brief and full documentation.
diff --git a/Help/command/find_file.rst b/Help/command/find_file.rst
index e56097b..2a14ad7 100644
--- a/Help/command/find_file.rst
+++ b/Help/command/find_file.rst
@@ -8,6 +8,9 @@ find_file
.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/include``
.. |entry_XXX_SUBDIR| replace:: ``<entry>/include``
+.. |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX| replace::
+ ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
+ is set, and |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX_SUBDIR|
.. |CMAKE_PREFIX_PATH_XXX| replace::
``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
is set, and |CMAKE_PREFIX_PATH_XXX_SUBDIR|
diff --git a/Help/command/find_library.rst b/Help/command/find_library.rst
index f774f17..0861d67 100644
--- a/Help/command/find_library.rst
+++ b/Help/command/find_library.rst
@@ -8,6 +8,9 @@ find_library
.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/lib``
.. |entry_XXX_SUBDIR| replace:: ``<entry>/lib``
+.. |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX| replace::
+ ``<prefix>/lib/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set,
+ and |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX_SUBDIR|
.. |CMAKE_PREFIX_PATH_XXX| replace::
``<prefix>/lib/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set,
and |CMAKE_PREFIX_PATH_XXX_SUBDIR|
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index b2e70f2..89c5a7a 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -64,6 +64,7 @@ The complete Config mode command signature is::
[PATHS path1 [path2 ... ]]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[NO_DEFAULT_PATH]
+ [NO_PACKAGE_ROOT_PATH]
[NO_CMAKE_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
@@ -249,7 +250,14 @@ The set of installation prefixes is constructed using the following
steps. If ``NO_DEFAULT_PATH`` is specified all ``NO_*`` options are
enabled.
-1. Search paths specified in cmake-specific cache variables. These
+1. Search paths specified in the ``PackageName_ROOT`` CMake and environment
+ variables. The package root variables are maintained as a stack so if
+ called from within a find module, root paths from the parent's find
+ module will also be searched after paths for the current package.
+ This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed.
+ See policy :policy:`CMP0074`.
+
+2. Search paths specified in cmake-specific cache variables. These
are intended to be used on the command line with a ``-DVAR=value``.
The values are interpreted as :ref:`;-lists <CMake Language Lists>`.
This can be skipped if ``NO_CMAKE_PATH`` is passed::
@@ -258,7 +266,7 @@ enabled.
CMAKE_FRAMEWORK_PATH
CMAKE_APPBUNDLE_PATH
-2. Search paths specified in cmake-specific environment variables.
+3. Search paths specified in cmake-specific environment variables.
These are intended to be set in the user's shell configuration,
and therefore use the host's native path separator
(``;`` on Windows and ``:`` on UNIX).
@@ -269,26 +277,26 @@ enabled.
CMAKE_FRAMEWORK_PATH
CMAKE_APPBUNDLE_PATH
-3. Search paths specified by the ``HINTS`` option. These should be paths
+4. Search paths specified by the ``HINTS`` option. These should be paths
computed by system introspection, such as a hint provided by the
location of another item already found. Hard-coded guesses should
be specified with the ``PATHS`` option.
-4. Search the standard system environment variables. This can be
+5. Search the standard system environment variables. This can be
skipped if ``NO_SYSTEM_ENVIRONMENT_PATH`` is passed. Path entries
ending in ``/bin`` or ``/sbin`` are automatically converted to their
parent directories::
PATH
-5. Search paths stored in the CMake :ref:`User Package Registry`.
+6. Search paths stored in the CMake :ref:`User Package Registry`.
This can be skipped if ``NO_CMAKE_PACKAGE_REGISTRY`` is passed or by
setting the :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY`
to ``TRUE``.
See the :manual:`cmake-packages(7)` manual for details on the user
package registry.
-6. Search cmake variables defined in the Platform files for the
+7. Search cmake variables defined in the Platform files for the
current system. This can be skipped if ``NO_CMAKE_SYSTEM_PATH`` is
passed::
@@ -296,14 +304,14 @@ enabled.
CMAKE_SYSTEM_FRAMEWORK_PATH
CMAKE_SYSTEM_APPBUNDLE_PATH
-7. Search paths stored in the CMake :ref:`System Package Registry`.
+8. Search paths stored in the CMake :ref:`System Package Registry`.
This can be skipped if ``NO_CMAKE_SYSTEM_PACKAGE_REGISTRY`` is passed
or by setting the
:variable:`CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY` to ``TRUE``.
See the :manual:`cmake-packages(7)` manual for details on the system
package registry.
-8. Search paths specified by the ``PATHS`` option. These are typically
+9. Search paths specified by the ``PATHS`` option. These are typically
hard-coded guesses.
.. |FIND_XXX| replace:: find_package
diff --git a/Help/command/find_path.rst b/Help/command/find_path.rst
index 76342d0..988a3fa 100644
--- a/Help/command/find_path.rst
+++ b/Help/command/find_path.rst
@@ -8,6 +8,9 @@ find_path
.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/include``
.. |entry_XXX_SUBDIR| replace:: ``<entry>/include``
+.. |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX| replace::
+ ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
+ is set, and |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX_SUBDIR|
.. |CMAKE_PREFIX_PATH_XXX| replace::
``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE`
is set, and |CMAKE_PREFIX_PATH_XXX_SUBDIR|
diff --git a/Help/command/find_program.rst b/Help/command/find_program.rst
index d3430c0..4f00773 100644
--- a/Help/command/find_program.rst
+++ b/Help/command/find_program.rst
@@ -8,6 +8,8 @@ find_program
.. |prefix_XXX_SUBDIR| replace:: ``<prefix>/[s]bin``
.. |entry_XXX_SUBDIR| replace:: ``<entry>/[s]bin``
+.. |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX| replace::
+ |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX_SUBDIR|
.. |CMAKE_PREFIX_PATH_XXX| replace::
|CMAKE_PREFIX_PATH_XXX_SUBDIR|
.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_PROGRAM_PATH`
diff --git a/Help/command/get_directory_property.rst b/Help/command/get_directory_property.rst
index e50abe0..bf8349c 100644
--- a/Help/command/get_directory_property.rst
+++ b/Help/command/get_directory_property.rst
@@ -7,11 +7,16 @@ Get a property of ``DIRECTORY`` scope.
get_directory_property(<variable> [DIRECTORY <dir>] <prop-name>)
-Store a property of directory scope in the named variable. If the
-property is not defined the empty-string is returned. The ``DIRECTORY``
-argument specifies another directory from which to retrieve the
-property value. The specified directory must have already been
-traversed by CMake.
+Store a property of directory scope in the named ``<variable>``.
+The ``DIRECTORY`` argument specifies another directory from which
+to retrieve the property value instead of the current directory.
+The specified directory must have already been traversed by CMake.
+
+If the property is not defined for the nominated directory scope,
+an empty string is returned. In the case of ``INHERITED`` properties,
+if the property is not found for the nominated directory scope,
+the search will chain to a parent scope as described for the
+:command:`define_property` command.
::
diff --git a/Help/command/get_property.rst b/Help/command/get_property.rst
index 632ece6..8b85f7d 100644
--- a/Help/command/get_property.rst
+++ b/Help/command/get_property.rst
@@ -50,7 +50,10 @@ be one of the following:
The required ``PROPERTY`` option is immediately followed by the name of
the property to get. If the property is not set an empty value is
-returned. If the ``SET`` option is given the variable is set to a boolean
+returned, although some properties support inheriting from a parent scope
+if defined to behave that way (see :command:`define_property`).
+
+If the ``SET`` option is given the variable is set to a boolean
value indicating whether the property has been set. If the ``DEFINED``
option is given the variable is set to a boolean value indicating
whether the property has been defined such as with the
diff --git a/Help/command/get_source_file_property.rst b/Help/command/get_source_file_property.rst
index 3e975c2..648ecbd 100644
--- a/Help/command/get_source_file_property.rst
+++ b/Help/command/get_source_file_property.rst
@@ -8,9 +8,15 @@ Get a property for a source file.
get_source_file_property(VAR file property)
Get a property from a source file. The value of the property is
-stored in the variable ``VAR``. If the property is not found, ``VAR``
-will be set to "NOTFOUND". Use :command:`set_source_files_properties`
-to set property values. Source file properties usually control how the
-file is built. One property that is always there is :prop_sf:`LOCATION`
+stored in the variable ``VAR``. If the source property is not found, the
+behavior depends on whether it has been defined to be an ``INHERITED`` property
+or not (see :command:`define_property`). Non-inherited properties will set
+``VAR`` to "NOTFOUND", whereas inheritied properties will search the relevent
+parent scope as described for the :command:`define_property` command and
+if still unable to find the property, ``VAR`` will be set to an empty string.
+
+Use :command:`set_source_files_properties` to set property values. Source
+file properties usually control how the file is built. One property that is
+always there is :prop_sf:`LOCATION`.
See also the more general :command:`get_property` command.
diff --git a/Help/command/get_target_property.rst b/Help/command/get_target_property.rst
index 2a72c3a..3d159dc 100644
--- a/Help/command/get_target_property.rst
+++ b/Help/command/get_target_property.rst
@@ -8,8 +8,15 @@ Get a property from a target.
get_target_property(VAR target property)
Get a property from a target. The value of the property is stored in
-the variable ``VAR``. If the property is not found, ``VAR`` will be set to
-"NOTFOUND". Use :command:`set_target_properties` to set property values.
+the variable ``VAR``. If the target property is not found, the behavior
+depends on whether it has been defined to be an ``INHERITED`` property
+or not (see :command:`define_property`). Non-inherited properties will
+set ``VAR`` to "NOTFOUND", whereas inheritied properties will search the
+relevent parent scope as described for the :command:`define_property`
+command and if still unable to find the property, ``VAR`` will be set to
+an empty string.
+
+Use :command:`set_target_properties` to set target property values.
Properties are usually used to control how a target is built, but some
query the target instead. This command can get properties for any
target so far created. The targets do not need to be in the current
diff --git a/Help/command/get_test_property.rst b/Help/command/get_test_property.rst
index e359f4b..703efdc 100644
--- a/Help/command/get_test_property.rst
+++ b/Help/command/get_test_property.rst
@@ -8,8 +8,14 @@ Get a property of the test.
get_test_property(test property VAR)
Get a property from the test. The value of the property is stored in
-the variable ``VAR``. If the test or property is not found, ``VAR`` will
-be set to "NOTFOUND". For a list of standard properties you can type
-``cmake --help-property-list``.
+the variable ``VAR``. If the test property is not found, the behavior
+depends on whether it has been defined to be an ``INHERITED`` property
+or not (see :command:`define_property`). Non-inherited properties will
+set ``VAR`` to "NOTFOUND", whereas inheritied properties will search the
+relevent parent scope as described for the :command:`define_property`
+command and if still unable to find the property, ``VAR`` will be set to
+an empty string.
+
+For a list of standard properties you can type ``cmake --help-property-list``.
See also the more general :command:`get_property` command.
diff --git a/Help/command/list.rst b/Help/command/list.rst
index f6b75bc..3c092bd 100644
--- a/Help/command/list.rst
+++ b/Help/command/list.rst
@@ -1,68 +1,162 @@
list
----
+.. only:: html
+
+ .. contents::
+
List operations.
+The list subcommands ``APPEND``, ``INSERT``, ``FILTER``, ``REMOVE_AT``,
+``REMOVE_ITEM``, ``REMOVE_DUPLICATES``, ``REVERSE`` and ``SORT`` may create
+new values for the list within the current CMake variable scope. Similar to
+the :command:`set` command, the LIST command creates new variable values in
+the current scope, even if the list itself is actually defined in a parent
+scope. To propagate the results of these operations upwards, use
+:command:`set` with ``PARENT_SCOPE``, :command:`set` with
+``CACHE INTERNAL``, or some other means of value propagation.
+
+.. note::
+
+ A list in cmake is a ``;`` separated group of strings. To create a
+ list the set command can be used. For example, ``set(var a b c d e)``
+ creates a list with ``a;b;c;d;e``, and ``set(var "a b c d e")`` creates a
+ string or a list with one item in it. (Note macro arguments are not
+ variables, and therefore cannot be used in LIST commands.)
+
+.. note::
+
+ When specifying index values, if ``<element index>`` is 0 or greater, it
+ is indexed from the beginning of the list, with 0 representing the
+ first list element. If ``<element index>`` is -1 or lesser, it is indexed
+ from the end of the list, with -1 representing the last list element.
+ Be careful when counting with negative indices: they do not start from
+ 0. -0 is equivalent to 0, the first list element.
+
+Capacity and Element access
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+LENGTH
+""""""
+
::
list(LENGTH <list> <output variable>)
- list(GET <list> <element index> [<element index> ...]
- <output variable>)
+
+Returns the list's length.
+
+GET
+"""
+
+::
+
+ list(GET <list> <element index> [<element index> ...] <output variable>)
+
+Returns the list of elements specified by indices from the list.
+
+JOIN
+""""
+
+::
+
+ list(JOIN <list> <glue> <output variable>)
+
+Returns a string joining all list's elements using the glue string.
+To join multiple strings, which are not part of a list, use ``JOIN`` operator
+from :command:`string` command.
+
+Search
+^^^^^^
+
+FIND
+""""
+
+::
+
+ list(FIND <list> <value> <output variable>)
+
+Returns the index of the element specified in the list or -1
+if it wasn't found.
+
+Modification
+^^^^^^^^^^^^
+
+APPEND
+""""""
+
+::
+
list(APPEND <list> [<element> ...])
+
+Appends elements to the list.
+
+FILTER
+""""""
+
+::
+
list(FILTER <list> <INCLUDE|EXCLUDE> REGEX <regular_expression>)
- list(FIND <list> <value> <output variable>)
+
+Includes or removes items from the list that match the mode's pattern.
+In ``REGEX`` mode, items will be matched against the given regular expression.
+
+For more information on regular expressions see also the
+:command:`string` command.
+
+INSERT
+""""""
+
+::
+
list(INSERT <list> <element_index> <element> [<element> ...])
+
+Inserts elements to the list to the specified location.
+
+REMOVE_ITEM
+"""""""""""
+
+::
+
list(REMOVE_ITEM <list> <value> [<value> ...])
+
+Removes the given items from the list.
+
+REMOVE_AT
+"""""""""
+
+::
+
list(REMOVE_AT <list> <index> [<index> ...])
- list(REMOVE_DUPLICATES <list>)
- list(REVERSE <list>)
- list(SORT <list>)
-``LENGTH`` will return a given list's length.
+Removes items at given indices from the list.
-``GET`` will return list of elements specified by indices from the list.
+REMOVE_DUPLICATES
+"""""""""""""""""
-``APPEND`` will append elements to the list.
+::
-``FILTER`` will include or remove items from the list that match the
-mode's pattern.
-In ``REGEX`` mode, items will be matched against the given regular expression.
-For more information on regular expressions see also the :command:`string`
-command.
+ list(REMOVE_DUPLICATES <list>)
-``FIND`` will return the index of the element specified in the list or -1
-if it wasn't found.
+Removes duplicated items in the list.
-``INSERT`` will insert elements to the list to the specified location.
+Sorting
+^^^^^^^
-``REMOVE_AT`` and ``REMOVE_ITEM`` will remove items from the list. The
-difference is that ``REMOVE_ITEM`` will remove the given items, while
-``REMOVE_AT`` will remove the items at the given indices.
+REVERSE
+"""""""
-``REMOVE_DUPLICATES`` will remove duplicated items in the list.
+::
-``REVERSE`` reverses the contents of the list in-place.
+ list(REVERSE <list>)
-``SORT`` sorts the list in-place alphabetically.
+Reverses the contents of the list in-place.
+
+SORT
+""""
+
+::
+
+ list(SORT <list>)
-The list subcommands ``APPEND``, ``INSERT``, ``FILTER``, ``REMOVE_AT``,
-``REMOVE_ITEM``, ``REMOVE_DUPLICATES``, ``REVERSE`` and ``SORT`` may create new
-values for the list within the current CMake variable scope. Similar to the
-:command:`set` command, the LIST command creates new variable values in the
-current scope, even if the list itself is actually defined in a parent
-scope. To propagate the results of these operations upwards, use
-:command:`set` with ``PARENT_SCOPE``, :command:`set` with
-``CACHE INTERNAL``, or some other means of value propagation.
-NOTES: A list in cmake is a ``;`` separated group of strings. To create a
-list the set command can be used. For example, ``set(var a b c d e)``
-creates a list with ``a;b;c;d;e``, and ``set(var "a b c d e")`` creates a
-string or a list with one item in it. (Note macro arguments are not
-variables, and therefore cannot be used in LIST commands.)
-
-When specifying index values, if ``<element index>`` is 0 or greater, it
-is indexed from the beginning of the list, with 0 representing the
-first list element. If ``<element index>`` is -1 or lesser, it is indexed
-from the end of the list, with -1 representing the last list element.
-Be careful when counting with negative indices: they do not start from
-0. -0 is equivalent to 0, the first list element.
+Sorts the list in-place alphabetically.
diff --git a/Help/command/project.rst b/Help/command/project.rst
index ac71d7a..e46dd69 100644
--- a/Help/command/project.rst
+++ b/Help/command/project.rst
@@ -9,6 +9,7 @@ Sets project details such as name, version, etc. and enables languages.
project(<PROJECT-NAME>
[VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
[DESCRIPTION <project-description-string>]
+ [HOMEPAGE_URL <url-string>]
[LANGUAGES <language-name>...])
Sets the name of the project and stores the name in the
@@ -41,9 +42,18 @@ in variables
Variables corresponding to unspecified versions are set to the empty string
(if policy :policy:`CMP0048` is set to ``NEW``).
-If optional ``DESCRIPTION`` is given, then additional :variable:`PROJECT_DESCRIPTION`
-variable will be set to its argument. The argument must be a string with short
-description of the project (only a few words).
+If the optional ``DESCRIPTION`` is given, then :variable:`PROJECT_DESCRIPTION`
+and :variable:`<PROJECT-NAME>_DESCRIPTION` will be set to its argument.
+The description is expected to be a relatively short string, usually no more
+than a few words.
+
+The optional ``HOMEPAGE_URL`` sets the analogous variables
+:variable:`PROJECT_HOMEPAGE_URL` and :variable:`<PROJECT-NAME>_HOMEPAGE_URL`.
+When this option is given, the URL provided should be the canonical home for
+the project.
+
+Note that the description and homepage URL may be used as defaults for
+things like packaging meta-data, documentation, etc.
Optionally you can specify which languages your project supports.
Example languages include ``C``, ``CXX`` (i.e. C++), ``CUDA``,
@@ -64,9 +74,10 @@ literal, direct call to the :command:`project` command; loading one
through the :command:`include` command is not sufficient. If no such
call exists CMake will implicitly add one to the top that enables the
default languages (``C`` and ``CXX``). The name of the project set in
-the top level CMakeLists.txt file is available from the
-:variable:`CMAKE_PROJECT_NAME` variable and its description from
-:variable:`CMAKE_PROJECT_DESCRIPTION`.
+the top level ``CMakeLists.txt`` file is available from the
+:variable:`CMAKE_PROJECT_NAME` variable, its description from
+:variable:`CMAKE_PROJECT_DESCRIPTION` and its homepage URL from
+:variable:`CMAKE_PROJECT_HOMEPAGE_URL`.
.. note::
Call the :command:`cmake_minimum_required` command at the beginning
diff --git a/Help/command/set_property.rst b/Help/command/set_property.rst
index 5ed788e..c89e1ce 100644
--- a/Help/command/set_property.rst
+++ b/Help/command/set_property.rst
@@ -59,11 +59,17 @@ be one of the following:
The required ``PROPERTY`` option is immediately followed by the name of
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 append to any
-existing property value as string, i.e. it results in a longer string
-and not a list of strings.
+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
+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``
+behavior (see :command:`define_property`), no inheriting occurs when
+finding the initial value to append to. If the property is not already
+directly set in the nominated scope, the command will behave as though
+``APPEND`` or ``APPEND_STRING`` had not been given.
See the :manual:`cmake-properties(7)` manual for a list of properties
in each scope.
diff --git a/Help/command/set_target_properties.rst b/Help/command/set_target_properties.rst
index b894eac..7db952d 100644
--- a/Help/command/set_target_properties.rst
+++ b/Help/command/set_target_properties.rst
@@ -9,10 +9,12 @@ Targets can have properties that affect how they are built.
PROPERTIES prop1 value1
prop2 value2 ...)
-Set properties on a target. The syntax for the command is to list all
-the files you want to change, and then provide the values you want to
+Set properties on targets. The syntax for the command is to list all
+the targets you want to change, and then provide the values you want to
set next. You can use any prop value pair you want and extract it
later with the :command:`get_property` or :command:`get_target_property`
command.
+See also the :command:`set_property(TARGET)` command.
+
See :ref:`Target Properties` for the list of properties known to CMake.
diff --git a/Help/command/string.rst b/Help/command/string.rst
index cd94bb4..bb07d29 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -161,6 +161,10 @@ JOIN
Join all the input arguments together using the glue
string and store the result in the named output variable.
+To join list's elements, use preferably the ``JOIN`` operator
+from :command:`list` command. This allows for the elements to have
+special characters like ``;`` in them.
+
TOLOWER
"""""""
diff --git a/Help/command/target_compile_definitions.rst b/Help/command/target_compile_definitions.rst
index 3709e7a..a740117 100644
--- a/Help/command/target_compile_definitions.rst
+++ b/Help/command/target_compile_definitions.rst
@@ -27,3 +27,13 @@ Arguments to ``target_compile_definitions`` may use "generator expressions"
with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
manual for available expressions. See the :manual:`cmake-buildsystem(7)`
manual for more on defining buildsystem properties.
+
+Any leading ``-D`` on an item will be removed. Empty items are ignored.
+For example, the following are all equivalent:
+
+.. code-block:: cmake
+
+ target_compile_definitions(foo PUBLIC FOO)
+ target_compile_definitions(foo PUBLIC -DFOO) # -D removed
+ target_compile_definitions(foo PUBLIC "" FOO) # "" ignored
+ target_compile_definitions(foo PUBLIC -D FOO) # -D becomes "", then ignored
diff --git a/Help/manual/cmake-compile-features.7.rst b/Help/manual/cmake-compile-features.7.rst
index 0124395..e9495c6 100644
--- a/Help/manual/cmake-compile-features.7.rst
+++ b/Help/manual/cmake-compile-features.7.rst
@@ -335,7 +335,7 @@ versions specified for each:
* ``Clang``: Clang compiler versions 2.9 through 3.4.
* ``GNU``: GNU compiler versions 4.4 through 5.0.
* ``MSVC``: Microsoft Visual Studio versions 2010 through 2017.
-* ``SunPro``: Oracle SolarisStudio versions 12.4 through 12.5.
+* ``SunPro``: Oracle SolarisStudio versions 12.4 through 12.6.
* ``Intel``: Intel compiler versions 12.1 through 17.0.
CMake is currently aware of the :prop_tgt:`C standards <C_STANDARD>`
diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst
index 41fe90c..32e8cfc 100644
--- a/Help/manual/cmake-developer.7.rst
+++ b/Help/manual/cmake-developer.7.rst
@@ -644,6 +644,8 @@ Documentation`_ section above.
+.. _`CMake Developer Standard Variable Names`:
+
Standard Variable Names
^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst
index 694bae5..070c6ed 100644
--- a/Help/manual/cmake-modules.7.rst
+++ b/Help/manual/cmake-modules.7.rst
@@ -196,6 +196,9 @@ All Modules
/module/FindPostgreSQL
/module/FindProducer
/module/FindProtobuf
+ /module/FindPython
+ /module/FindPython2
+ /module/FindPython3
/module/FindPythonInterp
/module/FindPythonLibs
/module/FindQt3
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 254656a..7e2255d 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.12
.. toctree::
:maxdepth: 1
+ CMP0074: find_package uses PackageName_ROOT variables. </policy/CMP0074>
CMP0073: Do not produce legacy _LIB_DEPENDS cache entries. </policy/CMP0073>
Policies Introduced by CMake 3.11
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 9d4a7e8..7ace270 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -176,6 +176,7 @@ Properties on Targets
/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD_CONFIG
/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD
/prop_tgt/EXPORT_NAME
+ /prop_tgt/EXPORT_PROPERTIES
/prop_tgt/FOLDER
/prop_tgt/Fortran_FORMAT
/prop_tgt/Fortran_MODULE_DIRECTORY
@@ -296,6 +297,7 @@ Properties on Targets
/prop_tgt/VISIBILITY_INLINES_HIDDEN
/prop_tgt/VS_CONFIGURATION_TYPE
/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY
+ /prop_tgt/VS_DEBUGGER_COMMAND
/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION
/prop_tgt/VS_DOTNET_REFERENCE_refname
/prop_tgt/VS_DOTNET_REFERENCEPROP_refname_TAG_tagname
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 13a72df..0cb90d4 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -67,6 +67,7 @@ Variables that Provide Information
/variable/CMAKE_PARENT_LIST_FILE
/variable/CMAKE_PATCH_VERSION
/variable/CMAKE_PROJECT_DESCRIPTION
+ /variable/CMAKE_PROJECT_HOMEPAGE_URL
/variable/CMAKE_PROJECT_NAME
/variable/CMAKE_RANLIB
/variable/CMAKE_ROOT
@@ -97,6 +98,8 @@ Variables that Provide Information
/variable/CMAKE_XCODE_GENERATE_SCHEME
/variable/CMAKE_XCODE_PLATFORM_TOOLSET
/variable/PROJECT-NAME_BINARY_DIR
+ /variable/PROJECT-NAME_DESCRIPTION
+ /variable/PROJECT-NAME_HOMEPAGE_URL
/variable/PROJECT-NAME_SOURCE_DIR
/variable/PROJECT-NAME_VERSION
/variable/PROJECT-NAME_VERSION_MAJOR
@@ -105,6 +108,7 @@ Variables that Provide Information
/variable/PROJECT-NAME_VERSION_TWEAK
/variable/PROJECT_BINARY_DIR
/variable/PROJECT_DESCRIPTION
+ /variable/PROJECT_HOMEPAGE_URL
/variable/PROJECT_NAME
/variable/PROJECT_SOURCE_DIR
/variable/PROJECT_VERSION
diff --git a/Help/module/FindPython.rst b/Help/module/FindPython.rst
new file mode 100644
index 0000000..057a350
--- /dev/null
+++ b/Help/module/FindPython.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindPython.cmake
diff --git a/Help/module/FindPython2.rst b/Help/module/FindPython2.rst
new file mode 100644
index 0000000..1696bed
--- /dev/null
+++ b/Help/module/FindPython2.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindPython2.cmake
diff --git a/Help/module/FindPython3.rst b/Help/module/FindPython3.rst
new file mode 100644
index 0000000..e530ab8
--- /dev/null
+++ b/Help/module/FindPython3.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindPython3.cmake
diff --git a/Help/policy/CMP0074.rst b/Help/policy/CMP0074.rst
new file mode 100644
index 0000000..ffac4a7
--- /dev/null
+++ b/Help/policy/CMP0074.rst
@@ -0,0 +1,22 @@
+CMP0074
+-------
+
+:command:`find_package` uses ``PackageName_ROOT`` variables.
+
+In CMake 3.12 and above the ``find_package(PackageName)`` command now searches
+a prefix specified by a ``PackageName_ROOT`` CMake or environment variable.
+Package roots are maintained as a stack so nested calls to all ``find_*``
+commands inside find modules also search the roots as prefixes. This policy
+provides compatibility with projects that have not been updated to avoid using
+``PackageName_ROOT`` variables for other purposes.
+
+The ``OLD`` behavior for this policy is to ignore ``PackageName_ROOT``
+variables. The ``NEW`` behavior for this policy is to use ``PackageName_ROOT``
+variables.
+
+This policy was introduced in CMake version 3.12. 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/EXPORT_PROPERTIES.rst b/Help/prop_tgt/EXPORT_PROPERTIES.rst
new file mode 100644
index 0000000..bcf47a6
--- /dev/null
+++ b/Help/prop_tgt/EXPORT_PROPERTIES.rst
@@ -0,0 +1,14 @@
+EXPORT_PROPERTIES
+-----------------
+
+List additional properties to export for a target.
+
+This property contains a list of property names that should be exported by
+the :command:`install(EXPORT)` and :command:`export` commands. By default
+only a limited number of properties are exported. This property can be used
+to additionally export other properties as well.
+
+Properties starting with ``INTERFACE_`` or ``IMPORTED_`` are not allowed as
+they are reserved for internal CMake use.
+
+Properties containing generator expressions are also not allowed.
diff --git a/Help/prop_tgt/INSTALL_NAME_DIR.rst b/Help/prop_tgt/INSTALL_NAME_DIR.rst
index a67ec15..34348bb 100644
--- a/Help/prop_tgt/INSTALL_NAME_DIR.rst
+++ b/Help/prop_tgt/INSTALL_NAME_DIR.rst
@@ -6,3 +6,7 @@ Mac OSX directory name for installed targets.
INSTALL_NAME_DIR is a string specifying the directory portion of the
"install_name" field of shared libraries on Mac OSX to use in the
installed targets.
+
+This property is initialized by the value of the variable
+:variable:`CMAKE_INSTALL_NAME_DIR` if it is set when a target is
+created.
diff --git a/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst b/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst
new file mode 100644
index 0000000..f898750
--- /dev/null
+++ b/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst
@@ -0,0 +1,9 @@
+VS_DEBUGGER_COMMAND
+-------------------
+
+Sets the local debugger command for Visual Studio C++ targets.
+This is defined in ``<LocalDebuggerCommand>`` in the Visual Studio
+project file.
+
+This property only works for Visual Studio 2010 and above;
+it is ignored on other generators.
diff --git a/Help/release/dev/FindPython-new-implementation.rst b/Help/release/dev/FindPython-new-implementation.rst
new file mode 100644
index 0000000..22051d0
--- /dev/null
+++ b/Help/release/dev/FindPython-new-implementation.rst
@@ -0,0 +1,5 @@
+FindPython(2|3)
+---------------
+
+* The new :module:`FindPython3` and :module:`FindPython2` modules, as well as
+ :module:`FindPython`, provide a new way to locate python environments.
diff --git a/Help/release/dev/export-properties.rst b/Help/release/dev/export-properties.rst
new file mode 100644
index 0000000..9b20799
--- /dev/null
+++ b/Help/release/dev/export-properties.rst
@@ -0,0 +1,6 @@
+EXPORT_PROPERTIES
+-----------------
+
+* An :prop_tgt:`EXPORT_PROPERTIES` target property was added to specify a
+ custom list of target properties to include in targets exported by the
+ :command:`install(EXPORT)` and :command:`export` commands.
diff --git a/Help/release/dev/find-package_root-restore.rst b/Help/release/dev/find-package_root-restore.rst
new file mode 100644
index 0000000..3e6b69e
--- /dev/null
+++ b/Help/release/dev/find-package_root-restore.rst
@@ -0,0 +1,8 @@
+find-package_root-restore
+-------------------------
+
+* The :command:`find_package` command now searches a prefix specified by
+ a ``PackageName_ROOT`` CMake or environment variable. Package roots are
+ maintained as a stack so nested calls to all ``find_*`` commands inside
+ find modules also search the roots as prefixes.
+ See policy :policy:`CMP0074`.
diff --git a/Help/release/dev/list-join.rst b/Help/release/dev/list-join.rst
new file mode 100644
index 0000000..0756b60
--- /dev/null
+++ b/Help/release/dev/list-join.rst
@@ -0,0 +1,5 @@
+list-join
+---------
+
+* The :command:`list` command learned a ``JOIN`` sub-command
+ to concatenate list's elements separated by a glue string.
diff --git a/Help/release/dev/project-homepage.rst b/Help/release/dev/project-homepage.rst
new file mode 100644
index 0000000..25799a4
--- /dev/null
+++ b/Help/release/dev/project-homepage.rst
@@ -0,0 +1,7 @@
+project-homepage
+----------------
+
+* The :command:`project` command learned an optional ``HOMEPAGE_URL``
+ parameter which has the effect of setting variables like
+ :variable:`PROJECT_HOMEPAGE_URL`, :variable:`<PROJECT-NAME>_HOMEPAGE_URL`
+ and :variable:`CMAKE_PROJECT_HOMEPAGE_URL`.
diff --git a/Help/release/dev/vs-debugger-config.rst b/Help/release/dev/vs-debugger-config.rst
new file mode 100644
index 0000000..bddae0c
--- /dev/null
+++ b/Help/release/dev/vs-debugger-config.rst
@@ -0,0 +1,6 @@
+vs-debugger-configuration
+-------------------------
+
+* For the :ref:`Visual Studio Generators` for VS 2010 and above
+ the debugging command line can be set using a new
+ :prop_tgt:`VS_DEBUGGER_COMMAND` target property.
diff --git a/Help/variable/CMAKE_PROJECT_DESCRIPTION.rst b/Help/variable/CMAKE_PROJECT_DESCRIPTION.rst
index 6db5b9e..51b0592 100644
--- a/Help/variable/CMAKE_PROJECT_DESCRIPTION.rst
+++ b/Help/variable/CMAKE_PROJECT_DESCRIPTION.rst
@@ -7,7 +7,7 @@ This variable holds the description of the project as specified in the top
level CMakeLists.txt file by a :command:`project` command. In the event that
the top level CMakeLists.txt contains multiple :command:`project` calls,
the most recently called one from that top level CMakeLists.txt will determine
-the name that ``CMAKE_PROJECT_DESCRIPTION`` contains. For example, consider
+the value that ``CMAKE_PROJECT_DESCRIPTION`` contains. For example, consider
the following top level CMakeLists.txt:
.. code-block:: cmake
diff --git a/Help/variable/CMAKE_PROJECT_HOMEPAGE_URL.rst b/Help/variable/CMAKE_PROJECT_HOMEPAGE_URL.rst
new file mode 100644
index 0000000..ee0bf7c
--- /dev/null
+++ b/Help/variable/CMAKE_PROJECT_HOMEPAGE_URL.rst
@@ -0,0 +1,35 @@
+CMAKE_PROJECT_HOMEPAGE_URL
+--------------------------
+
+The homepage URL of the top level project.
+
+This variable holds the homepage URL of the project as specified in the top
+level CMakeLists.txt file by a :command:`project` command. In the event that
+the top level CMakeLists.txt contains multiple :command:`project` calls,
+the most recently called one from that top level CMakeLists.txt will determine
+the value that ``CMAKE_PROJECT_HOMEPAGE_URL`` contains. For example, consider
+the following top level CMakeLists.txt:
+
+.. code-block:: cmake
+
+ cmake_minimum_required(VERSION 3.0)
+ project(First HOMEPAGE_URL "http://first.example.com")
+ project(Second HOMEPAGE_URL "http://second.example.com")
+ add_subdirectory(sub)
+ project(Third HOMEPAGE_URL "http://third.example.com")
+
+And ``sub/CMakeLists.txt`` with the following contents:
+
+.. code-block:: cmake
+
+ project(SubProj HOMEPAGE_URL "http://subproj.example.com")
+ message("CMAKE_PROJECT_HOMEPAGE_URL = ${CMAKE_PROJECT_HOMEPAGE_URL}")
+
+The most recently seen :command:`project` command from the top level
+CMakeLists.txt would be ``project(Second ...)``, so this will print::
+
+ CMAKE_PROJECT_HOMEPAGE_URL = http://second.example.com
+
+To obtain the homepage URL from the most recent call to :command:`project` in
+the current directory scope or above, see the :variable:`PROJECT_HOMEPAGE_URL`
+variable.
diff --git a/Help/variable/PROJECT-NAME_DESCRIPTION.rst b/Help/variable/PROJECT-NAME_DESCRIPTION.rst
new file mode 100644
index 0000000..2b88b1a
--- /dev/null
+++ b/Help/variable/PROJECT-NAME_DESCRIPTION.rst
@@ -0,0 +1,5 @@
+<PROJECT-NAME>_DESCRIPTION
+--------------------------
+
+Value given to the ``DESCRIPTION`` option of the most recent call to the
+:command:`project` command with project name ``<PROJECT-NAME>``, if any.
diff --git a/Help/variable/PROJECT-NAME_HOMEPAGE_URL.rst b/Help/variable/PROJECT-NAME_HOMEPAGE_URL.rst
new file mode 100644
index 0000000..22cc304
--- /dev/null
+++ b/Help/variable/PROJECT-NAME_HOMEPAGE_URL.rst
@@ -0,0 +1,5 @@
+<PROJECT-NAME>_HOMEPAGE_URL
+---------------------------
+
+Value given to the ``HOMEPAGE_URL`` option of the most recent call to the
+:command:`project` command with project name ``<PROJECT-NAME>``, if any.
diff --git a/Help/variable/PROJECT_HOMEPAGE_URL.rst b/Help/variable/PROJECT_HOMEPAGE_URL.rst
new file mode 100644
index 0000000..754c9e8
--- /dev/null
+++ b/Help/variable/PROJECT_HOMEPAGE_URL.rst
@@ -0,0 +1,9 @@
+PROJECT_HOMEPAGE_URL
+--------------------
+
+The homepage URL of the project.
+
+This is the homepage URL given to the most recently called :command:`project`
+command in the current directory scope or above. To obtain the homepage URL
+of the top level project, see the :variable:`CMAKE_PROJECT_HOMEPAGE_URL`
+variable.
diff --git a/Modules/CPackDeb.cmake b/Modules/CPackDeb.cmake
index 35447c9..444f632 100644
--- a/Modules/CPackDeb.cmake
+++ b/Modules/CPackDeb.cmake
@@ -254,7 +254,7 @@
# upstream documentation or information may be found.
#
# * Mandatory : NO
-# * Default : -
+# * Default : :variable:`CMAKE_PROJECT_HOMEPAGE_URL`
#
# .. note::
#
@@ -914,6 +914,11 @@ function(cpack_deb_prepare_package_vars)
endif()
endif()
+ # Homepage: (optional)
+ if(NOT CPACK_DEBIAN_PACKAGE_HOMEPAGE AND CMAKE_PROJECT_HOMEPAGE_URL)
+ set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "${CMAKE_PROJECT_HOMEPAGE_URL}")
+ endif()
+
# Section: (recommended)
if(NOT CPACK_DEBIAN_PACKAGE_SECTION)
set(CPACK_DEBIAN_PACKAGE_SECTION "devel")
diff --git a/Modules/CPackFreeBSD.cmake b/Modules/CPackFreeBSD.cmake
index 7fec78a..b681d4f 100644
--- a/Modules/CPackFreeBSD.cmake
+++ b/Modules/CPackFreeBSD.cmake
@@ -80,7 +80,8 @@ the RPM information (e.g. package license).
* Mandatory: YES
* Default:
- - :variable:`CPACK_DEBIAN_PACKAGE_HOMEPAGE` (this may be set already
+ - :variable:`CMAKE_PROJECT_HOMEPAGE_URL`, or if that is not set,
+ :variable:`CPACK_DEBIAN_PACKAGE_HOMEPAGE` (this may be set already
for Debian packaging, so we may as well re-use it).
.. variable:: CPACK_FREEBSD_PACKAGE_LICENSE
@@ -208,6 +209,7 @@ _cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_DESCRIPTION"
# There's really only one homepage for a project, so
# re-use the Debian setting if it's there.
_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_WWW"
+ "CMAKE_PROJECT_HOMEPAGE_URL"
"CPACK_DEBIAN_PACKAGE_HOMEPAGE"
"_cpack_freebsd_fallback_www"
)
diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake
index 258922c..87385de 100644
--- a/Modules/CPackRPM.cmake
+++ b/Modules/CPackRPM.cmake
@@ -191,7 +191,7 @@
# The projects URL.
#
# * Mandatory : NO
-# * Default : -
+# * Default : :variable:`CMAKE_PROJECT_HOMEPAGE_URL`
#
# .. variable:: CPACK_RPM_PACKAGE_DESCRIPTION
# CPACK_RPM_<component>_PACKAGE_DESCRIPTION
@@ -1787,6 +1787,10 @@ function(cpack_rpm_generate_package)
endif()
endif()
+ if(NOT CPACK_RPM_PACKAGE_URL AND CMAKE_PROJECT_HOMEPAGE_URL)
+ set(CPACK_RPM_PACKAGE_URL "${CMAKE_PROJECT_HOMEPAGE_URL}")
+ endif()
+
# CPACK_RPM_PACKAGE_NAME (mandatory)
if(NOT CPACK_RPM_PACKAGE_NAME)
string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_NAME)
diff --git a/Modules/Compiler/Intel-CXX-FeatureTests.cmake b/Modules/Compiler/Intel-CXX-FeatureTests.cmake
index 929a7c6..bbefe15 100644
--- a/Modules/Compiler/Intel-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/Intel-CXX-FeatureTests.cmake
@@ -31,11 +31,6 @@ set(_cmake_feature_test_cxx_aggregate_default_initializers "${Intel16_CXX14}")
set(_cmake_feature_test_cxx_contextual_conversions "${Intel16_CXX14}")
set(_cmake_feature_test_cxx_generic_lambdas "__cpp_generic_lambdas >= 201304")
set(_cmake_feature_test_cxx_digit_separators "${Intel16_CXX14}")
-# This test is supposed to work in Intel 14 but the compiler has a bug
-# in versions 14 and 15::
-# https://software.intel.com/en-us/forums/intel-c-compiler/topic/600514
-# It also appears to fail with an internal compiler error on Intel 16 and 17.
-#set(_cmake_feature_test_cxx_generalized_initializers "${Intel16_CXX14}")
unset(Intel16_CXX14)
set(Intel15 "__INTEL_COMPILER >= 1500")
@@ -75,6 +70,7 @@ set(_cmake_feature_test_cxx_override "${Intel14_CXX11}")
set(_cmake_feature_test_cxx_final "${Intel14_CXX11}")
set(_cmake_feature_test_cxx_noexcept "${Intel14_CXX11}")
set(_cmake_feature_test_cxx_defaulted_move_initializers "${Intel14_CXX11}")
+set(_cmake_feature_test_cxx_generalized_initializers "${Intel14_CXX11}")
unset(Intel14_CXX11)
set(Intel13_CXX11 "__INTEL_COMPILER >= 1300 && ${DETECT_CXX11}")
diff --git a/Modules/Compiler/SunPro-CXX-FeatureTests.cmake b/Modules/Compiler/SunPro-CXX-FeatureTests.cmake
index 60280ca..279d875 100644
--- a/Modules/Compiler/SunPro-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/SunPro-CXX-FeatureTests.cmake
@@ -1,10 +1,14 @@
# Based on GNU 4.8.2
-# http://docs.oracle.com/cd/E37069_01/html/E37071/gncix.html
+# https://docs.oracle.com/cd/E37069_01/html/E37071/gncix.html
+# https://docs.oracle.com/cd/E77782_01/html/E77784/gkeza.html
# Reference: http://gcc.gnu.org/projects/cxx0x.html
set(_cmake_oldestSupported "__SUNPRO_CC >= 0x5130")
+set(SolarisStudio126_CXX11 "(__SUNPRO_CC >= 0x5150) && __cplusplus >= 201103L")
+set(_cmake_feature_test_cxx_decltype_auto "${SolarisStudio126_CXX11}")
+
set(SolarisStudio125_CXX11 "(__SUNPRO_CC >= 0x5140) && __cplusplus >= 201103L")
set(_cmake_feature_test_cxx_binary_literals "${SolarisStudio125_CXX11}")
set(_cmake_feature_test_cxx_reference_qualified_functions "${SolarisStudio125_CXX11}")
diff --git a/Modules/FindCUDA/select_compute_arch.cmake b/Modules/FindCUDA/select_compute_arch.cmake
index b604a17..2a196c2 100644
--- a/Modules/FindCUDA/select_compute_arch.cmake
+++ b/Modules/FindCUDA/select_compute_arch.cmake
@@ -23,6 +23,12 @@ set(CUDA_KNOWN_GPU_ARCHITECTURES "Fermi" "Kepler" "Maxwell")
# This list will be used for CUDA_ARCH_NAME = Common option (enabled by default)
set(CUDA_COMMON_GPU_ARCHITECTURES "3.0" "3.5" "5.0")
+if(CMAKE_CUDA_COMPILER_LOADED) # CUDA as a language
+ if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
+ set(CUDA_VERSION "${CMAKE_CUDA_COMPILER_VERSION}")
+ endif()
+endif()
+
if (CUDA_VERSION VERSION_GREATER "6.5")
list(APPEND CUDA_KNOWN_GPU_ARCHITECTURES "Kepler+Tegra" "Kepler+Tesla" "Maxwell+Tegra")
list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "5.2")
@@ -49,7 +55,11 @@ endif()
#
function(CUDA_DETECT_INSTALLED_GPUS OUT_VARIABLE)
if(NOT CUDA_GPU_DETECT_OUTPUT)
- set(file ${PROJECT_BINARY_DIR}/detect_cuda_compute_capabilities.cpp)
+ if(CMAKE_CUDA_COMPILER_LOADED) # CUDA as a language
+ set(file "${PROJECT_BINARY_DIR}/detect_cuda_compute_capabilities.cu")
+ else()
+ set(file "${PROJECT_BINARY_DIR}/detect_cuda_compute_capabilities.cpp")
+ endif()
file(WRITE ${file} ""
"#include <cuda_runtime.h>\n"
@@ -68,10 +78,15 @@ function(CUDA_DETECT_INSTALLED_GPUS OUT_VARIABLE)
" return 0;\n"
"}\n")
- try_run(run_result compile_result ${PROJECT_BINARY_DIR} ${file}
- CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${CUDA_INCLUDE_DIRS}"
- LINK_LIBRARIES ${CUDA_LIBRARIES}
- RUN_OUTPUT_VARIABLE compute_capabilities)
+ if(CMAKE_CUDA_COMPILER_LOADED) # CUDA as a language
+ try_run(run_result compile_result ${PROJECT_BINARY_DIR} ${file}
+ RUN_OUTPUT_VARIABLE compute_capabilities)
+ else()
+ try_run(run_result compile_result ${PROJECT_BINARY_DIR} ${file}
+ CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${CUDA_INCLUDE_DIRS}"
+ LINK_LIBRARIES ${CUDA_LIBRARIES}
+ RUN_OUTPUT_VARIABLE compute_capabilities)
+ endif()
if(run_result EQUAL 0)
string(REPLACE "2.1" "2.1(2.0)" compute_capabilities "${compute_capabilities}")
diff --git a/Modules/FindCxxTest.cmake b/Modules/FindCxxTest.cmake
index 2aa5f6f..25454fd 100644
--- a/Modules/FindCxxTest.cmake
+++ b/Modules/FindCxxTest.cmake
@@ -196,7 +196,7 @@ if(NOT DEFINED CXXTEST_TESTGEN_ARGS)
set(CXXTEST_TESTGEN_ARGS --error-printer)
endif()
-find_package(PythonInterp QUIET)
+find_package(Python QUIET)
find_package(Perl QUIET)
find_path(CXXTEST_INCLUDE_DIR cxxtest/TestSuite.h)
@@ -206,17 +206,17 @@ find_program(CXXTEST_PYTHON_TESTGEN_EXECUTABLE
find_program(CXXTEST_PERL_TESTGEN_EXECUTABLE cxxtestgen.pl
PATHS ${CXXTEST_INCLUDE_DIR})
-if(PYTHONINTERP_FOUND OR PERL_FOUND)
+if(PYTHON_FOUND OR PERL_FOUND)
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
- if(PYTHONINTERP_FOUND AND (CXXTEST_USE_PYTHON OR NOT PERL_FOUND OR NOT DEFINED CXXTEST_USE_PYTHON))
+ if(PYTHON_FOUND AND (CXXTEST_USE_PYTHON OR NOT PERL_FOUND OR NOT DEFINED CXXTEST_USE_PYTHON))
set(CXXTEST_TESTGEN_EXECUTABLE ${CXXTEST_PYTHON_TESTGEN_EXECUTABLE})
execute_process(COMMAND ${CXXTEST_PYTHON_TESTGEN_EXECUTABLE} --version
OUTPUT_VARIABLE _CXXTEST_OUT ERROR_VARIABLE _CXXTEST_OUT RESULT_VARIABLE _CXXTEST_RESULT)
if(_CXXTEST_RESULT EQUAL 0)
set(CXXTEST_TESTGEN_INTERPRETER "")
else()
- set(CXXTEST_TESTGEN_INTERPRETER ${PYTHON_EXECUTABLE})
+ set(CXXTEST_TESTGEN_INTERPRETER ${Python_EXECUTABLE})
endif()
FIND_PACKAGE_HANDLE_STANDARD_ARGS(CxxTest DEFAULT_MSG
CXXTEST_INCLUDE_DIR CXXTEST_PYTHON_TESTGEN_EXECUTABLE)
diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake
new file mode 100644
index 0000000..c87f784
--- /dev/null
+++ b/Modules/FindPython.cmake
@@ -0,0 +1,180 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+FindPython
+----------
+
+Find Python interpreter, compiler and development environment (include
+directories and libraries).
+
+Three 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).
+
+If no ``COMPONENTS`` is specified, ``Interpreter`` is assumed.
+
+To ensure consistent versions between components ``Interpreter``, ``Compiler``
+and ``Development``, specify all components at the same time::
+
+ find_package (Python COMPONENTS Interpreter Development)
+
+This module looks preferably for version 3 of Python. If not found, version 2
+is searched.
+To manage concurrent versions 3 and 2 of Python, use :module:`FindPython3` and
+:module:`FindPython2` modules rather than this one.
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+This module defines the following :ref:`Imported Targets <Imported Targets>`:
+
+``Python::Interpreter``
+ Python interpreter. Target defined if component ``Interpreter`` is found.
+``Python::Compiler``
+ Python compiler. Target defined if component ``Compiler`` is found.
+``Python::Python``
+ Python library. Target defined if component ``Development`` is found.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module will set the following variables in your project
+(see :ref:`Standard Variable Names <CMake Developer Standard Variable Names>`):
+
+``Python_FOUND``
+ System has the Python requested components.
+``Python_Interpreter_FOUND``
+ System has the Python interpreter.
+``Python_EXECUTABLE``
+ Path to the Python interpreter.
+``Python_INTERPRETER_ID``
+ A short string unique to the interpreter. Possible values include:
+ * Python
+ * ActivePython
+ * Anaconda
+ * Canopy
+ * IronPython
+``Python_STDLIB``
+ Standard platform independent installation directory.
+
+ Information returned by
+ ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``.
+``Python_STDARCH``
+ Standard platform dependent installation directory.
+
+ Information returned by
+ ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``.
+``Python_SITELIB``
+ Third-party platform independent installation directory.
+
+ Information returned by
+ ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``.
+``Python_SITEARCH``
+ Third-party platform dependent installation directory.
+
+ Information returned by
+ ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``.
+``Python_Compiler_FOUND``
+ System has the Python compiler.
+``Python_COMPILER``
+ Path to the Python compiler. Only offered by IronPython.
+``Python_COMPILER_ID``
+ A short string unique to the compiler. Possible values include:
+ * IronPython
+``Python_Development_FOUND``
+ System has the Python development artifacts.
+``Python_INCLUDE_DIRS``
+ The Python include directories.
+``Python_LIBRARIES``
+ The Python libraries.
+``Python_LIBRARY_DIRS``
+ The Python library directories.
+``Python_RUNTIME_LIBRARY_DIRS``
+ The Python runtime library directories.
+``Python_VERSION``
+ Python version.
+``Python_VERSION_MAJOR``
+ Python major version.
+``Python_VERSION_MINOR``
+ Python minor version.
+``Python_VERSION_PATCH``
+ Python patch version.
+
+Hints
+^^^^^
+
+``Python_ROOT_DIR``
+ Define the root directory of a Python installation.
+
+``Python_USE_STATIC_LIBS``
+ * If not defined, search for shared libraries and static libraries in that
+ order.
+ * If set to TRUE, search **only** for static libraries.
+ * If set to FALSE, search **only** for shared libraries.
+
+Commands
+^^^^^^^^
+
+This module defines the command ``Python_add_library`` which have the same
+semantic as :command:`add_library` but take care of Python module naming rules
+(only applied if library is of type ``MODULE``) and add dependency to target
+``Python::Python``::
+
+ Python_add_library (my_module MODULE src1.cpp)
+
+If library type is not specified, ``MODULE`` is assumed.
+#]=======================================================================]
+
+
+set (_PYTHON_PREFIX Python)
+
+if (DEFINED Python_FIND_VERSION)
+ set (_Python_REQUIRED_VERSION_MAJOR ${Python_FIND_VERSION_MAJOR})
+
+ include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake)
+else()
+ # iterate over versions in quiet and NOT required modes to avoid multiple
+ # "Found" messages and prematurally failure.
+ set (_Python_QUIETLY ${Python_FIND_QUIETLY})
+ set (_Python_REQUIRED ${Python_FIND_REQUIRED})
+ set (Python_FIND_QUIETLY TRUE)
+ set (Python_FIND_REQUIRED FALSE)
+
+ foreach (_Python_REQUIRED_VERSION_MAJOR IN ITEMS 3 2)
+ set (Python_FIND_VERSION ${_Python_REQUIRED_VERSION_MAJOR})
+ include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake)
+ if (Python_FOUND)
+ break()
+ endif()
+ # clean-up some CACHE variables to ensure look-up restart from scratch
+ foreach (_Python_ITEM IN ITEMS EXECUTABLE COMPILER
+ LIBRARY_RELEASE RUNTIME_LIBRARY_RELEASE
+ LIBRARY_DEBUG RUNTIME_LIBRARY_DEBUG
+ INCLUDE_DIR)
+ unset (Python_${_Python_ITEM} CACHE)
+ endforeach()
+ endforeach()
+
+ unset (Python_FIND_VERSION)
+
+ set (Python_FIND_QUIETLY ${_Python_QUIETLY})
+ set (Python_FIND_REQUIRED ${_Python_REQUIRED})
+ if (Python_FIND_REQUIRED OR NOT Python_FIND_QUIETLY)
+ # call again validation command to get "Found" or error message
+ find_package_handle_standard_args (Python HANDLE_COMPONENTS
+ REQUIRED_VARS ${_Python_REQUIRED_VARS}
+ VERSION_VAR Python_VERSION)
+ endif()
+endif()
+
+if (COMMAND __Python_add_library)
+ macro (Python_add_library)
+ __Python_add_library (Python ${ARGV})
+ endmacro()
+endif()
+
+unset (_PYTHON_PREFIX)
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
new file mode 100644
index 0000000..be34624
--- /dev/null
+++ b/Modules/FindPython/Support.cmake
@@ -0,0 +1,843 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#
+# This file is a "template" file used by various FindPython modules.
+#
+
+cmake_policy (VERSION 3.7)
+
+#
+# Initial configuration
+#
+if (NOT DEFINED _PYTHON_PREFIX)
+ message (FATAL_ERROR "FindPython: INTERNAL ERROR")
+endif()
+if (NOT DEFINED _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
+ message (FATAL_ERROR "FindPython: INTERNAL ERROR")
+endif()
+if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 3)
+ set(_${_PYTHON_PREFIX}_VERSIONS 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
+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")
+endif()
+
+
+#
+# helper commands
+#
+macro (_PYTHON_DISPLAY_FAILURE _PYTHON_MSG)
+ if (${_PYTHON_PREFIX}_FIND_REQUIRED)
+ message (FATAL_ERROR "${_PYTHON_MSG}")
+ else()
+ if (NOT ${_PYTHON_PREFIX}_FIND_QUIETLY)
+ message(STATUS "${_PYTHON_MSG}")
+ endif ()
+ endif()
+
+ set (${_PYTHON_PREFIX}_FOUND FALSE)
+ string (TOUPPER "${_PYTHON_PREFIX}" _${_PYTHON_PREFIX}_UPPER_PREFIX)
+ set (${_PYTHON_UPPER_PREFIX}_FOUND FALSE)
+ return()
+endmacro()
+
+
+function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS _PYTHON_VERSION)
+ set (_PYTHON_FRAMEWORK_PATHS)
+ foreach (_PYTHON_FRAMEWORK IN LISTS Python_FRAMEWORKS)
+ list (APPEND _PYTHON_FRAMEWORK_PATHS
+ "${_PYTHON_FRAMEWORK}/Versions/${_PYTHON_VERSION}")
+ endforeach()
+ set (${_PYTHON_PGF_FRAMEWORK_PATHS} ${_PYTHON_FRAMEWORK_PATHS} PARENT_SCOPE)
+endfunction()
+
+
+function (_PYTHON_FIND_RUNTIME_LIBRARY _PYTHON_LIB)
+ string (REPLACE "_RUNTIME" "" _PYTHON_LIB "${_PYTHON_LIB}")
+ # look at runtime part on systems supporting it
+ if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR
+ (CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN"
+ AND ${_PYTHON_LIB} MATCHES "${CMAKE_IMPORT_LIBRARY_SUFFIX}$"))
+ set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX})
+ # MSYS has a special syntax for runtime libraries
+ if (CMAKE_SYSTEM_NAME MATCHES "MSYS")
+ list (APPEND CMAKE_FIND_LIBRARY_PREFIXES "msys-")
+ endif()
+ find_library (${ARGV})
+ endif()
+endfunction()
+
+
+function (_PYTHON_SET_LIBRARY_DIRS _PYTHON_SLD_RESULT)
+ unset (_PYTHON_DIRS)
+ set (_PYTHON_LIBS ${ARGV})
+ list (REMOVE_AT _PYTHON_LIBS 0)
+ foreach (_PYTHON_LIB IN LISTS _PYTHON_LIBS)
+ if (${_PYTHON_LIB})
+ get_filename_component (_PYTHON_DIR "${${_PYTHON_LIB}}" DIRECTORY)
+ list (APPEND _PYTHON_DIRS "${_PYTHON_DIR}")
+ endif()
+ endforeach()
+ if (_PYTHON_DIRS)
+ list (REMOVE_DUPLICATES _PYTHON_DIRS)
+ endif()
+ set (${_PYTHON_SLD_RESULT} ${_PYTHON_DIRS} PARENT_SCOPE)
+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)
+ _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong major version specified is \"${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}\", but expected major version is \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"")
+endif()
+
+
+# handle components
+if (NOT ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ set (${_PYTHON_PREFIX}_FIND_COMPONENTS Interpreter)
+ set (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter TRUE)
+endif()
+foreach (_${_PYTHON_PREFIX}_COMPONENT IN LISTS ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE)
+endforeach()
+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_EXACT)
+ set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR})
+ else()
+ unset (_${_PYTHON_PREFIX}_FIND_VERSIONS)
+ # add all compatible versions
+ foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_VERSIONS)
+ if (_${_PYTHON_PREFIX}_VERSION VERSION_GREATER_EQUAL ${_PYTHON_PREFIX}_FIND_VERSION)
+ list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSION})
+ endif()
+ endforeach()
+ endif()
+endif()
+
+# Anaconda distribution: define which architectures can be used
+if (CMAKE_SIZEOF_VOID_P)
+ # In this case, search only for 64bit or 32bit
+ math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8")
+ set (_${_PYTHON_PREFIX}_ARCH2 ${_${_PYTHON_PREFIX}_ARCH})
+else()
+ # architecture unknown, search for both 64bit and 32bit
+ set (_${_PYTHON_PREFIX}_ARCH 64)
+ set (_${_PYTHON_PREFIX}_ARCH2 32)
+endif()
+
+# IronPython support
+if (CMAKE_SIZEOF_VOID_P)
+ # In this case, search only for 64bit or 32bit
+ math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8")
+ set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy${_${_PYTHON_PREFIX}_ARCH} ipy)
+else()
+ # architecture unknown, search for natural interpreter
+ set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy)
+endif()
+
+# Apple frameworks handling
+include (${CMAKE_CURRENT_LIST_DIR}/../CMakeFindFrameworks.cmake)
+cmake_find_frameworks (Python)
+
+# Save CMAKE_FIND_FRAMEWORK
+if (DEFINED CMAKE_FIND_FRAMEWORK)
+ set (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK})
+else()
+ unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK)
+endif()
+# To avoid picking up the system elements pre-maturely.
+set (CMAKE_FIND_FRAMEWORK LAST)
+
+
+unset (${_PYTHON_PREFIX}_VERSION_MAJOR)
+unset (${_PYTHON_PREFIX}_VERSION_MINOR)
+unset (${_PYTHON_PREFIX}_VERSION_PATCH)
+
+unset (_${_PYTHON_PREFIX}_REQUIRED_VARS)
+
+
+# first step, search for the interpreter
+if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter)
+ list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE)
+ endif()
+
+ set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
+
+ # look-up for various versions and locations
+ foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
+ string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION})
+
+ _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION})
+
+ # try using HINTS
+ find_program (${_PYTHON_PREFIX}_EXECUTABLE
+ NAMES python${_${_PYTHON_PREFIX}_VERSION}
+ NAMES_PER_DIR
+ HINTS ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ PATH_SUFFIXES bin
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+ # try using registry
+ if (WIN32)
+ find_program (${_PYTHON_PREFIX}_EXECUTABLE
+ NAMES python${_${_PYTHON_PREFIX}_VERSION} python
+ ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
+ NAMES_PER_DIR
+ HINTS ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
+ PATH_SUFFIXES bin
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+ endif()
+ # try in standard paths
+ find_program (${_PYTHON_PREFIX}_EXECUTABLE
+ NAMES python${_${_PYTHON_PREFIX}_VERSION})
+
+ if (${_PYTHON_PREFIX}_EXECUTABLE)
+ break()
+ endif()
+ endforeach()
+
+ # try more generic names
+ find_program (${_PYTHON_PREFIX}_EXECUTABLE
+ NAMES python${${_PYTHON_PREFIX}_VERSION_MAJOR} python
+ ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
+ HINTS ${_${_PYTHON_PREFIX}_HINTS}
+ PATH_SUFFIXES bin)
+
+ # retrieve exact version of executable found
+ if (${_PYTHON_PREFIX}_EXECUTABLE)
+ execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))"
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE ${_PYTHON_PREFIX}_VERSION
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (NOT _${_PYTHON_PREFIX}_RESULT)
+ string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${${_PYTHON_PREFIX}_VERSION}")
+ list (GET _${_PYTHON_PREFIX}_VERSIONS 0 ${_PYTHON_PREFIX}_VERSION_MAJOR)
+ list (GET _${_PYTHON_PREFIX}_VERSIONS 1 ${_PYTHON_PREFIX}_VERSION_MINOR)
+ list (GET _${_PYTHON_PREFIX}_VERSIONS 2 ${_PYTHON_PREFIX}_VERSION_PATCH)
+ else()
+ # Interpreter is not usable
+ set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE)
+ unset (${_PYTHON_PREFIX}_VERSION)
+ endif()
+ endif()
+
+ if (${_PYTHON_PREFIX}_EXECUTABLE
+ AND ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
+ set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE)
+ # Use interpreter version for future searchs to ensure consistency
+ set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR})
+ endif()
+
+ if (${_PYTHON_PREFIX}_Interpreter_FOUND)
+ # retrieve interpreter identity
+ execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -V
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID
+ ERROR_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID)
+ if (NOT _${_PYTHON_PREFIX}_RESULT)
+ if (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Anaconda")
+ set (${_PYTHON_PREFIX}_INTERPRETER_ID "Anaconda")
+ elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Enthought")
+ set (${_PYTHON_PREFIX}_INTERPRETER_ID "Canopy")
+ else()
+ string (REGEX REPLACE "^([^ ]+).*" "\\1" ${_PYTHON_PREFIX}_INTERPRETER_ID "${${_PYTHON_PREFIX}_INTERPRETER_ID}")
+ if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "Python")
+ # try to get a more precise ID
+ execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.copyright)"
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE ${_PYTHON_PREFIX}_COPYRIGHT
+ ERROR_QUIET)
+ if (${_PYTHON_PREFIX}_COPYRIGHT MATCHES "ActiveState")
+ set (${_PYTHON_PREFIX}_INTERPRETER_ID "ActivePython")
+ endif()
+ endif()
+ endif()
+ else()
+ set (${_PYTHON_PREFIX}_INTERPRETER_ID Python)
+ endif()
+ else()
+ unset (${_PYTHON_PREFIX}_INTERPRETER_ID)
+ endif()
+
+ # retrieve various package installation directories
+ execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))"
+
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS
+ ERROR_QUIET)
+ if (NOT _${_PYTHON_PREFIX}_RESULT)
+ list (GET _${_PYTHON_PREFIX}_LIBPATHS 0 ${_PYTHON_PREFIX}_STDLIB)
+ list (GET _${_PYTHON_PREFIX}_LIBPATHS 1 ${_PYTHON_PREFIX}_STDARCH)
+ list (GET _${_PYTHON_PREFIX}_LIBPATHS 2 ${_PYTHON_PREFIX}_SITELIB)
+ list (GET _${_PYTHON_PREFIX}_LIBPATHS 3 ${_PYTHON_PREFIX}_SITEARCH)
+ else()
+ unset (${_PYTHON_PREFIX}_STDLIB)
+ unset (${_PYTHON_PREFIX}_STDARCH)
+ unset (${_PYTHON_PREFIX}_SITELIB)
+ unset (${_PYTHON_PREFIX}_SITEARCH)
+ endif()
+
+ mark_as_advanced (${_PYTHON_PREFIX}_EXECUTABLE)
+endif()
+
+
+# second step, search for compiler (IronPython)
+if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ if (${_PYTHON_PREFIX}_FIND_REQUIRED_Compiler)
+ list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_COMPILER)
+ endif()
+
+ # IronPython specific artifacts
+ # If IronPython interpreter is found, use its path
+ unset (_${_PYTHON_PREFIX}_IRON_ROOT)
+ if (${_PYTHON_PREFIX}_Interpreter_FOUND AND ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython")
+ get_filename_component (_${_PYTHON_PREFIX}_IRON_ROOT "${${_PYTHON_PREFIX}_EXECUTABLE}" DIRECTORY)
+ endif()
+
+ # try using root dir and registry
+ foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
+ find_program (${_PYTHON_PREFIX}_COMPILER
+ NAMES ipyc
+ HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+ if (${_PYTHON_PREFIX}_COMPILER)
+ break()
+ endif()
+ endforeach()
+ # try in standard paths
+ find_program (${_PYTHON_PREFIX}_COMPILER
+ NAMES ipyc)
+
+ if (${_PYTHON_PREFIX}_COMPILER)
+ # retrieve python environment version from compiler
+ set (_${_PYTHON_PREFIX}_VERSION_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir")
+ file (WRITE "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))\n")
+ execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py"
+ WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}"
+ OUTPUT_QUIET
+ ERROR_QUIET)
+ execute_process (COMMAND "${_${_PYTHON_PREFIX}_VERSION_DIR}/version"
+ WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}"
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE _${_PYTHON_PREFIX}_VERSION
+ ERROR_QUIET)
+ if (NOT _${_PYTHON_PREFIX}_RESULT)
+ string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}")
+ list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR)
+ list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR)
+ list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH)
+
+ if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND)
+ # set public version information
+ set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION})
+ set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR})
+ set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR})
+ set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH})
+ endif()
+ else()
+ # compiler not usable
+ set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE)
+ endif()
+ file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}")
+ endif()
+
+ if (${_PYTHON_PREFIX}_COMPILER)
+ if (${_PYTHON_PREFIX}_Interpreter_FOUND)
+ # Compiler must be compatible with interpreter
+ if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR})
+ set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE)
+ endif()
+ elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
+ set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE)
+ # Use compiler version for future searchs to ensure consistency
+ set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR})
+ endif()
+ endif()
+
+ if (${_PYTHON_PREFIX}_Compiler_FOUND)
+ set (${_PYTHON_PREFIX}_COMPILER_ID IronPython)
+ else()
+ unset (${_PYTHON_PREFIX}_COMPILER_ID)
+ endif()
+
+ mark_as_advanced (${_PYTHON_PREFIX}_COMPILER)
+endif()
+
+
+# third step, search for the development artifacts
+## Development environment is not compatible with IronPython interpreter
+if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython")
+ if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development)
+ list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARY
+ ${_PYTHON_PREFIX}_INCLUDE_DIR)
+ endif()
+
+ # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
+ unset (_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES)
+ if (DEFINED ${_PYTHON_PREFIX}_USE_STATIC_LIBS AND NOT WIN32)
+ set(_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ if(${_PYTHON_PREFIX}_USE_STATIC_LIBS)
+ set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
+ else()
+ list (REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
+ endif()
+ else()
+ endif()
+
+ # if python interpreter is found, use its location and version to ensure consistency
+ # between interpreter and development environment
+ unset (_${_PYTHON_PREFIX}_PREFIX)
+ if (${_PYTHON_PREFIX}_Interpreter_FOUND)
+ execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.PREFIX)"
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (_${_PYTHON_PREFIX}_RESULT)
+ unset (_${_PYTHON_PREFIX}_PREFIX)
+ endif()
+ endif()
+ set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
+
+ foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
+ string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION})
+
+ # try to use pythonX.Y-config tool
+ find_program (_${_PYTHON_PREFIX}_CONFIG
+ NAMES python${_${_PYTHON_PREFIX}_VERSION}-config
+ HINTS ${_${_PYTHON_PREFIX}_HINTS}
+ PATH_SUFFIXES bin)
+
+ if (NOT _${_PYTHON_PREFIX}_CONFIG)
+ continue()
+ endif()
+
+ # retrieve root install directory
+ execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --prefix
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (_${_PYTHON_PREFIX}_RESULT)
+ # python-config is not usable
+ unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ continue()
+ endif()
+ set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
+
+ # retrieve library
+ execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (NOT _${_PYTHON_PREFIX}_RESULT)
+ # retrieve library directory
+ string (REGEX MATCHALL "-L[^ ]+" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_FLAGS}")
+ string (REPLACE "-L" "" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_LIB_DIRS}")
+ list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_DIRS)
+ # retrieve library name
+ string (REGEX MATCHALL "-lpython[^ ]+" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_FLAGS}")
+ string (REPLACE "-l" "" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_LIB_NAMES}")
+ list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_NAMES)
+
+ find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE
+ NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
+ NAMES_PER_DIR
+ HINTS ${_${_PYTHON_PREFIX}_HINTS} ${_${_PYTHON_PREFIX}_LIB_DIRS}
+ PATH_SUFFIXES lib
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+ # retrieve runtime library
+ if (${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+ get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
+ _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
+ NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
+ NAMES_PER_DIR
+ HINTS ${_${_PYTHON_PREFIX}_PATH} ${_${_PYTHON_PREFIX}_HINTS}
+ PATH_SUFFIXES bin
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+ endif()
+ endif()
+
+ # retrieve include directory
+ execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --includes
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (NOT _${_PYTHON_PREFIX}_RESULT)
+ # retrieve include directory
+ string (REGEX MATCHALL "-I[^ ]+" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_FLAGS}")
+ string (REPLACE "-I" "" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIRS}")
+ list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_DIRS)
+
+ find_path (${_PYTHON_PREFIX}_INCLUDE_DIR
+ NAMES Python.h
+ HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS}
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+ endif()
+
+ if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_INCLUDE_DIR)
+ break()
+ endif()
+ endforeach()
+
+ # Rely on HINTS and standard paths if config tool failed to locate artifacts
+ if (NOT (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) OR NOT ${_PYTHON_PREFIX}_INCLUDE_DIR)
+ foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
+ string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION})
+
+ _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION})
+
+ find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE
+ NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}
+ python${_${_PYTHON_PREFIX}_VERSION}mu
+ python${_${_PYTHON_PREFIX}_VERSION}m
+ python${_${_PYTHON_PREFIX}_VERSION}u
+ python${_${_PYTHON_PREFIX}_VERSION}
+ NAMES_PER_DIR
+ HINTS ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+ PATH_SUFFIXES lib libs
+ lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu
+ lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m
+ lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u
+ lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}
+ lib/python${_${_PYTHON_PREFIX}_VERSION}/config)
+ # retrieve runtime library
+ if (${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+ get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
+ _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
+ NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}
+ python${_${_PYTHON_PREFIX}_VERSION}mu
+ python${_${_PYTHON_PREFIX}_VERSION}m
+ python${_${_PYTHON_PREFIX}_VERSION}u
+ python${_${_PYTHON_PREFIX}_VERSION}
+ NAMES_PER_DIR
+ HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+ PATH_SUFFIXES bin)
+ endif()
+
+ if (WIN32)
+ # search for debug library
+ if (${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+ # use library location as a hint
+ get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
+ find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG
+ NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d
+ NAMES_PER_DIR
+ HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS}
+ NO_DEFAULT_PATH)
+ else()
+ find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG
+ NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d
+ NAMES_PER_DIR
+ HINTS ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+ PATH_SUFFIXES lib libs)
+ endif()
+ if (${_PYTHON_PREFIX}_LIBRARY_DEBUG)
+ get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY)
+ _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
+ NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d
+ NAMES_PER_DIR
+ HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+ PATH_SUFFIXES bin)
+ endif()
+ endif()
+
+ # Don't search for include dir until library location is known
+ if (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG)
+ unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS)
+ foreach (_${_PYTHON_PREFIX}_LIB IN ITEMS ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG)
+ if (${_${_PYTHON_PREFIX}_LIB})
+ # Use the library's install prefix as a hint
+ if (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)")
+ list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
+ elseif (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config")
+ list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
+ else()
+ # assume library is in a directory under root
+ get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${${_${_PYTHON_PREFIX}_LIB}}" DIRECTORY)
+ get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY)
+ list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}")
+ endif()
+ endif()
+ endforeach()
+ list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_HINTS)
+
+ find_path (${_PYTHON_PREFIX}_INCLUDE_DIR
+ NAMES Python.h
+ HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+ PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu
+ include/python${_${_PYTHON_PREFIX}_VERSION}m
+ include/python${_${_PYTHON_PREFIX}_VERSION}u
+ include/python${_${_PYTHON_PREFIX}_VERSION}
+ include
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+ endif()
+
+ if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) AND ${_PYTHON_PREFIX}_INCLUDE_DIR)
+ break()
+ endif()
+ endforeach()
+
+ # search header file in standard locations
+ find_path (${_PYTHON_PREFIX}_INCLUDE_DIR
+ NAMES Python.h)
+ endif()
+
+ if (${_PYTHON_PREFIX}_INCLUDE_DIR)
+ # retrieve version from header file
+ file (STRINGS "${${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" _${_PYTHON_PREFIX}_VERSION
+ REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"")
+ string (REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1"
+ _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_VERSION}")
+ string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}")
+ list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR)
+ list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR)
+ list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH)
+
+ if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT ${_PYTHON_PREFIX}_Compiler_FOUND)
+ # set public version information
+ set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION})
+ set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR})
+ set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR})
+ set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH})
+ endif()
+ endif()
+
+ # define public variables
+ include (${CMAKE_CURRENT_LIST_DIR}/../SelectLibraryConfigurations.cmake)
+ select_library_configurations (${_PYTHON_PREFIX})
+ if (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE)
+ set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
+ elseif (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
+ set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}")
+ else()
+ set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "$${_PYTHON_PREFIX}_RUNTIME_LIBRARY-NOTFOUND")
+ endif()
+
+ _python_set_library_dirs (${_PYTHON_PREFIX}_LIBRARY_DIRS
+ ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG)
+ if (UNIX)
+ if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$"
+ OR ${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$")
+ set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS})
+ endif()
+ else()
+ _python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS
+ ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
+ endif()
+
+ set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${${_PYTHON_PREFIX}_INCLUDE_DIR}")
+
+ mark_as_advanced (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
+ ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
+ ${_PYTHON_PREFIX}_INCLUDE_DIR)
+
+ if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG)
+ AND ${_PYTHON_PREFIX}_INCLUDE_DIR)
+ if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND)
+ # devlopment 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})
+ set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
+ endif()
+ elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
+ set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
+ endif()
+ endif()
+
+ # Restore the original find library ordering
+ if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES)
+ set (CMAKE_FIND_LIBRARY_SUFFIXES ${_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES})
+ endif()
+endif()
+
+# final validation
+if (${_PYTHON_PREFIX}_VERSION_MAJOR AND
+ NOT ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
+ _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Found unsuitable major version \"${${_PYTHON_PREFIX}_VERSION_MAJOR}\", but required major version is exact version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"")
+endif()
+
+include (${CMAKE_CURRENT_LIST_DIR}/../FindPackageHandleStandardArgs.cmake)
+find_package_handle_standard_args (${_PYTHON_PREFIX}
+ REQUIRED_VARS ${_${_PYTHON_PREFIX}_REQUIRED_VARS}
+ VERSION_VAR ${_PYTHON_PREFIX}_VERSION
+ HANDLE_COMPONENTS)
+
+# Create imported targets and helper functions
+if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ AND ${_PYTHON_PREFIX}_Interpreter_FOUND
+ AND NOT TARGET ${_PYTHON_PREFIX}::Interpreter)
+ add_executable (${_PYTHON_PREFIX}::Interpreter IMPORTED)
+ set_property (TARGET ${_PYTHON_PREFIX}::Interpreter
+ PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_EXECUTABLE}")
+endif()
+
+if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ AND ${_PYTHON_PREFIX}_Compiler_FOUND
+ AND NOT TARGET ${_PYTHON_PREFIX}::Compiler)
+ add_executable (${_PYTHON_PREFIX}::Compiler IMPORTED)
+ set_property (TARGET ${_PYTHON_PREFIX}::Compiler
+ PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_COMPILER}")
+endif()
+
+if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ AND ${_PYTHON_PREFIX}_Development_FOUND AND NOT TARGET ${_PYTHON_PREFIX}::Python)
+
+ if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$"
+ OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$"
+ OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
+ set (_${_PYTHON_PREFIX}_LIBRARY_TYPE SHARED)
+ else()
+ set (_${_PYTHON_PREFIX}_LIBRARY_TYPE STATIC)
+ endif()
+
+ add_library (${_PYTHON_PREFIX}::Python ${_${_PYTHON_PREFIX}_LIBRARY_TYPE} IMPORTED)
+
+ set_property (TARGET ${_PYTHON_PREFIX}::Python
+ PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIR}")
+
+ if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE)
+ OR (${_PYTHON_PREFIX}_LIBRARY_DEBUG AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG))
+ # System manage shared libraries in two parts: import and runtime
+ if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG)
+ set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG)
+ set_target_properties (${_PYTHON_PREFIX}::Python
+ PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
+ IMPORTED_IMPLIB_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}"
+ IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
+ set_target_properties (${_PYTHON_PREFIX}::Python
+ PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
+ IMPORTED_IMPLIB_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}"
+ IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}")
+ else()
+ set_target_properties (${_PYTHON_PREFIX}::Python
+ PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+ IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARY}"
+ IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY}")
+ endif()
+ else()
+ if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG)
+ set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG)
+ set_target_properties (${_PYTHON_PREFIX}::Python
+ PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
+ IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
+ set_target_properties (${_PYTHON_PREFIX}::Python
+ PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
+ IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}")
+ else()
+ set_target_properties (${_PYTHON_PREFIX}::Python
+ PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+ IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY}")
+ endif()
+ endif()
+
+ if (_${_PYTHON_PREFIX}_CONFIG AND _${_PYTHON_PREFIX}_LIBRARY_TYPE STREQUAL "STATIC")
+ # extend link information with dependent libraries
+ execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (NOT _${_PYTHON_PREFIX}_RESULT)
+ string (REGEX MATCHALL "-[Ll][^ ]+" _${_PYTHON_PREFIX}_LINK_LIBRARIES "${_${_PYTHON_PREFIX}_FLAGS}")
+ # remove elements relative to python library itself
+ list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-lpython")
+ foreach (_${_PYTHON_PREFIX}_DIR IN LISTS ${_PYTHON_PREFIX}_LIBRARY_DIRS)
+ list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-L${${_PYTHON_PREFIX}_DIR}")
+ endforeach()
+ set_property (TARGET ${_PYTHON_PREFIX}::Python
+ PROPERTY INTERFACE_LINK_LIBRARIES ${_${_PYTHON_PREFIX}_LINK_LIBRARIES})
+ endif()
+ endif()
+
+ #
+ # PYTHON_ADD_LIBRARY (<name> [STATIC|SHARED|MODULE] src1 src2 ... srcN)
+ # It is used to build modules for python.
+ #
+ function (__${_PYTHON_PREFIX}_ADD_LIBRARY prefix name)
+ cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY
+ "STATIC;SHARED;MODULE" "" "")
+
+ unset (type)
+ if (NOT (PYTHON_ADD_LIBRARY_STATIC
+ OR PYTHON_ADD_LIBRARY_SHARED
+ OR PYTHON_ADD_LIBRARY_MODULE))
+ set (type MODULE)
+ endif()
+ add_library (${name} ${type} ${ARGN})
+ target_link_libraries (${name} PRIVATE ${prefix}::Python)
+
+ # customize library name to follow module name rules
+ get_property (type TARGET ${name} PROPERTY TYPE)
+ if (type STREQUAL "MODULE_LIBRARY")
+ set_property (TARGET ${name} PROPERTY PREFIX "")
+ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
+ set_property (TARGET ${name} PROPERTY SUFFIX ".pyd")
+ endif()
+ endif()
+ endfunction()
+endif()
+
+# final clean-up
+
+# Restore CMAKE_FIND_FRAMEWORK
+if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK)
+ set (CMAKE_FIND_FRAMEWORK ${_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK})
+ unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK)
+else()
+ unset (CMAKE_FIND_FRAMEWORK)
+endif()
+
+unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake
new file mode 100644
index 0000000..22e9a8f
--- /dev/null
+++ b/Modules/FindPython2.cmake
@@ -0,0 +1,146 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+FindPython2
+-----------
+
+Find Python 2 interpreter, compiler and development environment (include
+directories and libraries).
+
+Three 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)
+
+If no ``COMPONENTS`` is specified, ``Interpreter`` is assumed.
+
+To ensure consistent versions between components ``Interpreter``, ``Compiler``
+and ``Development``, specify all components at the same time::
+
+ find_package (Python2 COMPONENTS Interpreter Development)
+
+This module looks only for version 2 of Python. This module can be used
+concurrently with :module:`FindPython3` module to use both Python versions.
+
+The :module:`FindPython` module can be used if Python version does not matter
+for you.
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+This module defines the following :ref:`Imported Targets <Imported Targets>`:
+
+``Python2::Interpreter``
+ 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. Target defined if component ``Development`` is found.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module will set the following variables in your project
+(see :ref:`Standard Variable Names <CMake Developer Standard Variable Names>`):
+
+``Python2_FOUND``
+ System has the Python 2 requested components.
+``Python2_Interpreter_FOUND``
+ System has the Python 2 interpreter.
+``Python2_EXECUTABLE``
+ Path to the Python 2 interpreter.
+``Python2_INTERPRETER_ID``
+ A short string unique to the interpreter. Possible values include:
+ * Python
+ * ActivePython
+ * Anaconda
+ * Canopy
+ * IronPython
+``Python2_STDLIB``
+ Standard platform independent installation directory.
+
+ Information returned by
+ ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``.
+``Python2_STDARCH``
+ Standard platform dependent installation directory.
+
+ Information returned by
+ ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``.
+``Python2_SITELIB``
+ Third-party platform independent installation directory.
+
+ Information returned by
+ ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``.
+``Python2_SITEARCH``
+ Third-party platform dependent installation directory.
+
+ Information returned by
+ ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``.
+``Python2_Compiler_FOUND``
+ System has the Python 2 compiler.
+``Python2_COMPILER``
+ Path to the Python 2 compiler. Only offered by IronPython.
+``Python2_COMPILER_ID``
+ A short string unique to the compiler. Possible values include:
+ * IronPython
+``Python2_Development_FOUND``
+ System has the Python 2 development artifacts.
+``Python2_INCLUDE_DIRS``
+ The Python 2 include directories.
+``Python2_LIBRARIES``
+ The Python 2 libraries.
+``Python2_LIBRARY_DIRS``
+ The Python 2 library directories.
+``Python2_RUNTIME_LIBRARY_DIRS``
+ The Python 2 runtime library directories.
+``Python2_VERSION``
+ Python 2 version.
+``Python2_VERSION_MAJOR``
+ Python 2 major version.
+``Python2_VERSION_MINOR``
+ Python 2 minor version.
+``Python2_VERSION_PATCH``
+ Python 2 patch version.
+
+Hints
+^^^^^
+
+``Python2_ROOT_DIR``
+ Define the root directory of a Python 2 installation.
+
+``Python2_USE_STATIC_LIBS``
+ * If not defined, search for shared libraries and static libraries in that
+ order.
+ * If set to TRUE, search **only** for static libraries.
+ * If set to FALSE, search **only** for shared libraries.
+
+Commands
+^^^^^^^^
+
+This module defines the command ``Python2_add_library`` which have the same
+semantic as :command:`add_library` but take care of Python module naming rules
+(only applied if library is of type ``MODULE``) and add dependency to target
+``Python2::Python``::
+
+ Python2_add_library (my_module MODULE src1.cpp)
+
+If library type is not specified, ``MODULE`` is assumed.
+#]=======================================================================]
+
+
+set (_PYTHON_PREFIX Python2)
+
+set (_Python2_REQUIRED_VERSION_MAJOR 2)
+
+include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake)
+
+if (COMMAND __Python2_add_library)
+ macro (Python2_add_library)
+ __Python2_add_library (Python2 ${ARGV})
+ endmacro()
+endif()
+
+unset (_PYTHON_PREFIX)
diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake
new file mode 100644
index 0000000..99c159b
--- /dev/null
+++ b/Modules/FindPython3.cmake
@@ -0,0 +1,146 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+FindPython3
+-----------
+
+Find Python 3 interpreter, compiler and development environment (include
+directories and libraries).
+
+Three 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)
+
+If no ``COMPONENTS`` is specified, ``Interpreter`` is assumed.
+
+To ensure consistent versions between components ``Interpreter``, ``Compiler``
+and ``Development``, specify all components at the same time::
+
+ find_package (Python3 COMPONENTS Interpreter Development)
+
+This module looks only for version 3 of Python. This module can be used
+concurrently with :module:`FindPython2` module to use both Python versions.
+
+The :module:`FindPython` module can be used if Python version does not matter
+for you.
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+This module defines the following :ref:`Imported Targets <Imported Targets>`:
+
+``Python3::Interpreter``
+ 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. Target defined if component ``Development`` is found.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module will set the following variables in your project
+(see :ref:`Standard Variable Names <CMake Developer Standard Variable Names>`):
+
+``Python3_FOUND``
+ System has the Python 3 requested components.
+``Python3_Interpreter_FOUND``
+ System has the Python 3 interpreter.
+``Python3_EXECUTABLE``
+ Path to the Python 3 interpreter.
+``Python3_INTERPRETER_ID``
+ A short string unique to the interpreter. Possible values include:
+ * Python
+ * ActivePython
+ * Anaconda
+ * Canopy
+ * IronPython
+``Python3_STDLIB``
+ Standard platform independent installation directory.
+
+ Information returned by
+ ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``.
+``Python3_STDARCH``
+ Standard platform dependent installation directory.
+
+ Information returned by
+ ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``.
+``Python3_SITELIB``
+ Third-party platform independent installation directory.
+
+ Information returned by
+ ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``.
+``Python3_SITEARCH``
+ Third-party platform dependent installation directory.
+
+ Information returned by
+ ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``.
+``Python3_Compiler_FOUND``
+ System has the Python 3 compiler.
+``Python3_COMPILER``
+ Path to the Python 3 compiler. Only offered by IronPython.
+``Python3_COMPILER_ID``
+ A short string unique to the compiler. Possible values include:
+ * IronPython
+``Python3_Development_FOUND``
+ System has the Python 3 development artifacts.
+``Python3_INCLUDE_DIRS``
+ The Python 3 include directories.
+``Python3_LIBRARIES``
+ The Python 3 libraries.
+``Python3_LIBRARY_DIRS``
+ The Python 3 library directories.
+``Python3_RUNTIME_LIBRARY_DIRS``
+ The Python 3 runtime library directories.
+``Python3_VERSION``
+ Python 3 version.
+``Python3_VERSION_MAJOR``
+ Python 3 major version.
+``Python3_VERSION_MINOR``
+ Python 3 minor version.
+``Python3_VERSION_PATCH``
+ Python 3 patch version.
+
+Hints
+^^^^^
+
+``Python3_ROOT_DIR``
+ Define the root directory of a Python 3 installation.
+
+``Python3_USE_STATIC_LIBS``
+ * If not defined, search for shared libraries and static libraries in that
+ order.
+ * If set to TRUE, search **only** for static libraries.
+ * If set to FALSE, search **only** for shared libraries.
+
+Commands
+^^^^^^^^
+
+This module defines the command ``Python3_add_library`` which have the same
+semantic as :command:`add_library` but take care of Python module naming rules
+(only applied if library is of type ``MODULE``) and add dependency to target
+``Python3::Python``::
+
+ Python3_add_library (my_module MODULE src1.cpp)
+
+If library type is not specified, ``MODULE`` is assumed.
+#]=======================================================================]
+
+
+set (_PYTHON_PREFIX Python3)
+
+set (_Python3_REQUIRED_VERSION_MAJOR 3)
+
+include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake)
+
+if (COMMAND __Python3_add_library)
+ macro (Python3_add_library)
+ __Python3_add_library (Python3 ${ARGV})
+ endmacro()
+endif()
+
+unset (_PYTHON_PREFIX)
diff --git a/Modules/FindPythonInterp.cmake b/Modules/FindPythonInterp.cmake
index 3ef8e9f..bd64762 100644
--- a/Modules/FindPythonInterp.cmake
+++ b/Modules/FindPythonInterp.cmake
@@ -7,6 +7,10 @@
#
# Find python interpreter
#
+# .. deprecated:: 3.12
+#
+# Use :module:`FindPython3`, :module:`FindPython2` or :module:`FindPython` instead.
+#
# This module finds if Python interpreter is installed and determines
# where the executables are. This code sets the following variables:
#
diff --git a/Modules/FindPythonLibs.cmake b/Modules/FindPythonLibs.cmake
index 341d5d9..1a0cc2e 100644
--- a/Modules/FindPythonLibs.cmake
+++ b/Modules/FindPythonLibs.cmake
@@ -7,6 +7,10 @@
#
# Find python libraries
#
+# .. deprecated:: 3.12
+#
+# Use :module:`FindPython3`, :module:`FindPython2` or :module:`FindPython` instead.
+#
# This module finds if Python is installed and determines where the
# include files and libraries are. It also determines what the name of
# the library is. This code sets the following variables:
diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake
index a65c533..5a7eadb 100644
--- a/Modules/FindQt4.cmake
+++ b/Modules/FindQt4.cmake
@@ -710,19 +710,13 @@ if (QT_QMAKE_EXECUTABLE AND
if (QT_LIBRARY_DIR AND NOT QT_PLUGINS_DIR OR QT_QMAKE_CHANGED)
_qt4_query_qmake(QT_INSTALL_PLUGINS qt_plugins_dir)
set(QT_PLUGINS_DIR NOTFOUND)
- set(qt_cross_paths)
foreach(qt_cross_path ${CMAKE_FIND_ROOT_PATH})
set(qt_cross_paths ${qt_cross_paths} "${qt_cross_path}/plugins")
endforeach()
- find_path(QT_PLUGINS_DIR
- NAMES accessible bearer codecs designer graphicssystems iconengines imageformats inputmethods qmltooling script sqldrivers
+ find_path(QT_PLUGINS_DIR NAMES accessible imageformats sqldrivers codecs designer
HINTS ${qt_cross_paths} ${qt_plugins_dir}
DOC "The location of the Qt plugins"
NO_CMAKE_FIND_ROOT_PATH)
- # If no plugins were installed, set QT_PLUGINS_DIR to ${qt_plugins_dir}
- if(NOT QT_PLUGINS_DIR AND qt_plugins_dir)
- set(QT_PLUGINS_DIR ${qt_plugins_dir} CACHE PATH "The location of the Qt plugins")
- endif()
endif ()
# ask qmake for the translations directory
@@ -736,7 +730,6 @@ if (QT_QMAKE_EXECUTABLE AND
_qt4_query_qmake(QT_INSTALL_IMPORTS qt_imports_dir)
if(qt_imports_dir)
set(QT_IMPORTS_DIR NOTFOUND)
- set(qt_cross_paths)
foreach(qt_cross_path ${CMAKE_FIND_ROOT_PATH})
set(qt_cross_paths ${qt_cross_paths} "${qt_cross_path}/imports")
endforeach()
@@ -746,10 +739,6 @@ if (QT_QMAKE_EXECUTABLE AND
NO_CMAKE_FIND_ROOT_PATH
NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
- # If the imports folder is empty, set QT_IMPORTS_DIR to ${qt_imports_dir}
- if(NOT QT_IMPORTS_DIR AND qt_imports_dir)
- set(QT_IMPORTS_DIR ${qt_imports_dir} CACHE PATH "The location of the Qt imports")
- endif()
mark_as_advanced(QT_IMPORTS_DIR)
endif()
endif ()
diff --git a/Modules/FindwxWidgets.cmake b/Modules/FindwxWidgets.cmake
index 965948e..202d481 100644
--- a/Modules/FindwxWidgets.cmake
+++ b/Modules/FindwxWidgets.cmake
@@ -498,17 +498,17 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
set(_WX_TOOL gcc)
elseif(MSVC)
set(_WX_TOOL vc)
- if(MSVC_VERSION EQUAL 1910)
+ if(NOT MSVC_VERSION LESS 1910)
set(_WX_TOOLVER 141)
- elseif(MSVC_VERSION EQUAL 1900)
+ elseif(NOT MSVC_VERSION LESS 1900)
set(_WX_TOOLVER 140)
- elseif(MSVC_VERSION EQUAL 1800)
+ elseif(NOT MSVC_VERSION LESS 1800)
set(_WX_TOOLVER 120)
- elseif(MSVC_VERSION EQUAL 1700)
+ elseif(NOT MSVC_VERSION LESS 1700)
set(_WX_TOOLVER 110)
- elseif(MSVC_VERSION EQUAL 1600)
+ elseif(NOT MSVC_VERSION LESS 1600)
set(_WX_TOOLVER 100)
- elseif(MSVC_VERSION EQUAL 1500)
+ elseif(NOT MSVC_VERSION LESS 1500)
set(_WX_TOOLVER 90)
endif()
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake
index e7f9912..675df84 100644
--- a/Modules/WriteCompilerDetectionHeader.cmake
+++ b/Modules/WriteCompilerDetectionHeader.cmake
@@ -557,7 +557,18 @@ template<> struct ${prefix_arg}StaticAssert<true>{};
# endif
\n")
endif()
- _simpledefine(cxx_nullptr NULLPTR nullptr 0)
+ if (feature STREQUAL cxx_nullptr)
+ set(def_value "${prefix_arg}_NULLPTR")
+ string(APPEND file_content "
+# if defined(${def_name}) && ${def_name}
+# define ${def_value} nullptr
+# elif ${prefix_arg}_COMPILER_IS_GNU
+# define ${def_value} __null
+# else
+# define ${def_value} 0
+# endif
+\n")
+ endif()
if (feature STREQUAL cxx_thread_local)
set(def_value "${prefix_arg}_THREAD_LOCAL")
string(APPEND file_content "
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 184082a..7402526 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 11)
-set(CMake_VERSION_PATCH 20180316)
+set(CMake_VERSION_PATCH 20180322)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CursesDialog/cmCursesStandardIncludes.h b/Source/CursesDialog/cmCursesStandardIncludes.h
index 332d2af..60bad94 100644
--- a/Source/CursesDialog/cmCursesStandardIncludes.h
+++ b/Source/CursesDialog/cmCursesStandardIncludes.h
@@ -5,6 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
+// Record whether __attribute__ is currently defined. See purpose below.
+#ifndef __attribute__
+#define cm_no__attribute__
+#endif
+
#if defined(__hpux)
#define _BOOL_DEFINED
#include <sys/time.h>
@@ -29,4 +34,12 @@ inline void curses_clear()
#undef erase
#undef clear
+// The curses headers on some platforms (e.g. Solaris) may
+// define __attribute__ as a macro. This breaks C++ headers
+// in some cases, so undefine it now.
+#if defined(cm_no__attribute__) && defined(__attribute__)
+#undef __attribute__
+#endif
+#undef cm_no__attribute__
+
#endif // cmCursesStandardIncludes_h
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index e00450f..b82fc43 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -406,7 +406,7 @@ cmComputeLinkInformation::~cmComputeLinkInformation()
}
cmComputeLinkInformation::ItemVector const&
-cmComputeLinkInformation::GetItems()
+cmComputeLinkInformation::GetItems() const
{
return this->Items;
}
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index f8c6214..6c67fb4 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -48,7 +48,7 @@ public:
cmGeneratorTarget const* Target;
};
typedef std::vector<Item> ItemVector;
- ItemVector const& GetItems();
+ ItemVector const& GetItems() const;
std::vector<std::string> const& GetDirectories();
std::vector<std::string> const& GetDepends();
std::vector<std::string> const& GetFrameworkPaths();
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index 62bc8d9..34c0e94 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -96,9 +96,16 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
std::set<std::string> dependencies;
bool haveDeps = false;
+ std::string binDir = this->LocalGenerator->GetBinaryDirectory();
+
+ // Compute a path to the object file to write to the internal depend file.
+ // Any existing content of the internal depend file has already been
+ // loaded in ValidDeps with this path as a key.
+ std::string obj_i = this->LocalGenerator->ConvertToRelativePath(binDir, obj);
+
if (this->ValidDeps != nullptr) {
std::map<std::string, DependencyVector>::const_iterator tmpIt =
- this->ValidDeps->find(obj);
+ this->ValidDeps->find(obj_i);
if (tmpIt != this->ValidDeps->end()) {
dependencies.insert(tmpIt->second.begin(), tmpIt->second.end());
haveDeps = true;
@@ -222,8 +229,6 @@ 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 binDir = this->LocalGenerator->GetBinaryDirectory();
- std::string obj_i = this->LocalGenerator->ConvertToRelativePath(binDir, obj);
std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i);
internalDepends << obj_i << std::endl;
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index f0ae47b..bbbc998 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -97,6 +97,15 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", gte,
properties);
+
+ std::string errorMessage;
+ if (!this->PopulateExportProperties(gte, properties, errorMessage)) {
+ this->LG->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage(
+ cmake::FATAL_ERROR, errorMessage,
+ this->LG->GetMakefile()->GetBacktrace());
+ return false;
+ }
+
const bool newCMP0022Behavior =
gte->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
gte->GetPolicyStatusCMP0022() != cmPolicies::OLD;
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 0f1d745..2dcbfa0 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -11,6 +11,8 @@
#include "cmMakefile.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
+#include "cmPropertyMap.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
@@ -1097,3 +1099,41 @@ void cmExportFileGenerator::GenerateImportedFileChecksCode(
os << ")\n\n";
}
+
+bool cmExportFileGenerator::PopulateExportProperties(
+ cmGeneratorTarget* gte, ImportPropertyMap& properties,
+ std::string& errorMessage)
+{
+ auto& targetProperties = gte->Target->GetProperties();
+ const auto& exportProperties = targetProperties.find("EXPORT_PROPERTIES");
+ if (exportProperties != targetProperties.end()) {
+ std::vector<std::string> propsToExport;
+ cmSystemTools::ExpandListArgument(exportProperties->second.GetValue(),
+ propsToExport);
+ for (auto& prop : propsToExport) {
+ /* Black list reserved properties */
+ if (cmSystemTools::StringStartsWith(prop, "IMPORTED_") ||
+ cmSystemTools::StringStartsWith(prop, "INTERFACE_")) {
+ std::ostringstream e;
+ e << "Target \"" << gte->Target->GetName() << "\" contains property \""
+ << prop << "\" in EXPORT_PROPERTIES but IMPORTED_* and INTERFACE_* "
+ << "properties are reserved.";
+ errorMessage = e.str();
+ return false;
+ }
+ auto propertyValue = targetProperties.GetPropertyValue(prop);
+ std::string evaluatedValue = cmGeneratorExpression::Preprocess(
+ propertyValue, cmGeneratorExpression::StripAllGeneratorExpressions);
+ if (evaluatedValue != propertyValue) {
+ std::ostringstream e;
+ e << "Target \"" << gte->Target->GetName() << "\" contains property \""
+ << prop << "\" in EXPORT_PROPERTIES but this property contains a "
+ << "generator expression. This is not allowed.";
+ errorMessage = e.str();
+ return false;
+ }
+ properties[prop] = propertyValue;
+ }
+ }
+ return true;
+}
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index e541372..954e6c5 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -168,6 +168,10 @@ protected:
virtual void GenerateRequiredCMakeVersion(std::ostream& os,
const char* versionString);
+ bool PopulateExportProperties(cmGeneratorTarget* gte,
+ ImportPropertyMap& properties,
+ std::string& errorMessage);
+
// The namespace in which the exports are placed in the generated file.
std::string Namespace;
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 93ba2ce..63d04a6 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -104,6 +104,12 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
cmGeneratorExpression::InstallInterface,
properties, missingTargets);
+ std::string errorMessage;
+ if (!this->PopulateExportProperties(gt, properties, errorMessage)) {
+ cmSystemTools::Error(errorMessage.c_str());
+ return false;
+ }
+
const bool newCMP0022Behavior =
gt->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
gt->GetPolicyStatusCMP0022() != cmPolicies::OLD;
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index 4dbaa3f..c7c780c 100644
--- a/Source/cmExtraCodeLiteGenerator.cxx
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -408,7 +408,6 @@ void cmExtraCodeLiteGenerator::CreateProjectSourceEntries(
const std::string& projectPath, const cmMakefile* mf,
const std::string& projectType, const std::string& targetName)
{
-
cmXMLWriter& xml(*_xml);
FindMatchingHeaderfiles(cFiles, otherFiles);
// Create 2 virtual folders: src and include
@@ -469,10 +468,14 @@ void cmExtraCodeLiteGenerator::CreateProjectSourceEntries(
xml.EndElement(); // ResourceCompiler
xml.StartElement("General");
- std::string outputPath = mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
+ std::string outputPath =
+ mf->GetSafeDefinition("CMAKE_RUNTIME_OUTPUT_DIRECTORY");
+ if (outputPath.empty()) {
+ outputPath = mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
+ }
std::string relapath;
if (!outputPath.empty()) {
- relapath = cmSystemTools::RelativePath(this->WorkspacePath, outputPath);
+ relapath = cmSystemTools::RelativePath(projectPath, outputPath);
xml.Attribute("OutputFile", relapath + "/$(ProjectName)");
} else {
xml.Attribute("OutputFile", "$(IntermediateDirectory)/$(ProjectName)");
@@ -635,7 +638,7 @@ std::string cmExtraCodeLiteGenerator::GetBuildCommand(
if (generator == "NMake Makefiles" || generator == "Ninja") {
ss << make;
} else if (generator == "MinGW Makefiles" || generator == "Unix Makefiles") {
- ss << make << " -j " << this->CpuCount;
+ ss << make << " -f$(ProjectPath)/Makefile -j " << this->CpuCount;
}
if (!targetName.empty()) {
ss << " " << targetName;
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index 7069386..865595b 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -67,8 +67,6 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
}
this->AlreadyInCache = false;
- this->SelectDefaultNoPackageRootPath();
-
// Find the current root path mode.
this->SelectDefaultRootPathMode();
@@ -206,16 +204,12 @@ void cmFindBase::FillPackageRootPath()
{
cmSearchPath& paths = this->LabeledPaths[PathLabel::PackageRoot];
- // Add package specific search prefixes
- // NOTE: This should be using const_reverse_iterator but HP aCC and
- // Oracle sunCC both currently have standard library issues
- // with the reverse iterator APIs.
- for (std::deque<std::string>::reverse_iterator pkg =
- this->Makefile->FindPackageModuleStack.rbegin();
- pkg != this->Makefile->FindPackageModuleStack.rend(); ++pkg) {
- std::string varName = *pkg + "_ROOT";
- paths.AddCMakePrefixPath(varName);
- paths.AddEnvPrefixPath(varName);
+ // Add the PACKAGE_ROOT_PATH from each enclosing find_package call.
+ for (std::deque<std::vector<std::string>>::const_reverse_iterator pkgPaths =
+ this->Makefile->FindPackageRootPathStack.rbegin();
+ pkgPaths != this->Makefile->FindPackageRootPathStack.rend();
+ ++pkgPaths) {
+ paths.AddPrefixPaths(*pkgPaths);
}
paths.AddSuffixes(this->SearchPathSuffixes);
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index 4a467f3..64108d7 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -88,13 +88,6 @@ void cmFindCommon::InitializeSearchPathGroups()
std::make_pair(PathLabel::Guess, cmSearchPath(this)));
}
-void cmFindCommon::SelectDefaultNoPackageRootPath()
-{
- if (!this->Makefile->IsOn("__UNDOCUMENTED_CMAKE_FIND_PACKAGE_ROOT")) {
- this->NoPackageRootPath = true;
- }
-}
-
void cmFindCommon::SelectDefaultRootPathMode()
{
// Check the policy variable for this find command type.
diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h
index b237f1b..89ff174 100644
--- a/Source/cmFindCommon.h
+++ b/Source/cmFindCommon.h
@@ -84,9 +84,6 @@ protected:
/** Compute final search path list (reroot + trailing slash). */
void ComputeFinalPaths();
- /** Decide whether to enable the PACKAGE_ROOT search entries. */
- void SelectDefaultNoPackageRootPath();
-
/** Compute the current default root path mode. */
void SelectDefaultRootPathMode();
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 2f3a85b..e9ac4a7 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -21,6 +21,7 @@
#include "cmAlgorithms.h"
#include "cmMakefile.h"
+#include "cmPolicies.h"
#include "cmSearchPath.h"
#include "cmState.h"
#include "cmStateTypes.h"
@@ -209,8 +210,6 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
this->SortDirection = strcmp(sd, "ASC") == 0 ? Asc : Dec;
}
- this->SelectDefaultNoPackageRootPath();
-
// Find the current root path mode.
this->SelectDefaultRootPathMode();
@@ -454,6 +453,38 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
return true;
}
+ {
+ // Allocate a PACKAGE_ROOT_PATH for the current find_package call.
+ this->Makefile->FindPackageRootPathStack.emplace_back();
+ std::vector<std::string>& rootPaths =
+ *this->Makefile->FindPackageRootPathStack.rbegin();
+
+ // Add root paths from <PackageName>_ROOT CMake and environment variables,
+ // subject to CMP0074.
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0074)) {
+ case cmPolicies::WARN:
+ this->Makefile->MaybeWarnCMP0074(this->Name);
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ // OLD behavior is to ignore the <pkg>_ROOT variables.
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0074));
+ break;
+ case cmPolicies::NEW: {
+ // NEW behavior is to honor the <pkg>_ROOT variables.
+ std::string const rootVar = this->Name + "_ROOT";
+ if (const char* pkgRoot = this->Makefile->GetDefinition(rootVar)) {
+ cmSystemTools::ExpandListArgument(pkgRoot, rootPaths, false);
+ }
+ cmSystemTools::GetPath(rootPaths, rootVar.c_str());
+ } break;
+ }
+ }
+
this->SetModuleVariables(components);
// See if there is a Find<package>.cmake module.
@@ -589,9 +620,6 @@ void cmFindPackageCommand::SetModuleVariables(const std::string& components)
exact += "_FIND_VERSION_EXACT";
this->AddFindDefinition(exact, this->VersionExact ? "1" : "0");
}
-
- // Push on to the package stack
- this->Makefile->FindPackageModuleStack.push_back(this->Name);
}
void cmFindPackageCommand::AddFindDefinition(const std::string& var,
@@ -1076,7 +1104,7 @@ void cmFindPackageCommand::AppendSuccessInformation()
this->RestoreFindDefinitions();
// Pop the package stack
- this->Makefile->FindPackageModuleStack.pop_back();
+ this->Makefile->FindPackageRootPathStack.pop_back();
}
void cmFindPackageCommand::ComputePrefixes()
@@ -1116,16 +1144,14 @@ void cmFindPackageCommand::FillPrefixesPackageRoot()
{
cmSearchPath& paths = this->LabeledPaths[PathLabel::PackageRoot];
- // Add package specific search prefixes
- // NOTE: This should be using const_reverse_iterator but HP aCC and
- // Oracle sunCC both currently have standard library issues
- // with the reverse iterator APIs.
- for (std::deque<std::string>::reverse_iterator pkg =
- this->Makefile->FindPackageModuleStack.rbegin();
- pkg != this->Makefile->FindPackageModuleStack.rend(); ++pkg) {
- std::string varName = *pkg + "_ROOT";
- paths.AddCMakePath(varName);
- paths.AddEnvPath(varName);
+ // Add the PACKAGE_ROOT_PATH from each enclosing find_package call.
+ for (std::deque<std::vector<std::string>>::const_reverse_iterator pkgPaths =
+ this->Makefile->FindPackageRootPathStack.rbegin();
+ pkgPaths != this->Makefile->FindPackageRootPathStack.rend();
+ ++pkgPaths) {
+ for (std::string const& path : *pkgPaths) {
+ paths.AddPath(path);
+ }
}
}
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index ae4f0a8..62d4ea7 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -42,6 +42,9 @@ bool cmListCommand::InitialPass(std::vector<std::string> const& args,
if (subCommand == "INSERT") {
return this->HandleInsertCommand(args);
}
+ if (subCommand == "JOIN") {
+ return this->HandleJoinCommand(args);
+ }
if (subCommand == "REMOVE_AT") {
return this->HandleRemoveAtCommand(args);
}
@@ -294,6 +297,34 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args)
return true;
}
+bool cmListCommand::HandleJoinCommand(std::vector<std::string> const& args)
+{
+ if (args.size() != 4) {
+ std::ostringstream error;
+ error << "sub-command JOIN requires three arguments (" << args.size() - 1
+ << " found).";
+ this->SetError(error.str());
+ return false;
+ }
+
+ const std::string& listName = args[1];
+ const std::string& glue = args[2];
+ const std::string& variableName = args[3];
+
+ // expand the variable
+ std::vector<std::string> varArgsExpanded;
+ if (!this->GetList(varArgsExpanded, listName)) {
+ this->Makefile->AddDefinition(variableName, "");
+ return true;
+ }
+
+ std::string value =
+ cmJoin(cmMakeRange(varArgsExpanded.begin(), varArgsExpanded.end()), glue);
+
+ this->Makefile->AddDefinition(variableName, value.c_str());
+ return true;
+}
+
bool cmListCommand::HandleRemoveItemCommand(
std::vector<std::string> const& args)
{
diff --git a/Source/cmListCommand.h b/Source/cmListCommand.h
index 2965399..d6870e6 100644
--- a/Source/cmListCommand.h
+++ b/Source/cmListCommand.h
@@ -37,6 +37,7 @@ protected:
bool HandleAppendCommand(std::vector<std::string> const& args);
bool HandleFindCommand(std::vector<std::string> const& args);
bool HandleInsertCommand(std::vector<std::string> const& args);
+ bool HandleJoinCommand(std::vector<std::string> const& args);
bool HandleRemoveAtCommand(std::vector<std::string> const& args);
bool HandleRemoveItemCommand(std::vector<std::string> const& args);
bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 9e53579..5850f94 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -158,6 +158,32 @@ bool cmMakefile::CheckCMP0037(std::string const& targetName,
return true;
}
+void cmMakefile::MaybeWarnCMP0074(std::string const& pkg)
+{
+ // Warn if a <pkg>_ROOT variable we may use is set.
+ std::string const varName = pkg + "_ROOT";
+ const char* var = this->GetDefinition(varName);
+ std::string env;
+ cmSystemTools::GetEnv(varName, env);
+
+ bool const haveVar = var && *var;
+ bool const haveEnv = !env.empty();
+ if ((haveVar || haveEnv) && this->WarnedCMP0074.insert(varName).second) {
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0074) << "\n";
+ if (haveVar) {
+ w << "CMake variable " << varName << " is set to:\n"
+ << " " << var << "\n";
+ }
+ if (haveEnv) {
+ w << "Environment variable " << varName << " is set to:\n"
+ << " " << env << "\n";
+ }
+ w << "For compatibility, CMake is ignoring the variable.";
+ this->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+}
+
cmStringRange cmMakefile::GetIncludeDirectoriesEntries() const
{
return this->StateSnapshot.GetDirectory().GetIncludeDirectoriesEntries();
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 95ba53a..aafe60b 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -832,9 +832,11 @@ public:
void RemoveExportBuildFileGeneratorCMP0024(cmExportBuildFileGenerator* gen);
void AddExportBuildFileGenerator(cmExportBuildFileGenerator* gen);
- // Maintain a stack of package names to determine the depth of find modules
- // we are currently being called with
- std::deque<std::string> FindPackageModuleStack;
+ // Maintain a stack of package roots to allow nested PACKAGE_ROOT_PATH
+ // searches
+ std::deque<std::vector<std::string>> FindPackageRootPathStack;
+
+ void MaybeWarnCMP0074(std::string const& pkg);
protected:
// add link libraries and directories to the target
@@ -1001,6 +1003,7 @@ private:
bool WarnUnused;
bool CheckSystemVars;
bool CheckCMP0000;
+ std::set<std::string> WarnedCMP0074;
bool IsSourceFileTryCompile;
mutable bool SuppressWatches;
};
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index a784f98..34fe09d 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -217,7 +217,9 @@ class cmMakefile;
cmPolicies::WARN) \
SELECT(POLICY, CMP0073, \
"Do not produce legacy _LIB_DEPENDS cache entries.", 3, 12, 0, \
- cmPolicies::WARN)
+ cmPolicies::WARN) \
+ SELECT(POLICY, CMP0074, "find_package uses PackageName_ROOT variables.", 3, \
+ 12, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 67c971f..6ddb0b8 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -68,8 +68,10 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
bool haveVersion = false;
bool haveLanguages = false;
bool haveDescription = false;
+ bool haveHomepage = false;
std::string version;
std::string description;
+ std::string homepage;
std::vector<std::string> languages;
std::function<void()> missedValueReporter;
auto resetReporter = [&missedValueReporter]() {
@@ -78,6 +80,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
enum Doing
{
DoingDescription,
+ DoingHomepage,
DoingLanguages,
DoingVersion
};
@@ -141,6 +144,22 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
"by a value that expanded to nothing.");
resetReporter();
};
+ } else if (args[i] == "HOMEPAGE_URL") {
+ if (haveHomepage) {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR, "HOMEPAGE_URL may be specified at most once.");
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+ haveHomepage = true;
+ doing = DoingHomepage;
+ missedValueReporter = [this, &resetReporter]() {
+ this->Makefile->IssueMessage(
+ cmake::WARNING,
+ "HOMEPAGE_URL keyword not followed by a value or was followed "
+ "by a value that expanded to nothing.");
+ resetReporter();
+ };
} else if (doing == DoingVersion) {
doing = DoingLanguages;
version = args[i];
@@ -149,6 +168,10 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
doing = DoingLanguages;
description = args[i];
resetReporter();
+ } else if (doing == DoingHomepage) {
+ doing = DoingLanguages;
+ homepage = args[i];
+ resetReporter();
} else // doing == DoingLanguages
{
languages.push_back(args[i]);
@@ -159,12 +182,12 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
missedValueReporter();
}
- if ((haveVersion || haveDescription) && !haveLanguages &&
+ if ((haveVersion || haveDescription || haveHomepage) && !haveLanguages &&
!languages.empty()) {
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
- "project with VERSION or DESCRIPTION must use LANGUAGES before "
- "language names.");
+ "project with VERSION, DESCRIPTION or HOMEPAGE_URL must "
+ "use LANGUAGES before language names.");
cmSystemTools::SetFatalErrorOccured();
return true;
}
@@ -261,6 +284,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
if (haveDescription) {
this->Makefile->AddDefinition("PROJECT_DESCRIPTION", description.c_str());
+ this->Makefile->AddDefinition(projectName + "_DESCRIPTION",
+ description.c_str());
// Set the CMAKE_PROJECT_DESCRIPTION variable to be the highest-level
// project name in the tree. If there are two project commands
// in the same CMakeLists.txt file, and it is the top level
@@ -275,6 +300,24 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
}
}
+ if (haveHomepage) {
+ this->Makefile->AddDefinition("PROJECT_HOMEPAGE_URL", homepage.c_str());
+ this->Makefile->AddDefinition(projectName + "_HOMEPAGE_URL",
+ homepage.c_str());
+ // Set the CMAKE_PROJECT_HOMEPAGE_URL variable to be the highest-level
+ // project name in the tree. If there are two project commands
+ // in the same CMakeLists.txt file, and it is the top level
+ // CMakeLists.txt file, then go with the last one.
+ if (!this->Makefile->GetDefinition("CMAKE_PROJECT_HOMEPAGE_URL") ||
+ (this->Makefile->IsRootMakefile())) {
+ this->Makefile->AddDefinition("CMAKE_PROJECT_HOMEPAGE_URL",
+ homepage.c_str());
+ this->Makefile->AddCacheDefinition(
+ "CMAKE_PROJECT_HOMEPAGE_URL", homepage.c_str(),
+ "Value Computed by CMake", cmStateEnums::STATIC);
+ }
+ }
+
if (languages.empty()) {
// if no language is specified do c and c++
languages.push_back("C");
diff --git a/Source/cmSearchPath.h b/Source/cmSearchPath.h
index fd0c7c5..2a576ed 100644
--- a/Source/cmSearchPath.h
+++ b/Source/cmSearchPath.h
@@ -39,10 +39,10 @@ public:
void AddCMakePrefixPath(const std::string& variable);
void AddEnvPrefixPath(const std::string& variable, bool stripBin = false);
void AddSuffixes(const std::vector<std::string>& suffixes);
-
-protected:
void AddPrefixPaths(const std::vector<std::string>& paths,
const char* base = nullptr);
+
+protected:
void AddPathInternal(const std::string& path, const char* base = nullptr);
cmFindCommon* FC;
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 0fd8043..7e6e803 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -18,6 +18,45 @@
#include <iterator>
#include <memory> // IWYU pragma: keep
+struct cmVisualStudio10TargetGenerator::Elem
+{
+ cmGeneratedFileStream& S;
+ int Indent;
+ bool HasElements = false;
+
+ Elem(cmGeneratedFileStream& s, int i)
+ : S(s)
+ , Indent(i)
+ {
+ }
+ Elem(const Elem&) = delete;
+ Elem(Elem& par)
+ : S(par.S)
+ , Indent(par.Indent + 1)
+ {
+ par.SetHasElements();
+ }
+ void SetHasElements()
+ {
+ if (!HasElements) {
+ S << ">\n";
+ HasElements = true;
+ }
+ }
+ void WriteEndTag(const char* tag)
+ {
+ if (HasElements) {
+ S.fill(' ');
+ S.width(Indent * 2);
+ // write an empty string to get the fill level indent to print
+ S << "";
+ S << "</" << tag << ">\n";
+ } else {
+ S << " />\n";
+ }
+ }
+};
+
inline void cmVisualStudio10TargetGenerator::WriteElem(const char* tag,
const char* val,
int indentLevel)
@@ -787,7 +826,7 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup()
this->WriteString("<ItemGroup>\n", 1);
for (cmSourceFile const* oi : xamlObjs) {
std::string obj = oi->GetFullPath();
- std::string xamlType;
+ const char* xamlType;
const char* xamlTypeProperty = oi->GetProperty("VS_XAML_TYPE");
if (xamlTypeProperty) {
xamlType = xamlTypeProperty;
@@ -795,7 +834,9 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup()
xamlType = "Page";
}
- this->WriteSource(xamlType, oi, ">\n");
+ Elem e2(*this->BuildFileStream, 2);
+ this->WriteSource(xamlType, oi);
+ e2.SetHasElements();
if (this->ProjectType == csproj && !this->InSourceBuild) {
// add <Link> tag to written XAML source if necessary
const std::string srcDir = this->Makefile->GetCurrentSourceDirectory();
@@ -814,8 +855,7 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup()
}
}
this->WriteElem("SubType", "Designer", 3);
- this->WriteString("</", 2);
- (*this->BuildFileStream) << xamlType << ">\n";
+ e2.WriteEndTag(xamlType);
}
this->WriteString("</ItemGroup>\n", 1);
}
@@ -1148,17 +1188,20 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
}
cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
+ Elem e2(*this->BuildFileStream, 2);
if (this->ProjectType != csproj) {
- this->WriteSource("CustomBuild", source, ">\n");
+ this->WriteSource("CustomBuild", source);
+ e2.SetHasElements();
} else {
this->WriteString("<ItemGroup>\n", 1);
std::string link;
this->GetCSharpSourceLink(source, link);
- this->WriteSource("None", source, ">\n");
+ this->WriteSource("None", source);
+ e2.SetHasElements();
if (!link.empty()) {
this->WriteElem("Link", link, 3);
}
- this->WriteString("</None>\n", 2);
+ e2.WriteEndTag("None");
this->WriteString("</ItemGroup>\n", 1);
}
for (std::string const& c : this->Configurations) {
@@ -1202,7 +1245,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
}
}
if (this->ProjectType != csproj) {
- this->WriteString("</CustomBuild>\n", 2);
+ e2.WriteEndTag("CustomBuild");
}
}
@@ -1473,24 +1516,23 @@ void cmVisualStudio10TargetGenerator::WriteGroupSources(
void cmVisualStudio10TargetGenerator::WriteHeaderSource(cmSourceFile const* sf)
{
std::string const& fileName = sf->GetFullPath();
+ Elem e2(*this->BuildFileStream, 2);
+ this->WriteSource("ClInclude", sf);
if (this->IsResxHeader(fileName)) {
- this->WriteSource("ClInclude", sf, ">\n");
+ e2.SetHasElements();
this->WriteElem("FileType", "CppForm", 3);
- this->WriteString("</ClInclude>\n", 2);
} else if (this->IsXamlHeader(fileName)) {
- this->WriteSource("ClInclude", sf, ">\n");
std::string xamlFileName = fileName.substr(0, fileName.find_last_of("."));
+ e2.SetHasElements();
this->WriteElem("DependentUpon", xamlFileName, 3);
- this->WriteString("</ClInclude>\n", 2);
- } else {
- this->WriteSource("ClInclude", sf);
}
+ e2.WriteEndTag("ClInclude");
}
void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf)
{
bool toolHasSettings = false;
- std::string tool = "None";
+ const char* tool = "None";
std::string shaderType;
std::string shaderEntryPoint;
std::string shaderModel;
@@ -1640,8 +1682,10 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf)
}
}
+ Elem e2(*this->BuildFileStream, 2);
+ this->WriteSource(tool, sf);
if (toolHasSettings) {
- this->WriteSource(tool, sf, ">\n");
+ e2.SetHasElements();
if (!deployContent.empty()) {
cmGeneratorExpression ge;
@@ -1736,16 +1780,12 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf)
}
// write source file specific tags
this->WriteCSharpSourceProperties(sourceFileTags);
- this->WriteString("</", 2);
- (*this->BuildFileStream) << tool << ">\n";
- } else {
- this->WriteSource(tool, sf);
}
+ e2.WriteEndTag(tool);
}
void cmVisualStudio10TargetGenerator::WriteSource(std::string const& tool,
- cmSourceFile const* sf,
- const char* end)
+ cmSourceFile const* sf)
{
// Visual Studio tools append relative paths to the current dir, as in:
//
@@ -1782,8 +1822,7 @@ void cmVisualStudio10TargetGenerator::WriteSource(std::string const& tool,
ConvertToWindowsSlash(sourceFile);
this->WriteString("<", 2);
(*this->BuildFileStream) << tool << " Include=\""
- << cmVS10EscapeXML(sourceFile) << "\""
- << (end ? end : " />\n");
+ << cmVS10EscapeXML(sourceFile) << "\"";
ToolSource toolSource = { sf, forceRelative };
this->Tools[tool].push_back(toolSource);
@@ -1805,7 +1844,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
this->GeneratorTarget->GetAllConfigSources();
for (cmGeneratorTarget::AllConfigSource const& si : sources) {
- std::string tool;
+ const char* tool = nullptr;
switch (si.Kind) {
case cmGeneratorTarget::SourceKindAppManifest:
tool = "AppxManifest";
@@ -1874,7 +1913,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
break;
}
- if (!tool.empty()) {
+ if (tool) {
// Compute set of configurations to exclude, if any.
std::vector<size_t> const& include_configs = si.Configs;
std::vector<size_t> exclude_configs;
@@ -1882,31 +1921,15 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
include_configs.begin(), include_configs.end(),
std::back_inserter(exclude_configs));
+ Elem e2(*this->BuildFileStream, 2);
+ this->WriteSource(tool, si.Source);
if (si.Kind == cmGeneratorTarget::SourceKindObjectSource) {
- // FIXME: refactor generation to avoid tracking XML syntax state.
- this->WriteSource(tool, si.Source, "");
- bool have_nested = this->OutputSourceSpecificFlags(si.Source);
- if (!exclude_configs.empty()) {
- if (!have_nested) {
- (*this->BuildFileStream) << ">\n";
- }
- this->WriteExcludeFromBuild(exclude_configs);
- have_nested = true;
- }
- if (have_nested) {
- this->WriteString("</", 2);
- (*this->BuildFileStream) << tool << ">\n";
- } else {
- (*this->BuildFileStream) << " />\n";
- }
- } else if (!exclude_configs.empty()) {
- this->WriteSource(tool, si.Source, ">\n");
- this->WriteExcludeFromBuild(exclude_configs);
- this->WriteString("</", 2);
- (*this->BuildFileStream) << tool << ">\n";
- } else {
- this->WriteSource(tool, si.Source);
+ this->OutputSourceSpecificFlags(e2, si.Source);
+ }
+ if (!exclude_configs.empty()) {
+ this->WriteExcludeFromBuild(e2, exclude_configs);
}
+ e2.WriteEndTag(tool);
}
}
@@ -1917,8 +1940,8 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
this->WriteString("</ItemGroup>\n", 1);
}
-bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
- cmSourceFile const* source)
+void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
+ Elem& e2, cmSourceFile const* source)
{
cmSourceFile const& sf = *source;
@@ -1978,14 +2001,10 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
}
}
bool noWinRT = this->TargetCompileAsWinRT && lang == "C";
- bool hasFlags = false;
// for the first time we need a new line if there is something
// produced here.
- const char* firstString = ">\n";
if (!objectName.empty()) {
- (*this->BuildFileStream) << firstString;
- firstString = "";
- hasFlags = true;
+ e2.SetHasElements();
if (lang == "CUDA") {
this->WriteElem("CompileOut", "$(IntDir)/" + objectName, 3);
} else {
@@ -2009,9 +2028,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
// use them
if (!flags.empty() || !options.empty() || !configDefines.empty() ||
!includes.empty() || compileAs || noWinRT) {
- (*this->BuildFileStream) << firstString;
- firstString = ""; // only do firstString once
- hasFlags = true;
+ e2.SetHasElements();
cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
cmIDEFlagTable const* flagtable = nullptr;
const std::string& srclang = source->GetLanguage();
@@ -2086,9 +2103,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
}
}
if (this->IsXamlSource(source->GetFullPath())) {
- (*this->BuildFileStream) << firstString;
- firstString = ""; // only do firstString once
- hasFlags = true;
+ e2.SetHasElements();
const std::string& fileName = source->GetFullPath();
std::string xamlFileName = fileName.substr(0, fileName.find_last_of("."));
this->WriteElem("DependentUpon", xamlFileName, 3);
@@ -2106,19 +2121,16 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
this->GetCSharpSourceProperties(&sf, sourceFileTags);
// write source file specific tags
if (!sourceFileTags.empty()) {
- hasFlags = true;
- (*this->BuildFileStream) << firstString;
- firstString = "";
+ e2.SetHasElements();
this->WriteCSharpSourceProperties(sourceFileTags);
}
}
-
- return hasFlags;
}
void cmVisualStudio10TargetGenerator::WriteExcludeFromBuild(
- std::vector<size_t> const& exclude_configs)
+ Elem& e2, std::vector<size_t> const& exclude_configs)
{
+ e2.SetHasElements();
for (size_t ci : exclude_configs) {
this->WriteString("", 3);
(*this->BuildFileStream)
@@ -2180,6 +2192,13 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
<< "</LocalDebuggerWorkingDirectory>\n";
}
+ if (const char* debuggerCommand =
+ this->GeneratorTarget->GetProperty("VS_DEBUGGER_COMMAND")) {
+ this->WritePlatformConfigTag("LocalDebuggerCommand", config, 2);
+ *this->BuildFileStream << cmVS10EscapeXML(debuggerCommand)
+ << "</LocalDebuggerCommand>\n";
+ }
+
std::string name =
cmSystemTools::GetFilenameWithoutLastExtension(targetNameFull);
this->WritePlatformConfigTag("TargetName", config, 2);
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 64121ed..d557255 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -53,6 +53,8 @@ private:
std::vector<std::string> Configs;
};
+ struct Elem;
+
std::string ConvertPath(std::string const& path, bool forceRelative);
void WriteString(const char* line, int indentLevel);
void WriteElem(const char* tag, const char* val, int indentLevel);
@@ -66,9 +68,9 @@ private:
void WriteHeaderSource(cmSourceFile const* sf);
void WriteExtraSource(cmSourceFile const* sf);
void WriteNsightTegraConfigurationValues(std::string const& config);
- void WriteSource(std::string const& tool, cmSourceFile const* sf,
- const char* end = 0);
- void WriteExcludeFromBuild(std::vector<size_t> const& exclude_configs);
+ void WriteSource(std::string const& tool, cmSourceFile const* sf);
+ void WriteExcludeFromBuild(Elem&,
+ std::vector<size_t> const& exclude_configs);
void WriteAllSources();
void WriteDotNetReferences();
void WriteDotNetReference(std::string const& ref, std::string const& hint);
@@ -145,7 +147,7 @@ private:
void WriteGroups();
void WriteProjectReferences();
void WriteApplicationTypeSettings();
- bool OutputSourceSpecificFlags(cmSourceFile const* source);
+ void OutputSourceSpecificFlags(Elem&, cmSourceFile const* source);
void AddLibraries(cmComputeLinkInformation& cli,
std::vector<std::string>& libVec,
std::vector<std::string>& vsTargetVec);
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 101502f..cdea217 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -1427,6 +1427,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
add_subdirectory(FindXercesC)
endif()
+ if(CMake_TEST_FindPython)
+ add_subdirectory(FindPython)
+ endif()
+
add_subdirectory(FindThreads)
# Matlab module
diff --git a/Tests/CompileFeatures/cxx_generalized_initializers.cpp b/Tests/CompileFeatures/cxx_generalized_initializers.cpp
index cfe9d98..0df0a33 100644
--- a/Tests/CompileFeatures/cxx_generalized_initializers.cpp
+++ b/Tests/CompileFeatures/cxx_generalized_initializers.cpp
@@ -11,11 +11,17 @@ class initializer_list
const _E* __begin_;
size_t __size_;
+#ifdef __INTEL_COMPILER
+ // The Intel compiler internally asserts the constructor overloads, so
+ // reproduce the constructor used in its <initializer_list> header.
+ initializer_list(const _E*, size_t) {}
+#else
public:
template <typename T1, typename T2>
initializer_list(T1, T2)
{
}
+#endif
};
}
diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt
index cbc8c6b..0f1a556 100644
--- a/Tests/ExportImport/Export/CMakeLists.txt
+++ b/Tests/ExportImport/Export/CMakeLists.txt
@@ -356,6 +356,14 @@ install(FILES
set_property(TARGET testLib2 APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS USING_TESTLIB2)
set_property(TARGET testLib3 APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS USING_TESTLIB3)
+set_target_properties(testLib3 PROPERTIES
+ EXPORT_PROPERTIES "EXPORTED_PROPERTY1"
+ EXPORTED_PROPERTY1 "EXPORTING_TESTLIB3")
+set_target_properties(testLib4 PROPERTIES
+ EXPORTED_PROPERTY2 "EXPORTING_TESTLIB4_1"
+ EXPORTED_PROPERTY3 "EXPORTING_TESTLIB4_2")
+set_property(TARGET testLib4 PROPERTY
+ EXPORT_PROPERTIES EXPORTED_PROPERTY2 EXPORTED_PROPERTY3)
set_property(TARGET cmp0022NEW APPEND PROPERTY INTERFACE_LINK_LIBRARIES testLib2)
# set_property(TARGET cmp0022NEW APPEND PROPERTY LINK_INTERFACE_LIBRARIES testLibIncludeRequired2) # TODO: Test for error
diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt
index 4e8eac2..39a89dc 100644
--- a/Tests/ExportImport/Import/A/CMakeLists.txt
+++ b/Tests/ExportImport/Import/A/CMakeLists.txt
@@ -32,6 +32,20 @@ add_executable(imp_testExe1
${Import_BINARY_DIR}/exp_generated4.c
)
+function(checkForProperty _TARGET _PROP _EXPECTED)
+ get_target_property(EXPORTED_PROPERTY ${_TARGET} "${_PROP}")
+ if (NOT EXPORTED_PROPERTY STREQUAL "${_EXPECTED}")
+ message(SEND_ERROR "${_TARGET} was expected to export \"${_PROP}\" with value \"${_EXPECTED}\" but got \"${EXPORTED_PROPERTY}\"")
+ endif()
+endfunction()
+
+checkForProperty(bld_testLib3 "EXPORTED_PROPERTY1" "EXPORTING_TESTLIB3")
+checkForProperty(exp_testLib3 "EXPORTED_PROPERTY1" "EXPORTING_TESTLIB3")
+checkForProperty(bld_testLib4 "EXPORTED_PROPERTY2" "EXPORTING_TESTLIB4_1")
+checkForProperty(exp_testLib4 "EXPORTED_PROPERTY2" "EXPORTING_TESTLIB4_1")
+checkForProperty(bld_testLib4 "EXPORTED_PROPERTY3" "EXPORTING_TESTLIB4_2")
+checkForProperty(exp_testLib4 "EXPORTED_PROPERTY3" "EXPORTING_TESTLIB4_2")
+
# Try linking to a library imported from the install tree.
target_link_libraries(imp_testExe1
exp_testLib2
diff --git a/Tests/FindPython/CMakeLists.txt b/Tests/FindPython/CMakeLists.txt
new file mode 100644
index 0000000..639d29c
--- /dev/null
+++ b/Tests/FindPython/CMakeLists.txt
@@ -0,0 +1,69 @@
+add_test(NAME FindPython.Python2 COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python2"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python2"
+ ${build_generator_args}
+ --build-project TestPython2
+ --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
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python2Fail"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python2Fail"
+ ${build_generator_args}
+ --build-project TestPython2Fail
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+set_tests_properties(FindPython.Python2Fail PROPERTIES
+ PASS_REGULAR_EXPRESSION "Could NOT find Python2 \\(missing: foobar\\)")
+
+add_test(NAME FindPython.Python3 COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python3"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python3"
+ ${build_generator_args}
+ --build-project TestPython3
+ --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
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python3Fail"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python3Fail"
+ ${build_generator_args}
+ --build-project TestPython3Fail
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+set_tests_properties(FindPython.Python3Fail PROPERTIES
+ PASS_REGULAR_EXPRESSION "Could NOT find Python3 \\(missing: foobar\\)")
+
+add_test(NAME FindPython.Python COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python"
+ ${build_generator_args}
+ --build-project TestPython
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
+add_test(NAME FindPython.MultiplePackages COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/MultiplePackages"
+ "${CMake_BINARY_DIR}/Tests/FindPython/MultiplePackages"
+ ${build_generator_args}
+ --build-project TestMultiplePackages
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindPython/MultiplePackages/CMakeLists.txt b/Tests/FindPython/MultiplePackages/CMakeLists.txt
new file mode 100644
index 0000000..5c85155
--- /dev/null
+++ b/Tests/FindPython/MultiplePackages/CMakeLists.txt
@@ -0,0 +1,33 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestMultiplePackages C)
+
+find_package (Python2 REQUIRED COMPONENTS Interpreter Development)
+find_package (Python3 REQUIRED COMPONENTS Interpreter Development)
+
+# Must find Python 3
+find_package (Python REQUIRED)
+
+if (NOT Python3_EXECUTABLE STREQUAL Python_EXECUTABLE)
+ message (FATAL_ERROR
+ "Python interpreters do not match:\n"
+ " Python_EXECUTABLE='${Python_EXECUTABLE}'\n"
+ " Python3_EXECUTABLE='${Python3_EXECUTABLE}'\n"
+ )
+endif()
+
+
+Python2_add_library (spam2 MODULE ../spam.c)
+target_compile_definitions (spam2 PRIVATE PYTHON2)
+
+Python3_add_library (spam3 MODULE ../spam.c)
+target_compile_definitions (spam3 PRIVATE PYTHON3)
+
+
+add_test (NAME python2_spam2
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:spam3>"
+ "${Python2_EXECUTABLE}" -c "import spam2; spam2.system(\"cd\")")
+
+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/FindPython/Python/CMakeLists.txt b/Tests/FindPython/Python/CMakeLists.txt
new file mode 100644
index 0000000..bebd23f
--- /dev/null
+++ b/Tests/FindPython/Python/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPython C)
+
+include(CTest)
+
+find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
+if (NOT Python_FOUND)
+ message (FATAL_ERROR "Fail to found Python 3")
+endif()
+
+Python_add_library (spam3 MODULE ../spam.c)
+target_compile_definitions (spam3 PRIVATE PYTHON3)
+
+add_test (NAME python_spam3
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:spam3>"
+ "${Python_EXECUTABLE}" -c "import spam3; spam3.system(\"cd\")")
diff --git a/Tests/FindPython/Python2/CMakeLists.txt b/Tests/FindPython/Python2/CMakeLists.txt
new file mode 100644
index 0000000..9622b6f
--- /dev/null
+++ b/Tests/FindPython/Python2/CMakeLists.txt
@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPython2 C)
+
+include(CTest)
+
+find_package(Python2 3 QUIET)
+if (Python2_FOUND)
+ message (FATAL_ERROR "Wrong python version found: ${Python2_VERSION}")
+endif()
+
+find_package(Python2 REQUIRED COMPONENTS Interpreter Development)
+if (NOT Python2_FOUND)
+ message (FATAL_ERROR "Fail to found Python 2")
+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/Python2Fail/CMakeLists.txt b/Tests/FindPython/Python2Fail/CMakeLists.txt
new file mode 100644
index 0000000..989688f
--- /dev/null
+++ b/Tests/FindPython/Python2Fail/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPython2Fail C)
+
+include(CTest)
+
+find_package(Python2 REQUIRED COMPONENTS Interpreter Development foobar)
+
+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
new file mode 100644
index 0000000..cb86eae
--- /dev/null
+++ b/Tests/FindPython/Python3/CMakeLists.txt
@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPython3 C)
+
+include(CTest)
+
+find_package(Python3 2 QUIET)
+if (Python3_FOUND)
+ message (FATAL_ERROR "Wrong python version found: ${Python3_VERSION}")
+endif()
+
+find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
+if (NOT Python3_FOUND)
+ message (FATAL_ERROR "Fail to found Python 3")
+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/FindPython/Python3Fail/CMakeLists.txt b/Tests/FindPython/Python3Fail/CMakeLists.txt
new file mode 100644
index 0000000..cd46c88
--- /dev/null
+++ b/Tests/FindPython/Python3Fail/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPython3Fail C)
+
+include(CTest)
+
+find_package(Python3 REQUIRED COMPONENTS Interpreter Development foobar)
+
+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/FindPython/spam.c b/Tests/FindPython/spam.c
new file mode 100644
index 0000000..1c65d54
--- /dev/null
+++ b/Tests/FindPython/spam.c
@@ -0,0 +1,41 @@
+
+#include <Python.h>
+
+static PyObject* spam_system(PyObject* self, PyObject* args)
+{
+ const char* command;
+ int sts;
+
+ if (!PyArg_ParseTuple(args, "s", &command))
+ return NULL;
+ sts = system(command);
+ /* return PyLong_FromLong(sts); */
+ return Py_BuildValue("i", sts);
+}
+
+static PyMethodDef SpamMethods[] = {
+ { "system", spam_system, METH_VARARGS, "Execute a shell command." },
+ { NULL, NULL, 0, NULL } /* Sentinel */
+};
+
+#if defined(PYTHON2)
+PyMODINIT_FUNC initspam2(void)
+{
+ (void)Py_InitModule("spam2", SpamMethods);
+}
+#endif
+
+#if defined(PYTHON3)
+static struct PyModuleDef spammodule = {
+ PyModuleDef_HEAD_INIT, "spam3", /* name of module */
+ NULL, /* module documentation, may be NULL */
+ -1, /* size of per-interpreter state of the module,
+ or -1 if the module keeps state in global variables. */
+ SpamMethods
+};
+
+PyMODINIT_FUNC PyInit_spam3(void)
+{
+ return PyModule_Create(&spammodule);
+}
+#endif
diff --git a/Tests/RunCMake/UseSWIG/BasicConfiguration.cmake b/Tests/RunCMake/UseSWIG/BasicConfiguration.cmake
index 94d8dd3..2f46d63 100644
--- a/Tests/RunCMake/UseSWIG/BasicConfiguration.cmake
+++ b/Tests/RunCMake/UseSWIG/BasicConfiguration.cmake
@@ -9,10 +9,9 @@ unset(SWIG_LANG_OPTIONS)
unset(SWIG_LANG_LIBRARIES)
if(${language} MATCHES python)
- find_package(PythonInterp REQUIRED)
- find_package(PythonLibs REQUIRED)
- set(SWIG_LANG_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_PATH})
- set(SWIG_LANG_LIBRARIES ${PYTHON_LIBRARIES})
+ find_package(Python REQUIRED COMPONENTS Interpreter Development)
+ set(SWIG_LANG_INCLUDE_DIRECTORIES ${Python_INCLUDE_DIRS})
+ set(SWIG_LANG_LIBRARIES ${Python_LIBRARIES})
endif()
if(${language} MATCHES perl)
find_package(Perl REQUIRED)
diff --git a/Tests/RunCMake/UseSWIG/BasicPython.cmake b/Tests/RunCMake/UseSWIG/BasicPython.cmake
index 0d8c824..873dbe9 100644
--- a/Tests/RunCMake/UseSWIG/BasicPython.cmake
+++ b/Tests/RunCMake/UseSWIG/BasicPython.cmake
@@ -5,5 +5,5 @@ include (BasicConfiguration.cmake)
add_custom_target (RunTest
COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:example>"
- "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/runme.py"
+ "${Python_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/runme.py"
DEPENDS example)
diff --git a/Tests/RunCMake/UseSWIG/CMakeLists.txt b/Tests/RunCMake/UseSWIG/CMakeLists.txt
index f452db1..2d75985 100644
--- a/Tests/RunCMake/UseSWIG/CMakeLists.txt
+++ b/Tests/RunCMake/UseSWIG/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.1)
project(${RunCMake_TEST} CXX)
include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/UseSWIG/MultiplePython.cmake b/Tests/RunCMake/UseSWIG/MultiplePython.cmake
new file mode 100644
index 0000000..3804bdd
--- /dev/null
+++ b/Tests/RunCMake/UseSWIG/MultiplePython.cmake
@@ -0,0 +1,26 @@
+
+find_package(SWIG REQUIRED)
+include(${SWIG_USE_FILE})
+
+find_package(Python2 REQUIRED COMPONENTS Development)
+find_package(Python3 REQUIRED COMPONENTS Development)
+
+unset(CMAKE_SWIG_FLAGS)
+
+set (CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set_property(SOURCE example.i PROPERTY CPLUSPLUS ON)
+set_property(SOURCE example.i PROPERTY COMPILE_OPTIONS -includeall)
+
+swig_add_library(example1
+ LANGUAGE python
+ OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/Python2"
+ SOURCES example.i example.cxx)
+target_link_libraries(example1 PRIVATE Python2::Python)
+
+# re-use sample interface file for another plugin
+swig_add_library(example2
+ LANGUAGE python
+ OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/Python3"
+ SOURCES example.i example.cxx)
+target_link_libraries(example2 PRIVATE Python3::Python)
diff --git a/Tests/RunCMake/UseSWIG/RunCMakeTest.cmake b/Tests/RunCMake/UseSWIG/RunCMakeTest.cmake
index c63ff2e..cded22f 100644
--- a/Tests/RunCMake/UseSWIG/RunCMakeTest.cmake
+++ b/Tests/RunCMake/UseSWIG/RunCMakeTest.cmake
@@ -10,8 +10,11 @@ function(run_SWIG test)
set(RunCMake_TEST_NO_CLEAN 1)
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set (RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release)
+ endif()
run_cmake(${test})
- run_cmake_command(${test}-test ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR} ${_SWIG_TEST_TARGET})
+ run_cmake_command(${test}-test ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR} --config Release ${_SWIG_TEST_TARGET})
endfunction()
run_SWIG(LegacyPython TARGET RunTest)
@@ -21,3 +24,4 @@ run_SWIG(BasicPython TARGET RunTest)
run_SWIG(BasicPerl TARGET RunTest)
run_SWIG(MultipleModules)
+run_SWIG(MultiplePython)
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index 7100b31..afe9d6d 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -3,6 +3,7 @@ run_cmake(VsConfigurationType)
run_cmake(VsTargetsFileReferences)
run_cmake(VsCustomProps)
run_cmake(VsDebuggerWorkingDir)
+run_cmake(VsDebuggerCommand)
run_cmake(VsCSharpCustomTags)
run_cmake(VsCSharpReferenceProps)
run_cmake(VsCSharpWithoutSources)
diff --git a/Tests/RunCMake/VS10Project/VsDebuggerCommand-check.cmake b/Tests/RunCMake/VS10Project/VsDebuggerCommand-check.cmake
new file mode 100644
index 0000000..0ded780
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsDebuggerCommand-check.cmake
@@ -0,0 +1,22 @@
+set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
+if(NOT EXISTS "${vcProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
+ return()
+endif()
+
+set(debuggerCommandSet FALSE)
+
+file(STRINGS "${vcProjectFile}" lines)
+foreach(line IN LISTS lines)
+ if(line MATCHES "^ *<LocalDebuggerCommand[^>]*>([^<>]+)</LocalDebuggerCommand>$")
+ if("${CMAKE_MATCH_1}" STREQUAL "my-debugger-command")
+ message(STATUS "foo.vcxproj has debugger command set")
+ set(debuggerCommandSet TRUE)
+ endif()
+ endif()
+endforeach()
+
+if(NOT debuggerCommandSet)
+ set(RunCMake_TEST_FAILED "LocalDebuggerCommand not found or not set correctly.")
+ return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsDebuggerCommand.cmake b/Tests/RunCMake/VS10Project/VsDebuggerCommand.cmake
new file mode 100644
index 0000000..e29adc4
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsDebuggerCommand.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+add_library(foo foo.cpp)
+
+set_target_properties(foo PROPERTIES
+ VS_DEBUGGER_COMMAND "my-debugger-command")
diff --git a/Tests/RunCMake/export/ForbiddenToExportImportedProperties-result.txt b/Tests/RunCMake/export/ForbiddenToExportImportedProperties-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/export/ForbiddenToExportImportedProperties-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/export/ForbiddenToExportImportedProperties-stderr.txt b/Tests/RunCMake/export/ForbiddenToExportImportedProperties-stderr.txt
new file mode 100644
index 0000000..ab03943
--- /dev/null
+++ b/Tests/RunCMake/export/ForbiddenToExportImportedProperties-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+ Target \"foo\" contains property \"IMPORTED_FOOBAR\" in EXPORT_PROPERTIES but
+ IMPORTED_\* and INTERFACE_\* properties are reserved.
diff --git a/Tests/RunCMake/export/ForbiddenToExportImportedProperties.cmake b/Tests/RunCMake/export/ForbiddenToExportImportedProperties.cmake
new file mode 100644
index 0000000..9c8653d
--- /dev/null
+++ b/Tests/RunCMake/export/ForbiddenToExportImportedProperties.cmake
@@ -0,0 +1,12 @@
+enable_language(CXX)
+add_library(foo empty.cpp)
+set_target_properties(foo PROPERTIES
+ IMPORTED_FOOBAR "Some other string"
+ EXPORT_PROPERTIES "IMPORTED_FOOBAR"
+)
+export(TARGETS foo FILE "${CMAKE_CURRENT_BINARY_DIR}/foo.cmake")
+install(TARGETS foo EXPORT fooExport
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib
+)
diff --git a/Tests/RunCMake/export/ForbiddenToExportInterfaceProperties-result.txt b/Tests/RunCMake/export/ForbiddenToExportInterfaceProperties-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/export/ForbiddenToExportInterfaceProperties-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/export/ForbiddenToExportInterfaceProperties-stderr.txt b/Tests/RunCMake/export/ForbiddenToExportInterfaceProperties-stderr.txt
new file mode 100644
index 0000000..577602b
--- /dev/null
+++ b/Tests/RunCMake/export/ForbiddenToExportInterfaceProperties-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+ Target \"foo\" contains property \"INTERFACE_FOOBAR\" in EXPORT_PROPERTIES but
+ IMPORTED_\* and INTERFACE_\* properties are reserved.
diff --git a/Tests/RunCMake/export/ForbiddenToExportInterfaceProperties.cmake b/Tests/RunCMake/export/ForbiddenToExportInterfaceProperties.cmake
new file mode 100644
index 0000000..bab8de0
--- /dev/null
+++ b/Tests/RunCMake/export/ForbiddenToExportInterfaceProperties.cmake
@@ -0,0 +1,12 @@
+enable_language(CXX)
+add_library(foo empty.cpp)
+set_target_properties(foo PROPERTIES
+ INTERFACE_FOOBAR "Some string"
+ EXPORT_PROPERTIES "INTERFACE_FOOBAR"
+)
+export(TARGETS foo FILE "${CMAKE_CURRENT_BINARY_DIR}/foo.cmake")
+install(TARGETS foo EXPORT fooExport
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib
+)
diff --git a/Tests/RunCMake/export/ForbiddenToExportPropertyWithGenExp-result.txt b/Tests/RunCMake/export/ForbiddenToExportPropertyWithGenExp-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/export/ForbiddenToExportPropertyWithGenExp-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/export/ForbiddenToExportPropertyWithGenExp-stderr.txt b/Tests/RunCMake/export/ForbiddenToExportPropertyWithGenExp-stderr.txt
new file mode 100644
index 0000000..56488e6
--- /dev/null
+++ b/Tests/RunCMake/export/ForbiddenToExportPropertyWithGenExp-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+ Target \"foo\" contains property \"JUST_A_PROPERTY\" in EXPORT_PROPERTIES but
+ this property contains a generator expression. This is not allowed.
diff --git a/Tests/RunCMake/export/ForbiddenToExportPropertyWithGenExp.cmake b/Tests/RunCMake/export/ForbiddenToExportPropertyWithGenExp.cmake
new file mode 100644
index 0000000..065cdbc
--- /dev/null
+++ b/Tests/RunCMake/export/ForbiddenToExportPropertyWithGenExp.cmake
@@ -0,0 +1,12 @@
+enable_language(CXX)
+add_library(foo empty.cpp)
+set_target_properties(foo PROPERTIES
+ JUST_A_PROPERTY "$<C_COMPILER_VERSION:0>"
+ EXPORT_PROPERTIES "JUST_A_PROPERTY"
+)
+export(TARGETS foo FILE "${CMAKE_CURRENT_BINARY_DIR}/foo.cmake")
+install(TARGETS foo EXPORT fooExport
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib
+)
diff --git a/Tests/RunCMake/export/RunCMakeTest.cmake b/Tests/RunCMake/export/RunCMakeTest.cmake
index 6d0b7ca..10ced90 100644
--- a/Tests/RunCMake/export/RunCMakeTest.cmake
+++ b/Tests/RunCMake/export/RunCMakeTest.cmake
@@ -5,3 +5,6 @@ run_cmake(TargetNotFound)
run_cmake(AppendExport)
run_cmake(OldIface)
run_cmake(NoExportSet)
+run_cmake(ForbiddenToExportInterfaceProperties)
+run_cmake(ForbiddenToExportImportedProperties)
+run_cmake(ForbiddenToExportPropertyWithGenExp)
diff --git a/Tests/RunCMake/export/empty.cpp b/Tests/RunCMake/export/empty.cpp
new file mode 100644
index 0000000..11ec041
--- /dev/null
+++ b/Tests/RunCMake/export/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+ int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/find_package/CMP0074-OLD-stderr.txt b/Tests/RunCMake/find_package/CMP0074-OLD-stderr.txt
new file mode 100644
index 0000000..4c2e517
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0074-OLD-stderr.txt
@@ -0,0 +1,12 @@
+----------
+Foo_ROOT :<base>/foo/cmake_root
+ENV{Foo_ROOT} :<base>/foo/env_root
+
+find_package\(Foo\)
+FOO_TEST_FILE_FOO :FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT :FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT :FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
diff --git a/Tests/RunCMake/find_package/CMP0074-OLD.cmake b/Tests/RunCMake/find_package/CMP0074-OLD.cmake
new file mode 100644
index 0000000..4358317
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0074-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0074 OLD)
+include(CMP0074-common.cmake)
diff --git a/Tests/RunCMake/find_package/CMP0074-WARN-stderr.txt b/Tests/RunCMake/find_package/CMP0074-WARN-stderr.txt
new file mode 100644
index 0000000..27fbb86
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0074-WARN-stderr.txt
@@ -0,0 +1,32 @@
+----------
+Foo_ROOT :<base>/foo/cmake_root
+ENV{Foo_ROOT} :<base>/foo/env_root
++
+CMake Warning \(dev\) at CMP0074-common.cmake:[0-9]+ \(find_package\):
+ Policy CMP0074 is not set: find_package uses PackageName_ROOT variables.
+ Run "cmake --help-policy CMP0074" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+
+ CMake variable Foo_ROOT is set to:
+
+ .*/Tests/RunCMake/find_package/PackageRoot/foo/cmake_root
+
+ Environment variable Foo_ROOT is set to:
+
+ .*/Tests/RunCMake/find_package/PackageRoot/foo/env_root
+
+ For compatibility, CMake is ignoring the variable.
+Call Stack \(most recent call first\):
+ CMP0074-common.cmake:[0-9]+ \(RunPackageRootTest\)
+ CMP0074-WARN.cmake:[0-9]+ \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
++
+find_package\(Foo\)
+FOO_TEST_FILE_FOO :FOO_TEST_FILE_FOO-NOTFOUND
+FOO_TEST_FILE_ZOT :FOO_TEST_FILE_ZOT-NOTFOUND
+FOO_TEST_PATH_FOO :FOO_TEST_PATH_FOO-NOTFOUND
+FOO_TEST_PATH_ZOT :FOO_TEST_PATH_ZOT-NOTFOUND
+FOO_TEST_PROG_FOO :FOO_TEST_PROG_FOO-NOTFOUND
+
+----------
diff --git a/Tests/RunCMake/find_package/CMP0074-WARN.cmake b/Tests/RunCMake/find_package/CMP0074-WARN.cmake
new file mode 100644
index 0000000..0d4ada7
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0074-WARN.cmake
@@ -0,0 +1,2 @@
+# (do not set CMP0074)
+include(CMP0074-common.cmake)
diff --git a/Tests/RunCMake/find_package/CMP0074-common.cmake b/Tests/RunCMake/find_package/CMP0074-common.cmake
new file mode 100644
index 0000000..bfacd82
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0074-common.cmake
@@ -0,0 +1,46 @@
+# (includer selects CMP0074)
+cmake_policy(SET CMP0057 NEW)
+list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
+set(PackageRoot_BASE ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
+
+function(PrintPath label path)
+ string(REPLACE "${PackageRoot_BASE}" "<base>" out "${path}")
+ message("${label}${out}")
+endfunction()
+
+macro(CleanUpPackageRootTest)
+ unset(Foo_ROOT)
+ unset(ENV{Foo_ROOT})
+ unset(FOO_TEST_FILE_FOO)
+ unset(FOO_TEST_FILE_ZOT)
+ unset(FOO_TEST_PATH_FOO)
+ unset(FOO_TEST_PATH_ZOT)
+ unset(FOO_TEST_PROG_FOO)
+ unset(FOO_TEST_FILE_FOO CACHE)
+ unset(FOO_TEST_FILE_ZOT CACHE)
+ unset(FOO_TEST_PATH_FOO CACHE)
+ unset(FOO_TEST_PATH_ZOT CACHE)
+ unset(FOO_TEST_PROG_FOO CACHE)
+endmacro()
+
+macro(RunPackageRootTest)
+ message("----------")
+ PrintPath("Foo_ROOT :" "${Foo_ROOT}")
+ PrintPath("ENV{Foo_ROOT} :" "$ENV{Foo_ROOT}")
+ message("")
+
+ find_package(Foo)
+ message("find_package(Foo)")
+ PrintPath("FOO_TEST_FILE_FOO :" "${FOO_TEST_FILE_FOO}")
+ PrintPath("FOO_TEST_FILE_ZOT :" "${FOO_TEST_FILE_ZOT}")
+ PrintPath("FOO_TEST_PATH_FOO :" "${FOO_TEST_PATH_FOO}")
+ PrintPath("FOO_TEST_PATH_ZOT :" "${FOO_TEST_PATH_ZOT}")
+ PrintPath("FOO_TEST_PROG_FOO :" "${FOO_TEST_PROG_FOO}")
+ CleanUpPackageRootTest()
+ message("")
+endmacro()
+
+set(Foo_ROOT ${PackageRoot_BASE}/foo/cmake_root)
+set(ENV{Foo_ROOT} ${PackageRoot_BASE}/foo/env_root)
+RunPackageRootTest()
+message("----------")
diff --git a/Tests/RunCMake/find_package/PackageRoot.cmake b/Tests/RunCMake/find_package/PackageRoot.cmake
index 4c4f4c2..aa12e9b 100644
--- a/Tests/RunCMake/find_package/PackageRoot.cmake
+++ b/Tests/RunCMake/find_package/PackageRoot.cmake
@@ -1,5 +1,5 @@
-set(__UNDOCUMENTED_CMAKE_FIND_PACKAGE_ROOT 1)
cmake_policy(SET CMP0057 NEW)
+cmake_policy(SET CMP0074 NEW)
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
set(PackageRoot_BASE ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
diff --git a/Tests/RunCMake/find_package/PackageRootNestedConfig.cmake b/Tests/RunCMake/find_package/PackageRootNestedConfig.cmake
index ba06c09..1ef32cb 100644
--- a/Tests/RunCMake/find_package/PackageRootNestedConfig.cmake
+++ b/Tests/RunCMake/find_package/PackageRootNestedConfig.cmake
@@ -1,5 +1,5 @@
-set(__UNDOCUMENTED_CMAKE_FIND_PACKAGE_ROOT 1)
cmake_policy(SET CMP0057 NEW)
+cmake_policy(SET CMP0074 NEW)
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
set(PackageRoot_BASE ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
diff --git a/Tests/RunCMake/find_package/PackageRootNestedModule.cmake b/Tests/RunCMake/find_package/PackageRootNestedModule.cmake
index 2795cd4..017834c 100644
--- a/Tests/RunCMake/find_package/PackageRootNestedModule.cmake
+++ b/Tests/RunCMake/find_package/PackageRootNestedModule.cmake
@@ -1,5 +1,5 @@
-set(__UNDOCUMENTED_CMAKE_FIND_PACKAGE_ROOT 1)
cmake_policy(SET CMP0057 NEW)
+cmake_policy(SET CMP0074 NEW)
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
set(PackageRoot_BASE ${CMAKE_CURRENT_SOURCE_DIR}/PackageRoot)
diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake
index d548da0..c068402 100644
--- a/Tests/RunCMake/find_package/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake
@@ -1,5 +1,7 @@
include(RunCMake)
+run_cmake(CMP0074-WARN)
+run_cmake(CMP0074-OLD)
run_cmake(ComponentRequiredAndOptional)
run_cmake(MissingNormal)
run_cmake(MissingNormalRequired)
diff --git a/Tests/RunCMake/list/JOIN-NoArguments-result.txt b/Tests/RunCMake/list/JOIN-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/JOIN-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/JOIN-NoArguments-stderr.txt b/Tests/RunCMake/list/JOIN-NoArguments-stderr.txt
new file mode 100644
index 0000000..5e1b98f
--- /dev/null
+++ b/Tests/RunCMake/list/JOIN-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at JOIN-NoArguments.cmake:1 \(list\):
+ list sub-command JOIN requires three arguments \(1 found\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/JOIN-NoArguments.cmake b/Tests/RunCMake/list/JOIN-NoArguments.cmake
new file mode 100644
index 0000000..2ab449a
--- /dev/null
+++ b/Tests/RunCMake/list/JOIN-NoArguments.cmake
@@ -0,0 +1 @@
+list(JOIN mylist)
diff --git a/Tests/RunCMake/list/JOIN-NoVariable-result.txt b/Tests/RunCMake/list/JOIN-NoVariable-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/JOIN-NoVariable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/JOIN-NoVariable-stderr.txt b/Tests/RunCMake/list/JOIN-NoVariable-stderr.txt
new file mode 100644
index 0000000..db1d773
--- /dev/null
+++ b/Tests/RunCMake/list/JOIN-NoVariable-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at JOIN-NoVariable.cmake:1 \(list\):
+ list sub-command JOIN requires three arguments \(2 found\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/JOIN-NoVariable.cmake b/Tests/RunCMake/list/JOIN-NoVariable.cmake
new file mode 100644
index 0000000..b60d8f1
--- /dev/null
+++ b/Tests/RunCMake/list/JOIN-NoVariable.cmake
@@ -0,0 +1 @@
+list(JOIN mylist "glue")
diff --git a/Tests/RunCMake/list/JOIN-TooManyArguments-result.txt b/Tests/RunCMake/list/JOIN-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/JOIN-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/JOIN-TooManyArguments-stderr.txt b/Tests/RunCMake/list/JOIN-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..2b09e22
--- /dev/null
+++ b/Tests/RunCMake/list/JOIN-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at JOIN-TooManyArguments.cmake:1 \(list\):
+ list sub-command JOIN requires three arguments \(4 found\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/JOIN-TooManyArguments.cmake b/Tests/RunCMake/list/JOIN-TooManyArguments.cmake
new file mode 100644
index 0000000..dc651f6
--- /dev/null
+++ b/Tests/RunCMake/list/JOIN-TooManyArguments.cmake
@@ -0,0 +1 @@
+list(JOIN mylist "glue" out one_too_many)
diff --git a/Tests/RunCMake/list/JOIN.cmake b/Tests/RunCMake/list/JOIN.cmake
new file mode 100644
index 0000000..24a623e
--- /dev/null
+++ b/Tests/RunCMake/list/JOIN.cmake
@@ -0,0 +1,18 @@
+list(JOIN undefList % out)
+if(NOT out STREQUAL "")
+ message(FATAL_ERROR "\"list(JOIN undefList % out)\" set out to \"${out}\"")
+endif()
+set(myList a)
+list(JOIN myList % out)
+if(NOT out STREQUAL "a")
+ message(FATAL_ERROR "\"list(JOIN \"a\" % out)\" set out to \"${out}\"")
+endif()
+set(myList a b)
+list(JOIN myList % out)
+if(NOT out STREQUAL "a%b")
+ message(FATAL_ERROR "\"list(JOIN \"a;b\" % out)\" set out to \"${out}\"")
+endif()
+list(JOIN myList "" out)
+if(NOT out STREQUAL "ab")
+ message(FATAL_ERROR "\"list(JOIN \"a;b\" \"\" out a)\" set out to \"${out}\"")
+endif()
diff --git a/Tests/RunCMake/list/RunCMakeTest.cmake b/Tests/RunCMake/list/RunCMakeTest.cmake
index b002ab3..1be4f85 100644
--- a/Tests/RunCMake/list/RunCMakeTest.cmake
+++ b/Tests/RunCMake/list/RunCMakeTest.cmake
@@ -15,6 +15,7 @@ run_cmake(INSERT-InvalidIndex)
run_cmake(REMOVE_AT-InvalidIndex)
run_cmake(FILTER-REGEX-TooManyArguments)
+run_cmake(JOIN-TooManyArguments)
run_cmake(LENGTH-TooManyArguments)
run_cmake(REMOVE_DUPLICATES-TooManyArguments)
run_cmake(REVERSE-TooManyArguments)
@@ -31,3 +32,7 @@ run_cmake(FILTER-REGEX-InvalidMode)
run_cmake(FILTER-REGEX-InvalidOperator)
run_cmake(FILTER-REGEX-Valid0)
run_cmake(FILTER-REGEX-Valid1)
+
+run_cmake(JOIN-NoArguments)
+run_cmake(JOIN-NoVariable)
+run_cmake(JOIN)
diff --git a/Tests/RunCMake/project/ProjectDescriptionNoArg.cmake b/Tests/RunCMake/project/ProjectDescriptionNoArg.cmake
index 64bac54..25acff8 100644
--- a/Tests/RunCMake/project/ProjectDescriptionNoArg.cmake
+++ b/Tests/RunCMake/project/ProjectDescriptionNoArg.cmake
@@ -1,2 +1,2 @@
cmake_policy(SET CMP0048 NEW)
-project(ProjectDescriptionTest VERSION 1.0.0 DESCRIPTION)
+project(ProjectDescriptionTest VERSION 1.0.0 LANGUAGES NONE DESCRIPTION)
diff --git a/Tests/RunCMake/project/ProjectHomepage-stdout.txt b/Tests/RunCMake/project/ProjectHomepage-stdout.txt
new file mode 100644
index 0000000..253990f
--- /dev/null
+++ b/Tests/RunCMake/project/ProjectHomepage-stdout.txt
@@ -0,0 +1,3 @@
+-- PROJECT_HOMEPAGE_URL=http://example.com
+-- CMAKE_PROJECT_HOMEPAGE_URL=http://example.com
+-- ProjectHomepageTest_HOMEPAGE_URL=http://example.com
diff --git a/Tests/RunCMake/project/ProjectHomepage.cmake b/Tests/RunCMake/project/ProjectHomepage.cmake
new file mode 100644
index 0000000..3307f1f
--- /dev/null
+++ b/Tests/RunCMake/project/ProjectHomepage.cmake
@@ -0,0 +1,14 @@
+cmake_policy(SET CMP0048 NEW)
+project(ProjectHomepageTest VERSION 1.0.0 HOMEPAGE_URL "http://example.com" LANGUAGES)
+if(NOT PROJECT_HOMEPAGE_URL)
+ message(FATAL_ERROR "PROJECT_HOMEPAGE_URL expected to be set")
+endif()
+if(NOT CMAKE_PROJECT_HOMEPAGE_URL)
+ message(FATAL_ERROR "CMAKE_PROJECT_HOMEPAGE_URL expected to be set")
+endif()
+if(NOT ProjectHomepageTest_HOMEPAGE_URL)
+ message(FATAL_ERROR "ProjectHomepageTest_HOMEPAGE_URL expected to be set")
+endif()
+message(STATUS "PROJECT_HOMEPAGE_URL=${PROJECT_HOMEPAGE_URL}")
+message(STATUS "CMAKE_PROJECT_HOMEPAGE_URL=${CMAKE_PROJECT_HOMEPAGE_URL}")
+message(STATUS "ProjectHomepageTest_HOMEPAGE_URL=${ProjectHomepageTest_HOMEPAGE_URL}")
diff --git a/Tests/RunCMake/project/ProjectHomepage2-result.txt b/Tests/RunCMake/project/ProjectHomepage2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/project/ProjectHomepage2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/project/ProjectHomepage2-stderr.txt b/Tests/RunCMake/project/ProjectHomepage2-stderr.txt
new file mode 100644
index 0000000..4a0adc2
--- /dev/null
+++ b/Tests/RunCMake/project/ProjectHomepage2-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at ProjectHomepage2.cmake:2 \(project\):
+ HOMEPAGE_URL may be specified at most once.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/project/ProjectHomepage2.cmake b/Tests/RunCMake/project/ProjectHomepage2.cmake
new file mode 100644
index 0000000..184c392
--- /dev/null
+++ b/Tests/RunCMake/project/ProjectHomepage2.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0048 NEW)
+project(ProjectDescriptionTest VERSION 1.0.0 HOMEPAGE_URL "http://example.com" HOMEPAGE_URL "http://example.com" LANGUAGES)
diff --git a/Tests/RunCMake/project/ProjectHomepageNoArg-stderr.txt b/Tests/RunCMake/project/ProjectHomepageNoArg-stderr.txt
new file mode 100644
index 0000000..c9503b7
--- /dev/null
+++ b/Tests/RunCMake/project/ProjectHomepageNoArg-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Warning at ProjectHomepageNoArg.cmake:2 \(project\):
+ HOMEPAGE_URL keyword not followed by a value or was followed by a value
+ that expanded to nothing.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/project/ProjectHomepageNoArg.cmake b/Tests/RunCMake/project/ProjectHomepageNoArg.cmake
new file mode 100644
index 0000000..4605541
--- /dev/null
+++ b/Tests/RunCMake/project/ProjectHomepageNoArg.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0048 NEW)
+project(ProjectDescriptionTest VERSION 1.0.0 LANGUAGES NONE HOMEPAGE_URL)
diff --git a/Tests/RunCMake/project/RunCMakeTest.cmake b/Tests/RunCMake/project/RunCMakeTest.cmake
index f77c15d..e9fb929 100644
--- a/Tests/RunCMake/project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/project/RunCMakeTest.cmake
@@ -12,6 +12,9 @@ run_cmake(ProjectDescription)
run_cmake(ProjectDescription2)
run_cmake(ProjectDescriptionNoArg)
run_cmake(ProjectDescriptionNoArg2)
+run_cmake(ProjectHomepage)
+run_cmake(ProjectHomepage2)
+run_cmake(ProjectHomepageNoArg)
run_cmake(VersionAndLanguagesEmpty)
run_cmake(VersionEmpty)
run_cmake(VersionInvalid)
diff --git a/Tests/RunCMake/project/VersionMissingLanguages-stderr.txt b/Tests/RunCMake/project/VersionMissingLanguages-stderr.txt
index 1139df7..576ac69 100644
--- a/Tests/RunCMake/project/VersionMissingLanguages-stderr.txt
+++ b/Tests/RunCMake/project/VersionMissingLanguages-stderr.txt
@@ -1,5 +1,5 @@
CMake Error at VersionMissingLanguages.cmake:2 \(project\):
- project with VERSION or DESCRIPTION must use LANGUAGES before language
- names.
+ project with VERSION, DESCRIPTION or HOMEPAGE_URL must use LANGUAGES before
+ language names.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/set_property/RunCMakeTest.cmake b/Tests/RunCMake/set_property/RunCMakeTest.cmake
index 5b5327d..b966e89 100644
--- a/Tests/RunCMake/set_property/RunCMakeTest.cmake
+++ b/Tests/RunCMake/set_property/RunCMakeTest.cmake
@@ -9,3 +9,4 @@ run_cmake(LINK_LIBRARIES)
run_cmake(SOURCES)
run_cmake(TYPE)
run_cmake(USER_PROP)
+run_cmake(USER_PROP_INHERITED)
diff --git a/Tests/RunCMake/set_property/USER_PROP_INHERITED-stdout.txt b/Tests/RunCMake/set_property/USER_PROP_INHERITED-stdout.txt
new file mode 100644
index 0000000..dcb0f87
--- /dev/null
+++ b/Tests/RunCMake/set_property/USER_PROP_INHERITED-stdout.txt
@@ -0,0 +1,29 @@
+-- TopDir-to-nothing chaining: ''
+-- TopDir-to-global chaining: 'vGlobal'
+-- TopDir no chaining required: 'vTopDir'
+-- TopDir unset append chaining: 'aTopDir'
+-- TopDir preset append chaining: 'vTopDir;aTopDir'
+-- Subdir-to-parent chaining: 'vTopDir'
+-- Subdir-to-global chaining: 'vGlobal'
+-- Subdir no chaining required: 'vSubdir'
+-- Subdir preset append chaining: 'vSubdir;aSubdir'
+-- Subdir unset append chaining: 'aSubdir'
+-- Subdir undefined append chaining: 'aSubdir'
+-- Target-to-directory chaining: 'vTopDir'
+-- Target unset append chaining: 'aTarget'
+-- Target no chaining required: 'vTarget'
+-- Target preset append chaining: 'vTarget;aTarget'
+-- Target undefined get chaining: ''
+-- Target undefined append chaining: 'aTarget'
+-- Source-to-directory chaining: 'vTopDir'
+-- Source unset append chaining: 'aSource'
+-- Source no chaining required: 'vSource'
+-- Source preset append chaining: 'vSource;aSource'
+-- Source undefined get chaining: ''
+-- Source undefined append chaining: 'aSource'
+-- Test-to-directory chaining: 'vTopDir'
+-- Test unset append chaining: 'aTest'
+-- Test no chaining required: 'vTest'
+-- Test preset append chaining: 'vTest;aTest'
+-- Test undefined get chaining: ''
+-- Test undefined append chaining: 'aTest'
diff --git a/Tests/RunCMake/set_property/USER_PROP_INHERITED.cmake b/Tests/RunCMake/set_property/USER_PROP_INHERITED.cmake
new file mode 100644
index 0000000..2429866
--- /dev/null
+++ b/Tests/RunCMake/set_property/USER_PROP_INHERITED.cmake
@@ -0,0 +1,83 @@
+# Needed for source property tests
+enable_language(C)
+
+#=================================================
+# Directory property chaining
+#=================================================
+
+foreach(i RANGE 1 5)
+ foreach(propType DIRECTORY TARGET SOURCE TEST)
+ define_property(${propType} PROPERTY USER_PROP${i} INHERITED
+ BRIEF_DOCS "Brief" FULL_DOCS "Full"
+ )
+ endforeach()
+endforeach()
+
+get_property(val DIRECTORY PROPERTY USER_PROP1)
+message(STATUS "TopDir-to-nothing chaining: '${val}'")
+
+set_property(GLOBAL PROPERTY USER_PROP1 vGlobal)
+set_property(GLOBAL PROPERTY USER_PROP2 vGlobal)
+set_property(DIRECTORY PROPERTY USER_PROP2 vTopDir)
+set_property(GLOBAL PROPERTY USER_PROP3 vGlobal)
+set_property(DIRECTORY PROPERTY USER_PROP4 vTopDir)
+
+get_property(val DIRECTORY PROPERTY USER_PROP1)
+message(STATUS "TopDir-to-global chaining: '${val}'")
+
+get_property(val DIRECTORY PROPERTY USER_PROP2)
+message(STATUS "TopDir no chaining required: '${val}'")
+
+set_property(DIRECTORY APPEND PROPERTY USER_PROP3 aTopDir)
+get_property(val DIRECTORY PROPERTY USER_PROP3)
+message(STATUS "TopDir unset append chaining: '${val}'")
+
+set_property(DIRECTORY APPEND PROPERTY USER_PROP4 aTopDir)
+get_property(val DIRECTORY PROPERTY USER_PROP4)
+message(STATUS "TopDir preset append chaining: '${val}'")
+
+add_subdirectory(USER_PROP_INHERITED)
+
+#=================================================
+# The other property types all chain the same way
+#=================================================
+macro(__chainToDirTests propType)
+ string(TOUPPER ${propType} propTypeUpper)
+
+ get_property(val ${propTypeUpper} ${propType}1 PROPERTY USER_PROP2)
+ message(STATUS "${propType}-to-directory chaining: '${val}'")
+
+ set_property(${propTypeUpper} ${propType}1 APPEND PROPERTY USER_PROP2 a${propType})
+ get_property(val ${propTypeUpper} ${propType}1 PROPERTY USER_PROP2)
+ message(STATUS "${propType} unset append chaining: '${val}'")
+
+ set_property(${propTypeUpper} ${propType}1 PROPERTY USER_PROP1 v${propType})
+ get_property(val ${propTypeUpper} ${propType}1 PROPERTY USER_PROP1)
+ message(STATUS "${propType} no chaining required: '${val}'")
+
+ set_property(${propTypeUpper} ${propType}1 APPEND PROPERTY USER_PROP1 a${propType})
+ get_property(val ${propTypeUpper} ${propType}1 PROPERTY USER_PROP1)
+ message(STATUS "${propType} preset append chaining: '${val}'")
+
+ get_property(val ${propTypeUpper} ${propType}2 PROPERTY USER_PROP5)
+ message(STATUS "${propType} undefined get chaining: '${val}'")
+
+ set_property(${propTypeUpper} ${propType}2 APPEND PROPERTY USER_PROP5 a${propType})
+ get_property(val ${propTypeUpper} ${propType}2 PROPERTY USER_PROP5)
+ message(STATUS "${propType} undefined append chaining: '${val}'")
+endmacro()
+
+add_custom_target(Target1)
+add_custom_target(Target2)
+__chainToDirTests(Target)
+
+foreach(i RANGE 1 2)
+ set(Source${i} "${CMAKE_CURRENT_BINARY_DIR}/src${i}.c")
+ file(WRITE ${Source${i}} "int foo${i}() { return ${i}; }")
+endforeach()
+add_library(srcProps OBJECT ${Source1} ${Source2})
+__chainToDirTests(Source)
+
+add_test(NAME Test1 COMMAND ${CMAKE_COMMAND} -E touch_nocreate iDoNotExist)
+add_test(NAME Test2 COMMAND ${CMAKE_COMMAND} -E touch_nocreate iDoNotExist)
+__chainToDirTests(Test)
diff --git a/Tests/RunCMake/set_property/USER_PROP_INHERITED/CMakeLists.txt b/Tests/RunCMake/set_property/USER_PROP_INHERITED/CMakeLists.txt
new file mode 100644
index 0000000..234f4ee
--- /dev/null
+++ b/Tests/RunCMake/set_property/USER_PROP_INHERITED/CMakeLists.txt
@@ -0,0 +1,21 @@
+get_property(val DIRECTORY PROPERTY USER_PROP2)
+message(STATUS "Subdir-to-parent chaining: '${val}'")
+
+get_property(val DIRECTORY PROPERTY USER_PROP1)
+message(STATUS "Subdir-to-global chaining: '${val}'")
+
+set_property(DIRECTORY PROPERTY USER_PROP1 vSubdir)
+get_property(val DIRECTORY PROPERTY USER_PROP1)
+message(STATUS "Subdir no chaining required: '${val}'")
+
+set_property(DIRECTORY APPEND PROPERTY USER_PROP1 aSubdir)
+get_property(val DIRECTORY PROPERTY USER_PROP1)
+message(STATUS "Subdir preset append chaining: '${val}'")
+
+set_property(DIRECTORY APPEND PROPERTY USER_PROP2 aSubdir)
+get_property(val DIRECTORY PROPERTY USER_PROP2)
+message(STATUS "Subdir unset append chaining: '${val}'")
+
+set_property(DIRECTORY APPEND PROPERTY USER_PROP5 aSubdir)
+get_property(val DIRECTORY PROPERTY USER_PROP5)
+message(STATUS "Subdir undefined append chaining: '${val}'")
diff --git a/Tests/Server/CMakeLists.txt b/Tests/Server/CMakeLists.txt
index 41d1131..8321edb 100644
--- a/Tests/Server/CMakeLists.txt
+++ b/Tests/Server/CMakeLists.txt
@@ -1,10 +1,10 @@
cmake_minimum_required(VERSION 3.4)
project(Server CXX)
-find_package(PythonInterp REQUIRED)
+find_package(Python REQUIRED)
macro(do_test bsname file type)
- execute_process(COMMAND ${PYTHON_EXECUTABLE}
+ execute_process(COMMAND ${Python_EXECUTABLE}
-B # no .pyc files
"${CMAKE_SOURCE_DIR}/${type}-test.py"
"${CMAKE_COMMAND}"