summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/command/project.rst23
-rw-r--r--Help/manual/cmake-properties.7.rst2
-rw-r--r--Help/manual/cmake-variables.7.rst4
-rw-r--r--Help/prop_tgt/EXPORT_PROPERTIES.rst14
-rw-r--r--Help/prop_tgt/VS_DEBUGGER_COMMAND.rst9
-rw-r--r--Help/release/3.10.rst17
-rw-r--r--Help/release/dev/export-properties.rst6
-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/GoogleTest.cmake21
-rw-r--r--Source/CMakeVersion.cmake2
-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/cmProjectCommand.cxx49
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx152
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h10
-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/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt (renamed from Tests/RunCMake/GoogleTest/GoogleTest-timeout-result.txt)0
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-stdout.txt (renamed from Tests/RunCMake/GoogleTest/GoogleTest-timeout-stdout.txt)2
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-property-timeout1-result.txt1
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-property-timeout1-stderr.txt1
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-property-timeout1-stdout.txt10
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-property-timeout2-result.txt1
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-property-timeout2-stderr.txt1
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-property-timeout2-stdout.txt10
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-test-missing-stderr.txt2
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest.cmake34
-rw-r--r--Tests/RunCMake/GoogleTest/RunCMakeTest.cmake27
-rw-r--r--Tests/RunCMake/GoogleTest/no_tests_defined.cpp4
-rw-r--r--Tests/RunCMake/GoogleTest/timeout_test.cpp30
-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/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
68 files changed, 634 insertions, 114 deletions
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/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/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/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/3.10.rst b/Help/release/3.10.rst
index 6a19dbf..1205b17 100644
--- a/Help/release/3.10.rst
+++ b/Help/release/3.10.rst
@@ -139,7 +139,8 @@ Modules
This is robust against unusual ways of labeling tests, provides much better
support for advanced features such as parameterized tests, and does not
require re-running CMake to discover added or removed tests within a test
- executable.
+ executable. Note that a breaking change was made in CMake 3.10.3 to address
+ an ambiguity of the ``TIMEOUT`` keyword (see :ref:`Release Notes 3.10.3`).
* The :module:`InstallRequiredSystemLibraries` module gained support
for installing Intel compiler runtimes.
@@ -267,3 +268,17 @@ Changes made since CMake 3.10.0 include the following.
* The :manual:`cmake-server(7)` ``codemodel`` response ``crossReferences``
field added by 3.10.0 has been dropped due to excessive memory usage.
Another approach will be needed to provide backtrace information.
+
+.. _`Release Notes 3.10.3`:
+
+3.10.3
+------
+
+* CMake 3.10.1 added a ``TIMEOUT`` option to :command:`gtest_discover_tests`
+ from the :module:`GoogleTest` module. That keyword clashed with the
+ ``TIMEOUT`` test property, which is one of the common properties that
+ would be set with the command's ``PROPERTIES`` keyword, usually leading
+ to legal but unintended behavior. The keyword was changed to
+ ``DISCOVERY_TIMEOUT`` in CMake 3.10.3 to address this problem. The
+ ambiguous behavior of the :command:`gtest_discover_tests` command's
+ ``TIMEOUT`` keyword in 3.10.1 and 3.10.2 has not been preserved.
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/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/GoogleTest.cmake b/Modules/GoogleTest.cmake
index c525101..bfb83e1 100644
--- a/Modules/GoogleTest.cmake
+++ b/Modules/GoogleTest.cmake
@@ -150,6 +150,7 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
[NO_PRETTY_TYPES] [NO_PRETTY_VALUES]
[PROPERTIES name1 value1...]
[TEST_LIST var]
+ [DISCOVERY_TIMEOUT seconds]
)
``gtest_discover_tests`` sets up a post-build command on the test executable
@@ -217,7 +218,7 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
executable is being used in multiple calls to ``gtest_discover_tests()``.
Note that this variable is only available in CTest.
- ``TIMEOUT num``
+ ``DISCOVERY_TIMEOUT num``
Specifies how long (in seconds) CMake will wait for the test to enumerate
available tests. If the test takes longer than this, discovery (and your
build) will fail. Most test executables will enumerate their tests very
@@ -225,6 +226,16 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
longer timeout. The default is 5. See also the ``TIMEOUT`` option of
:command:`execute_process`.
+ .. note::
+
+ In CMake versions 3.10.1 and 3.10.2, this option was called ``TIMEOUT``.
+ This clashed with the ``TIMEOUT`` test property, which is one of the
+ common properties that would be set with the ``PROPERTIES`` keyword,
+ usually leading to legal but unintended behavior. The keyword was
+ changed to ``DISCOVERY_TIMEOUT`` in CMake 3.10.3 to address this
+ problem. The ambiguous behavior of the ``TIMEOUT`` keyword in 3.10.1
+ and 3.10.2 has not been preserved.
+
#]=======================================================================]
#------------------------------------------------------------------------------
@@ -357,7 +368,7 @@ function(gtest_discover_tests TARGET)
cmake_parse_arguments(
""
"NO_PRETTY_TYPES;NO_PRETTY_VALUES"
- "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;TIMEOUT"
+ "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;DISCOVERY_TIMEOUT"
"EXTRA_ARGS;PROPERTIES"
${ARGN}
)
@@ -368,8 +379,8 @@ function(gtest_discover_tests TARGET)
if(NOT _TEST_LIST)
set(_TEST_LIST ${TARGET}_TESTS)
endif()
- if(NOT _TIMEOUT)
- set(_TIMEOUT 5)
+ if(NOT _DISCOVERY_TIMEOUT)
+ set(_DISCOVERY_TIMEOUT 5)
endif()
get_property(
@@ -418,7 +429,7 @@ function(gtest_discover_tests TARGET)
-D "NO_PRETTY_VALUES=${_NO_PRETTY_VALUES}"
-D "TEST_LIST=${_TEST_LIST}"
-D "CTEST_FILE=${ctest_tests_file}"
- -D "TEST_DISCOVERY_TIMEOUT=${_TIMEOUT}"
+ -D "TEST_DISCOVERY_TIMEOUT=${_DISCOVERY_TIMEOUT}"
-P "${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}"
VERBATIM
)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 184082a..ca63858 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 20180319)
#set(CMake_VERSION_RC 1)
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/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/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 0fd8043..87d3c78 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -18,6 +18,42 @@
#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(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);
+ S << "</" << tag << ">\n";
+ } else {
+ S << " />\n";
+ }
+ }
+};
+
inline void cmVisualStudio10TargetGenerator::WriteElem(const char* tag,
const char* val,
int indentLevel)
@@ -787,7 +823,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 +831,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 +852,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 +1185,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 +1242,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
}
}
if (this->ProjectType != csproj) {
- this->WriteString("</CustomBuild>\n", 2);
+ e2.WriteEndTag("CustomBuild");
}
}
@@ -1473,24 +1513,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 +1679,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 +1777,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 +1819,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 +1841,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 +1910,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 +1918,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 +1937,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 +1998,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 +2025,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 +2100,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 +2118,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 +2189,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/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/RunCMake/GoogleTest/GoogleTest-timeout-result.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt
index d197c91..d197c91 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest-timeout-result.txt
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-timeout-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-stdout.txt
index 8464c80..3a6572c 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest-timeout-stdout.txt
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-stdout.txt
@@ -1,7 +1,7 @@
( *|[0-9]+>)CMake Error at .*GoogleTestAddTests.cmake:[0-9]+ \(message\):
( *|[0-9]+>) Error running test executable.
?( *|[0-9]+>)
-( *|[0-9]+>) Path: '.*timeout_test(\.exe)?'
+( *|[0-9]+>) Path: '.*discovery_timeout_test(\.exe)?'
( *|[0-9]+>) Result: Process terminated due to timeout
( *|[0-9]+>) Output:
( *|[0-9]+>) +
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout1-result.txt b/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout1-result.txt
new file mode 100644
index 0000000..d197c91
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout1-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout1-stderr.txt b/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout1-stderr.txt
new file mode 100644
index 0000000..ba4235d
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout1-stderr.txt
@@ -0,0 +1 @@
+Errors while running CTest
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout1-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout1-stdout.txt
new file mode 100644
index 0000000..0dda49d
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout1-stdout.txt
@@ -0,0 +1,10 @@
+Test project .*GoogleTest-build
+[ \t]*Start [0-9]+: property_timeout.case_no_discovery
+[^\n]+property_timeout.case_no_discovery +\.+\*\*\*Timeout +[0-9.]+ sec
++
+0% tests passed, 1 tests failed out of 1
++
+Total Test time \(real\) = +[0-9.]+ sec
++
+The following tests FAILED:
+[^\n]*property_timeout.case_no_discovery \(Timeout\)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout2-result.txt b/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout2-result.txt
new file mode 100644
index 0000000..d197c91
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout2-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout2-stderr.txt b/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout2-stderr.txt
new file mode 100644
index 0000000..ba4235d
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout2-stderr.txt
@@ -0,0 +1 @@
+Errors while running CTest
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout2-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout2-stdout.txt
new file mode 100644
index 0000000..72cea55
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-property-timeout2-stdout.txt
@@ -0,0 +1,10 @@
+Test project .*GoogleTest-build
+[ \t]*Start [0-9]+: property_timeout.case_with_discovery
+[^\n]+property_timeout.case_with_discovery +\.+\*\*\*Timeout +[0-9.]+ sec
++
+0% tests passed, 1 tests failed out of 1
++
+Total Test time \(real\) = +[0-9.]+ sec
++
+The following tests FAILED:
+[^\n]*property_timeout.case_with_discovery \(Timeout\)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-test-missing-stderr.txt b/Tests/RunCMake/GoogleTest/GoogleTest-test-missing-stderr.txt
index 55a4a7a..a4cc971 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest-test-missing-stderr.txt
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-test-missing-stderr.txt
@@ -1,2 +1,2 @@
-Unable to find executable: timeout_test_NOT_BUILT
+Unable to find executable: no_tests_defined_NOT_BUILT
Errors while running CTest
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest.cmake b/Tests/RunCMake/GoogleTest/GoogleTest.cmake
index 5e4b8ef..31808c6 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest.cmake
+++ b/Tests/RunCMake/GoogleTest/GoogleTest.cmake
@@ -22,8 +22,38 @@ gtest_discover_tests(
PROPERTIES LABELS TEST2
)
-add_executable(timeout_test timeout_test.cpp)
+add_executable(no_tests_defined no_tests_defined.cpp)
gtest_discover_tests(
- timeout_test
+ no_tests_defined
+)
+
+# Note change in behavior of TIMEOUT keyword in 3.10.3
+# where it was renamed to DISCOVERY_TIMEOUT to prevent it
+# from shadowing the TIMEOUT test property. Verify the
+# 3.10.3 and later behavior, old behavior added in 3.10.1
+# is not supported.
+add_executable(property_timeout_test timeout_test.cpp)
+target_compile_definitions(property_timeout_test PRIVATE sleepSec=10)
+
+gtest_discover_tests(
+ property_timeout_test
+ TEST_PREFIX property_
+ TEST_SUFFIX _no_discovery
+ PROPERTIES TIMEOUT 2
+)
+gtest_discover_tests(
+ property_timeout_test
+ TEST_PREFIX property_
+ TEST_SUFFIX _with_discovery
+ DISCOVERY_TIMEOUT 20
+ PROPERTIES TIMEOUT 2
+)
+
+add_executable(discovery_timeout_test timeout_test.cpp)
+target_compile_definitions(discovery_timeout_test PRIVATE discoverySleepSec=10)
+gtest_discover_tests(
+ discovery_timeout_test
+ TEST_PREFIX discovery_
+ DISCOVERY_TIMEOUT 2
)
diff --git a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
index 209e769..0fa4e2a 100644
--- a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
@@ -19,12 +19,19 @@ function(run_GoogleTest)
--target fake_gtest
)
+ run_cmake_command(GoogleTest-property-timeout-exe
+ ${CMAKE_COMMAND}
+ --build .
+ --config Debug
+ --target property_timeout_test
+ )
+
set(RunCMake_TEST_OUTPUT_MERGE 1)
- run_cmake_command(GoogleTest-timeout
+ run_cmake_command(GoogleTest-discovery-timeout
${CMAKE_COMMAND}
--build .
--config Debug
- --target timeout_test
+ --target discovery_timeout_test
)
set(RunCMake_TEST_OUTPUT_MERGE 0)
@@ -45,7 +52,21 @@ function(run_GoogleTest)
run_cmake_command(GoogleTest-test-missing
${CMAKE_CTEST_COMMAND}
-C Debug
- -R timeout
+ -R no_tests_defined
+ --no-label-summary
+ )
+
+ run_cmake_command(GoogleTest-property-timeout1
+ ${CMAKE_CTEST_COMMAND}
+ -C Debug
+ -R property_timeout\\.case_no_discovery
+ --no-label-summary
+ )
+
+ run_cmake_command(GoogleTest-property-timeout2
+ ${CMAKE_CTEST_COMMAND}
+ -C Debug
+ -R property_timeout\\.case_with_discovery
--no-label-summary
)
endfunction()
diff --git a/Tests/RunCMake/GoogleTest/no_tests_defined.cpp b/Tests/RunCMake/GoogleTest/no_tests_defined.cpp
new file mode 100644
index 0000000..f8b643a
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/no_tests_defined.cpp
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/GoogleTest/timeout_test.cpp b/Tests/RunCMake/GoogleTest/timeout_test.cpp
index a8e5c1c..9162dcf 100644
--- a/Tests/RunCMake/GoogleTest/timeout_test.cpp
+++ b/Tests/RunCMake/GoogleTest/timeout_test.cpp
@@ -4,12 +4,36 @@
#include <unistd.h>
#endif
-int main()
+#include <iostream>
+#include <string>
+
+void sleepFor(unsigned seconds)
{
#if defined(_WIN32)
- Sleep(10000);
+ Sleep(seconds * 1000);
#else
- sleep(10);
+ sleep(seconds);
+#endif
+}
+
+int main(int argc, char** argv)
+{
+ // Note: GoogleTest.cmake doesn't actually depend on Google Test as such;
+ // it only requires that we produce output in the expected format when
+ // invoked with --gtest_list_tests. Thus, we fake that here. This allows us
+ // to test the module without actually needing Google Test.
+ if (argc > 1 && std::string(argv[1]) == "--gtest_list_tests") {
+ std::cout << "timeout." << std::endl;
+ std::cout << " case" << std::endl;
+#ifdef discoverySleepSec
+ sleepFor(discoverySleepSec);
+#endif
+ return 0;
+ }
+
+#ifdef sleepSec
+ sleepFor(sleepSec);
#endif
+
return 0;
}
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/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\)$