summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/command/target_compile_features.rst30
-rw-r--r--Help/manual/cmake-commands.7.rst1
-rw-r--r--Help/manual/cmake-properties.7.rst4
-rw-r--r--Help/manual/cmake-variables.7.rst4
-rw-r--r--Help/prop_tgt/COMPILE_FEATURES.rst11
-rw-r--r--Help/prop_tgt/CXX_EXTENSIONS.rst8
-rw-r--r--Help/prop_tgt/CXX_STANDARD.rst14
-rw-r--r--Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst14
-rw-r--r--Help/release/dev/compile-language-features.rst18
-rw-r--r--Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst8
-rw-r--r--Help/variable/CMAKE_CXX_EXTENSIONS.rst8
-rw-r--r--Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst18
-rw-r--r--Help/variable/CMAKE_CXX_STANDARD.rst8
-rw-r--r--Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst2
-rw-r--r--Modules/CMakeCXXCompiler.cmake.in3
-rw-r--r--Modules/CMakeDetermineCompileFeatures.cmake43
-rw-r--r--Modules/CMakeTestCXXCompiler.cmake3
-rw-r--r--Modules/Compiler/AppleClang-CXX.cmake7
-rw-r--r--Modules/Compiler/Clang-CXX.cmake18
-rw-r--r--Modules/Compiler/GNU-CXX-FeatureTests.cmake8
-rw-r--r--Modules/Compiler/GNU-CXX.cmake25
-rw-r--r--Modules/Internal/FeatureTesting.cmake57
-rw-r--r--Source/CMakeLists.txt1
-rw-r--r--Source/cmExportBuildFileGenerator.cxx3
-rw-r--r--Source/cmExportInstallFileGenerator.cxx4
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h3
-rw-r--r--Source/cmLocalGenerator.cxx39
-rw-r--r--Source/cmLocalGenerator.h2
-rw-r--r--Source/cmMakefile.cxx133
-rw-r--r--Source/cmMakefile.h4
-rw-r--r--Source/cmTarget.cxx159
-rw-r--r--Source/cmTarget.h3
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.cxx3
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.h2
-rw-r--r--Source/cmTargetCompileFeaturesCommand.cxx70
-rw-r--r--Source/cmTargetCompileFeaturesCommand.h41
-rw-r--r--Source/cmTargetCompileOptionsCommand.cxx3
-rw-r--r--Source/cmTargetCompileOptionsCommand.h2
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.cxx3
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.h2
-rw-r--r--Source/cmTargetPropCommandBase.cxx14
-rw-r--r--Source/cmTargetPropCommandBase.h4
-rw-r--r--Source/cmTargetSourcesCommand.cxx3
-rw-r--r--Source/cmTargetSourcesCommand.h2
-rw-r--r--Tests/CMakeCommands/target_compile_features/CMakeLists.txt17
-rw-r--r--Tests/CMakeCommands/target_compile_features/dummy.cpp5
-rw-r--r--Tests/CMakeCommands/target_compile_features/lib_auto_type.cpp6
-rw-r--r--Tests/CMakeCommands/target_compile_features/lib_auto_type.h8
-rw-r--r--Tests/CMakeCommands/target_compile_features/lib_user.cpp7
-rw-r--r--Tests/CMakeCommands/target_compile_features/main.cpp6
-rw-r--r--Tests/CMakeLists.txt18
-rw-r--r--Tests/CompileFeatures/CMakeLists.txt36
-rw-r--r--Tests/CompileFeatures/cxx_auto_type.cpp5
-rw-r--r--Tests/CompileFeatures/main.cpp6
-rw-r--r--Tests/CxxDialect/CMakeLists.txt14
-rw-r--r--Tests/CxxDialect/use_constexpr.cxx10
-rw-r--r--Tests/CxxDialect/use_constexpr_and_typeof.cxx11
-rw-r--r--Tests/CxxDialect/use_typeof.cxx6
-rw-r--r--Tests/ExportImport/Export/Interface/CMakeLists.txt5
-rw-r--r--Tests/ExportImport/Import/CMakeLists.txt1
-rw-r--r--Tests/ExportImport/Import/Interface/CMakeLists.txt17
-rw-r--r--Tests/RunCMake/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/CompileFeatures/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature-stderr.txt2
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature.cmake3
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeatureGenex-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeatureGenex-stderr.txt2
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeatureGenex.cmake3
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-stderr.txt2
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeatureTransitive.cmake6
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-stderr.txt11
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug.cmake4
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-stderr.txt11
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex.cmake4
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-stderr.txt11
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive.cmake6
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug_target_compile_features-result.txt1
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug_target_compile_features-stderr.txt5
-rw-r--r--Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug_target_compile_features.cmake4
-rw-r--r--Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake9
-rw-r--r--Tests/RunCMake/CompileFeatures/empty.cpp7
-rw-r--r--Tests/RunCMake/target_compile_features/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/target_compile_features/RunCMakeTest.cmake11
-rw-r--r--Tests/RunCMake/target_compile_features/alias_target-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/alias_target-stderr.txt4
-rw-r--r--Tests/RunCMake/target_compile_features/alias_target.cmake4
-rw-r--r--Tests/RunCMake/target_compile_features/empty.cpp7
-rw-r--r--Tests/RunCMake/target_compile_features/imported_target-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/imported_target-stderr.txt4
-rw-r--r--Tests/RunCMake/target_compile_features/imported_target.cmake3
-rw-r--r--Tests/RunCMake/target_compile_features/invalid_args-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/invalid_args-stderr.txt4
-rw-r--r--Tests/RunCMake/target_compile_features/invalid_args.cmake3
-rw-r--r--Tests/RunCMake/target_compile_features/invalid_args_on_interface-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/invalid_args_on_interface-stderr.txt5
-rw-r--r--Tests/RunCMake/target_compile_features/invalid_args_on_interface.cmake3
-rw-r--r--Tests/RunCMake/target_compile_features/no_matching_cxx_feature-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/no_matching_cxx_feature-stderr.txt8
-rw-r--r--Tests/RunCMake/target_compile_features/no_matching_cxx_feature.cmake26
-rw-r--r--Tests/RunCMake/target_compile_features/no_target-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/no_target-stderr.txt5
-rw-r--r--Tests/RunCMake/target_compile_features/no_target.cmake2
-rw-r--r--Tests/RunCMake/target_compile_features/not_a_cxx_feature-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/not_a_cxx_feature-stderr.txt5
-rw-r--r--Tests/RunCMake/target_compile_features/not_a_cxx_feature.cmake6
-rw-r--r--Tests/RunCMake/target_compile_features/not_enough_args-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/not_enough_args-stderr.txt4
-rw-r--r--Tests/RunCMake/target_compile_features/not_enough_args.cmake3
-rw-r--r--Tests/RunCMake/target_compile_features/utility_target-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_features/utility_target-stderr.txt4
-rw-r--r--Tests/RunCMake/target_compile_features/utility_target.cmake4
-rw-r--r--Tests/SystemInformation/CMakeLists.txt2
-rw-r--r--Tests/SystemInformation/SystemInformation.in6
118 files changed, 1209 insertions, 21 deletions
diff --git a/Help/command/target_compile_features.rst b/Help/command/target_compile_features.rst
new file mode 100644
index 0000000..f8e5c54
--- /dev/null
+++ b/Help/command/target_compile_features.rst
@@ -0,0 +1,30 @@
+target_compile_features
+-----------------------
+
+Add expected compiler features to a target.
+
+::
+
+ target_compile_features(<target> <PRIVATE|PUBLIC|INTERFACE> <feature> [...])
+
+Specify compiler features required when compiling a given target. If the
+feature is not listed in the :variable:`CMAKE_CXX_COMPILE_FEATURES` variable,
+then an error will be reported by CMake. If the use of the feature requires
+an additional compiler flag, such as ``-std=c++11``, the flag will be added
+automatically.
+
+The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
+specify the scope of the features. ``PRIVATE`` and ``PUBLIC`` items will
+populate the :prop_tgt:`COMPILE_FEATURES` property of ``<target>``.
+``PUBLIC`` and ``INTERFACE`` items will populate the
+:prop_tgt:`INTERFACE_COMPILE_FEATURES` property of ``<target>``. Repeated
+calls for the same ``<target>`` append items.
+
+The named ``<target>`` must have been created by a command such as
+:command:`add_executable` or :command:`add_library` and must not be
+an ``IMPORTED`` target.
+
+Arguments to ``target_compile_features`` may use "generator expressions"
+with the syntax ``$<...>``.
+See the :manual:`cmake-generator-expressions(7)` manual for available
+expressions.
diff --git a/Help/manual/cmake-commands.7.rst b/Help/manual/cmake-commands.7.rst
index 4b1dbed..17c3236 100644
--- a/Help/manual/cmake-commands.7.rst
+++ b/Help/manual/cmake-commands.7.rst
@@ -91,6 +91,7 @@ These commands may be used freely in CMake projects.
/command/source_group
/command/string
/command/target_compile_definitions
+ /command/target_compile_features
/command/target_compile_options
/command/target_include_directories
/command/target_link_libraries
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index fd16eb9..a82522d 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -98,6 +98,7 @@ Properties on Targets
/prop_tgt/COMPATIBLE_INTERFACE_STRING
/prop_tgt/COMPILE_DEFINITIONS_CONFIG
/prop_tgt/COMPILE_DEFINITIONS
+ /prop_tgt/COMPILE_FEATURES
/prop_tgt/COMPILE_FLAGS
/prop_tgt/COMPILE_OPTIONS
/prop_tgt/COMPILE_PDB_NAME
@@ -106,6 +107,8 @@ Properties on Targets
/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG
/prop_tgt/CONFIG_OUTPUT_NAME
/prop_tgt/CONFIG_POSTFIX
+ /prop_tgt/CXX_STANDARD
+ /prop_tgt/CXX_EXTENSIONS
/prop_tgt/DEBUG_POSTFIX
/prop_tgt/DEFINE_SYMBOL
/prop_tgt/EchoString
@@ -148,6 +151,7 @@ Properties on Targets
/prop_tgt/INSTALL_RPATH_USE_LINK_PATH
/prop_tgt/INTERFACE_AUTOUIC_OPTIONS
/prop_tgt/INTERFACE_COMPILE_DEFINITIONS
+ /prop_tgt/INTERFACE_COMPILE_FEATURES
/prop_tgt/INTERFACE_COMPILE_OPTIONS
/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES
/prop_tgt/INTERFACE_LINK_LIBRARIES
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 4fac6a5..dfdd09b 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -257,6 +257,10 @@ Variables for Languages
:maxdepth: 1
/variable/CMAKE_COMPILER_IS_GNULANG
+ /variable/CMAKE_CXX_COMPILE_FEATURES
+ /variable/CMAKE_CXX_KNOWN_FEATURES
+ /variable/CMAKE_CXX_STANDARD
+ /variable/CMAKE_CXX_EXTENSIONS
/variable/CMAKE_Fortran_MODDIR_DEFAULT
/variable/CMAKE_Fortran_MODDIR_FLAG
/variable/CMAKE_Fortran_MODOUT_FLAG
diff --git a/Help/prop_tgt/COMPILE_FEATURES.rst b/Help/prop_tgt/COMPILE_FEATURES.rst
new file mode 100644
index 0000000..dc32825
--- /dev/null
+++ b/Help/prop_tgt/COMPILE_FEATURES.rst
@@ -0,0 +1,11 @@
+COMPILE_FEATURES
+----------------
+
+Compiler features enabled for this target.
+
+The list of features in this property are a subset of the features listed
+in the :variable:`CMAKE_CXX_COMPILE_FEATURES` variable.
+
+Contents of ``COMPILE_FEATURES`` may use "generator expressions" with the
+syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for
+available expressions.
diff --git a/Help/prop_tgt/CXX_EXTENSIONS.rst b/Help/prop_tgt/CXX_EXTENSIONS.rst
new file mode 100644
index 0000000..b9c9931
--- /dev/null
+++ b/Help/prop_tgt/CXX_EXTENSIONS.rst
@@ -0,0 +1,8 @@
+CXX_EXTENSIONS
+--------------
+
+Boolean specifying whether compiler specific extensions are requested.
+
+This property specifies whether compiler specific extensions should be
+used. For some compilers, this results in adding a flag such
+as ``-std=gnu++11`` instead of ``-std=c++11`` to the compile line.
diff --git a/Help/prop_tgt/CXX_STANDARD.rst b/Help/prop_tgt/CXX_STANDARD.rst
new file mode 100644
index 0000000..e1b6e78
--- /dev/null
+++ b/Help/prop_tgt/CXX_STANDARD.rst
@@ -0,0 +1,14 @@
+CXX_STANDARD
+------------
+
+The C++ standard whose features are required to build this target.
+
+This property specifies the C++ standard whose features are required
+to build this target. For some compilers, this results in adding a
+flag such as ``-std=c++11`` to the compile line.
+
+Supported values are ``98`` and ``11``.
+
+This property is initialized by the value of
+the :variable:`CMAKE_CXX_STANDARD` variable if it is set when a target
+is created.
diff --git a/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
new file mode 100644
index 0000000..a98e362
--- /dev/null
+++ b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
@@ -0,0 +1,14 @@
+INTERFACE_COMPILE_FEATURES
+--------------------------
+
+List of public compile requirements for a library.
+
+Targets may populate this property to publish the compiler features
+required to compile against the headers for the target. Consuming
+targets can add entries to their own :prop_tgt:`COMPILE_FEATURES`
+property such as ``$<TARGET_PROPERTY:foo,INTERFACE_COMPILE_FEATURES>``
+to require the features specified in the interface of ``foo``.
+
+Contents of ``INTERFACE_COMPILE_FEATURES`` may use "generator expressions"
+with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions.
diff --git a/Help/release/dev/compile-language-features.rst b/Help/release/dev/compile-language-features.rst
new file mode 100644
index 0000000..3c5d7ca
--- /dev/null
+++ b/Help/release/dev/compile-language-features.rst
@@ -0,0 +1,18 @@
+target-language-features
+------------------------
+
+* New :prop_tgt:`CXX_STANDARD` and :prop_tgt:`CXX_EXTENSIONS` target
+ properties may specify values which CMake uses to compute required
+ compile options such as ``-std=c++11`` or ``-std=gnu++11``. The
+ :variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_EXTENSIONS`
+ variables may be set to initialize the target properties.
+
+* New :prop_tgt:`COMPILE_FEATURES` target property may contain a list
+ of features required to compile a target. CMake uses this
+ information to ensure that the compiler in use is capable of building
+ the target, and to add any necessary compile flags to support language
+ features.
+
+* New :command:`target_compile_features` command allows populating the
+ :prop_tgt:`COMPILE_FEATURES` target property, just like any other
+ build variable.
diff --git a/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
new file mode 100644
index 0000000..6be0124
--- /dev/null
+++ b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
@@ -0,0 +1,8 @@
+CMAKE_CXX_COMPILE_FEATURES
+--------------------------
+
+List of features known to the C++ compiler
+
+These features are known to be available for use with the C++ compiler. This
+list is a subset of the features listed in the :variable:`CMAKE_CXX_KNOWN_FEATURES`
+variable.
diff --git a/Help/variable/CMAKE_CXX_EXTENSIONS.rst b/Help/variable/CMAKE_CXX_EXTENSIONS.rst
new file mode 100644
index 0000000..734d508
--- /dev/null
+++ b/Help/variable/CMAKE_CXX_EXTENSIONS.rst
@@ -0,0 +1,8 @@
+CMAKE_CXX_EXTENSIONS
+--------------------
+
+Default value for ``CXX_EXTENSIONS`` property of targets.
+
+This variable is used to initialize the :prop_tgt:`CXX_EXTENSIONS`
+property on all targets. See that target property for additional
+information.
diff --git a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
new file mode 100644
index 0000000..3278b2e
--- /dev/null
+++ b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
@@ -0,0 +1,18 @@
+CMAKE_CXX_KNOWN_FEATURES
+------------------------
+
+List of C++ features known to this version of CMake.
+
+The features listed in this variable may be known to be available to the
+C++ compiler. If the feature is available with the C++ compiler, it will
+be listed in the :variable:`CMAKE_CXX_COMPILE_FEATURES` variable.
+
+The features listed here may be used with the :command:`target_compile_features`
+command.
+
+The features known to this version of CMake are:
+
+``cxx_auto_type``
+ Automatic type deduction, as defined in N1984_.
+
+ .. _N1984: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf
diff --git a/Help/variable/CMAKE_CXX_STANDARD.rst b/Help/variable/CMAKE_CXX_STANDARD.rst
new file mode 100644
index 0000000..5fd4138
--- /dev/null
+++ b/Help/variable/CMAKE_CXX_STANDARD.rst
@@ -0,0 +1,8 @@
+CMAKE_CXX_STANDARD
+------------------
+
+Default value for ``CXX_STANDARD`` property of targets.
+
+This variable is used to initialize the :prop_tgt:`CXX_STANDARD`
+property on all targets. See that target property for additional
+information.
diff --git a/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst b/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst
index edd8fa1..e200b86 100644
--- a/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst
+++ b/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst
@@ -7,7 +7,7 @@ This variable can be populated with a list of properties to generate
debug output for when evaluating target properties. Currently it can
only be used when evaluating the :prop_tgt:`INCLUDE_DIRECTORIES`,
:prop_tgt:`COMPILE_DEFINITIONS`, :prop_tgt:`COMPILE_OPTIONS`,
-:prop_tgt:`AUTOUIC_OPTIONS`, :prop_tgt:`SOURCES`,
+:prop_tgt:`AUTOUIC_OPTIONS`, :prop_tgt:`SOURCES`, :prop_tgt:`COMPILE_FEATURES`,
:prop_tgt:`POSITION_INDEPENDENT_CODE` target properties and any other property
listed in :prop_tgt:`COMPATIBLE_INTERFACE_STRING` and other ``COMPATIBLE_INTERFACE_``
properties. It outputs an origin for each entry in the target property.
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index c75611a..fdee336 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -2,6 +2,9 @@ set(CMAKE_CXX_COMPILER "@CMAKE_CXX_COMPILER@")
set(CMAKE_CXX_COMPILER_ARG1 "@CMAKE_CXX_COMPILER_ARG1@")
set(CMAKE_CXX_COMPILER_ID "@CMAKE_CXX_COMPILER_ID@")
set(CMAKE_CXX_COMPILER_VERSION "@CMAKE_CXX_COMPILER_VERSION@")
+set(CMAKE_CXX_COMPILE_FEATURES "@CMAKE_CXX_COMPILE_FEATURES@")
+set(CMAKE_CXX11_COMPILE_FEATURES "@CMAKE_CXX11_COMPILE_FEATURES@")
+
set(CMAKE_CXX_PLATFORM_ID "@CMAKE_CXX_PLATFORM_ID@")
set(CMAKE_CXX_SIMULATE_ID "@CMAKE_CXX_SIMULATE_ID@")
set(CMAKE_CXX_SIMULATE_VERSION "@CMAKE_CXX_SIMULATE_VERSION@")
diff --git a/Modules/CMakeDetermineCompileFeatures.cmake b/Modules/CMakeDetermineCompileFeatures.cmake
new file mode 100644
index 0000000..40aa9d6
--- /dev/null
+++ b/Modules/CMakeDetermineCompileFeatures.cmake
@@ -0,0 +1,43 @@
+
+#=============================================================================
+# Copyright 2013 Stephen Kelly <steveire@gmail.com>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+function(cmake_determine_compile_features lang)
+
+ if(lang STREQUAL CXX AND COMMAND cmake_record_cxx_compile_features)
+ message(STATUS "Detecting ${lang} compile features")
+
+ set(CMAKE_CXX11_COMPILE_FEATURES)
+
+ include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake")
+
+ cmake_record_cxx_compile_features()
+
+ if(NOT _result EQUAL 0)
+ message(STATUS "Detecting ${lang} compile features - failed")
+ return()
+ endif()
+
+ if(NOT CMAKE_CXX_COMPILE_FEATURES)
+ set(CMAKE_CXX_COMPILE_FEATURES
+ ${CMAKE_CXX11_COMPILE_FEATURES}
+ )
+ endif()
+
+ set(CMAKE_CXX_COMPILE_FEATURES ${CMAKE_CXX_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_CXX11_COMPILE_FEATURES ${CMAKE_CXX11_COMPILE_FEATURES} PARENT_SCOPE)
+
+ message(STATUS "Detecting ${lang} compile features - done")
+ endif()
+
+endfunction()
diff --git a/Modules/CMakeTestCXXCompiler.cmake b/Modules/CMakeTestCXXCompiler.cmake
index a06c92a..81561b2 100644
--- a/Modules/CMakeTestCXXCompiler.cmake
+++ b/Modules/CMakeTestCXXCompiler.cmake
@@ -66,6 +66,9 @@ else()
# Try to identify the ABI and configure it into CMakeCXXCompiler.cmake
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
CMAKE_DETERMINE_COMPILER_ABI(CXX ${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp)
+ # Try to identify the compiler features
+ include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
+ CMAKE_DETERMINE_COMPILE_FEATURES(CXX)
# Re-configure to save learned information.
configure_file(
diff --git a/Modules/Compiler/AppleClang-CXX.cmake b/Modules/Compiler/AppleClang-CXX.cmake
index 680f720..0372e18 100644
--- a/Modules/Compiler/AppleClang-CXX.cmake
+++ b/Modules/Compiler/AppleClang-CXX.cmake
@@ -1 +1,6 @@
-include(Compiler/Clang-CXX)
+include(Compiler/Clang)
+__compiler_clang(CXX)
+
+if(NOT CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
+ set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
+endif()
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index 0372e18..a1b3a10 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -4,3 +4,21 @@ __compiler_clang(CXX)
if(NOT CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
endif()
+
+cmake_policy(GET CMP0025 appleClangPolicy)
+if(NOT appleClangPolicy STREQUAL NEW)
+ return()
+endif()
+
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1)
+ set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++98")
+ set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98")
+endif()
+
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.1)
+ set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11")
+ set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11")
+elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1)
+ set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++0x")
+ set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x")
+endif()
diff --git a/Modules/Compiler/GNU-CXX-FeatureTests.cmake b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
new file mode 100644
index 0000000..b36315f
--- /dev/null
+++ b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
@@ -0,0 +1,8 @@
+
+# Reference: http://gcc.gnu.org/projects/cxx0x.html
+
+set(_oldestSupported "(__GNUC__ * 100 + __GNUC_MINOR__) >= 408")
+# TODO: Should be supported by GNU 4.4
+set(GNU44_CXX11 "${_oldestSupported} && __cplusplus >= 201103L")
+set(_cmake_feature_test_cxx_auto_type "${GNU44_CXX11}")
+set(_oldestSupported)
diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake
index 33d6093..7acad52 100644
--- a/Modules/Compiler/GNU-CXX.cmake
+++ b/Modules/Compiler/GNU-CXX.cmake
@@ -10,3 +10,28 @@ else()
set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
endif()
endif()
+
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.3)
+ set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++98")
+ set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98")
+endif()
+
+if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
+ set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11")
+ set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11")
+elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.3)
+ set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++0x")
+ set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x")
+endif()
+
+macro(cmake_record_cxx_compile_features)
+ macro(_get_gcc_features std_version list)
+ record_compiler_features(CXX "-std=${std_version}" ${list})
+ endmacro()
+
+ if (UNIX AND NOT APPLE AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
+ _get_gcc_features(c++11 CMAKE_CXX11_COMPILE_FEATURES)
+ else()
+ set(_result 0)
+ endif()
+endmacro()
diff --git a/Modules/Internal/FeatureTesting.cmake b/Modules/Internal/FeatureTesting.cmake
new file mode 100644
index 0000000..92d262c
--- /dev/null
+++ b/Modules/Internal/FeatureTesting.cmake
@@ -0,0 +1,57 @@
+
+macro(record_compiler_features lang compile_flags feature_list)
+ include("${CMAKE_ROOT}/Modules/Compiler/${CMAKE_${lang}_COMPILER_ID}-${lang}-FeatureTests.cmake" OPTIONAL)
+
+ string(TOLOWER ${lang} lang_lc)
+ file(REMOVE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin")
+ file(WRITE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" "
+ extern const char features[] = {\"\"\n")
+ foreach(feature ${CMAKE_${lang}_KNOWN_FEATURES})
+ if (_cmake_feature_test_${feature})
+ if (${_cmake_feature_test_${feature}} STREQUAL 1)
+ set(_feature_condition "\"1\" ")
+ else()
+ set(_feature_condition "#if ${_cmake_feature_test_${feature}}\n\"1\"\n#else\n\"0\"\n#endif\n")
+ endif()
+ file(APPEND "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" "\"${lang}_FEATURE:\"\n${_feature_condition}\"${feature}\\n\"\n")
+ endif()
+ endforeach()
+ file(APPEND "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}"
+ "\n};\n\nint main(int, char **) { return 0; }\n")
+
+ try_compile(CMAKE_${lang}_FEATURE_TEST
+ ${CMAKE_BINARY_DIR} "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}"
+ COMPILE_DEFINITIONS "${compile_flags}"
+ OUTPUT_VARIABLE _output
+ COPY_FILE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin"
+ COPY_FILE_ERROR _copy_error
+ )
+ if(CMAKE_${lang}_FEATURE_TEST AND NOT _copy_error)
+ set(_result 0)
+ else()
+ set(_result 255)
+ endif()
+ unset(CMAKE_${lang}_FEATURE_TEST CACHE)
+
+ if (_result EQUAL 0)
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "\n\nDetecting ${lang} [${compile_flags}] compiler features compiled with the following output:\n${_output}\n\n")
+ if(EXISTS "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin")
+ file(STRINGS "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin"
+ features REGEX "${lang}_FEATURE:.*")
+ foreach(info ${features})
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ " Feature record: ${info}\n")
+ string(REPLACE "${lang}_FEATURE:" "" info ${info})
+ string(SUBSTRING ${info} 0 1 has_feature)
+ if(has_feature)
+ string(REGEX REPLACE "^1" "" feature ${info})
+ list(APPEND ${feature_list} ${feature})
+ endif()
+ endforeach()
+ endif()
+ else()
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Detecting ${lang} [${compile_flags}] compiler features failed to compile with the following output:\n${_output}\n${_copy_error}\n\n")
+ endif()
+endmacro()
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 4c678d8..660c0c5 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -346,6 +346,7 @@ foreach(command_file
cmSourceGroupCommand
cmSubdirDependsCommand
cmTargetCompileDefinitionsCommand
+ cmTargetCompileFeaturesCommand
cmTargetCompileOptionsCommand
cmTargetIncludeDirectoriesCommand
cmTargetSourcesCommand
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index e79206d..6c8ebb6 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -85,6 +85,9 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
this->PopulateInterfaceProperty("INTERFACE_AUTOUIC_OPTIONS", te,
cmGeneratorExpression::BuildInterface,
properties, missingTargets);
+ this->PopulateInterfaceProperty("INTERFACE_COMPILE_FEATURES", te,
+ cmGeneratorExpression::BuildInterface,
+ properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
te, properties);
const bool newCMP0022Behavior =
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index a83a228..89071c0 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -149,6 +149,10 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
te,
cmGeneratorExpression::InstallInterface,
properties, missingTargets);
+ this->PopulateInterfaceProperty("INTERFACE_COMPILE_FEATURES",
+ te,
+ cmGeneratorExpression::InstallInterface,
+ properties, missingTargets);
const bool newCMP0022Behavior =
te->GetPolicyStatusCMP0022() != cmPolicies::WARN
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index b3147f7..7217a56 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -26,7 +26,8 @@
SELECT(F, EvaluatingCompileDefinitions, COMPILE_DEFINITIONS) \
SELECT(F, EvaluatingCompileOptions, COMPILE_OPTIONS) \
SELECT(F, EvaluatingAutoUicOptions, AUTOUIC_OPTIONS) \
- SELECT(F, EvaluatingSources, SOURCES)
+ SELECT(F, EvaluatingSources, SOURCES) \
+ SELECT(F, EvaluatingCompileFeatures, COMPILE_FEATURES)
#define CM_FOR_EACH_TRANSITIVE_PROPERTY(F) \
CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_BOTH)
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 8e56d2f..f375b5f 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1460,6 +1460,17 @@ void cmLocalGenerator::AddCompileOptions(
this->AppendFlagEscape(flags, *i);
}
}
+ std::vector<std::string> features;
+ target->GetCompileFeatures(features, config);
+ for(std::vector<std::string>::const_iterator it = features.begin();
+ it != features.end(); ++it)
+ {
+ if (!this->Makefile->AddRequiredTargetFeature(target, *it))
+ {
+ return;
+ }
+ }
+ this->AddCompilerRequirementFlag(flags, target, lang);
}
//----------------------------------------------------------------------------
@@ -2131,6 +2142,34 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags,
}
}
+//----------------------------------------------------------------------------
+void cmLocalGenerator::
+AddCompilerRequirementFlag(std::string &flags, cmTarget* target,
+ const std::string& lang)
+{
+ if (lang.empty())
+ {
+ return;
+ }
+ std::string stdProp = lang + "_STANDARD";
+ const char *standard = target->GetProperty(stdProp);
+ if (!standard)
+ {
+ return;
+ }
+ std::string extProp = lang + "_EXTENSIONS";
+ bool ext = target->GetPropertyAsBool(extProp);
+ std::string type = ext ? "EXTENSION" : "STANDARD";
+
+ std::string compile_option =
+ "CMAKE_" + lang + std::string(standard)
+ + "_" + type + "_COMPILE_OPTION";
+ if (const char *opt = target->GetMakefile()->GetDefinition(compile_option))
+ {
+ this->AppendFlags(flags, opt);
+ }
+}
+
static void AddVisibilityCompileOption(std::string &flags, cmTarget* target,
cmLocalGenerator *lg,
const std::string& lang)
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 8090b34..cf754aa 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -149,6 +149,8 @@ public:
const std::string& lang);
void AddConfigVariableFlags(std::string& flags, const std::string& var,
const std::string& config);
+ void AddCompilerRequirementFlag(std::string &flags, cmTarget* target,
+ const std::string& lang);
///! Append flags to a string.
virtual void AppendFlags(std::string& flags, const char* newFlags);
virtual void AppendFlagEscape(std::string& flags,
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 1328974..5004a08 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -41,6 +41,9 @@
#include <ctype.h> // for isspace
#include <assert.h>
+#define FOR_EACH_CXX_FEATURE(F) \
+ F(cxx_auto_type)
+
class cmMakefile::Internals
{
public:
@@ -2451,6 +2454,12 @@ const char* cmMakefile::GetDefinition(const std::string& name) const
{
this->Internal->VarUsageStack.top().insert(name);
}
+ if (name == "CMAKE_CXX_KNOWN_FEATURES")
+ {
+#define STRING_LIST_ELEMENT(F) ";" #F
+ return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1;
+#undef STRING_LIST_ELEMENT
+ }
const char* def = this->Internal->VarStack.top().Get(name);
if(!def)
{
@@ -4494,3 +4503,127 @@ void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm)
pm[pid] = this->GetPolicyStatus(pid);
}
}
+
+#define FEATURE_STRING(F) , #F
+
+static const char * const CXX_FEATURES[] = {
+ 0
+ FOR_EACH_CXX_FEATURE(FEATURE_STRING)
+};
+
+static const char * const CXX_STANDARDS[] = {
+ "98"
+ , "11"
+};
+
+//----------------------------------------------------------------------------
+bool cmMakefile::
+AddRequiredTargetFeature(cmTarget *target, const std::string& feature,
+ std::string *error) const
+{
+ if (cmGeneratorExpression::Find(feature) != std::string::npos)
+ {
+ target->AppendProperty("COMPILE_FEATURES", feature.c_str());
+ return true;
+ }
+ bool isCxxFeature = std::find_if(cmArrayBegin(CXX_FEATURES) + 1,
+ cmArrayEnd(CXX_FEATURES), cmStrCmp(feature))
+ != cmArrayEnd(CXX_FEATURES);
+ if (!isCxxFeature)
+ {
+ cmOStringStream e;
+ if (error)
+ {
+ e << "specified";
+ }
+ else
+ {
+ e << "Specified";
+ }
+ e << " unknown feature \"" << feature << "\" for "
+ "target \"" << target->GetName() << "\".";
+ if (error)
+ {
+ *error = e.str();
+ }
+ else
+ {
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ }
+ return false;
+ }
+
+ std::string lang = "CXX";
+
+ const char* featuresKnown =
+ this->GetDefinition("CMAKE_" + lang + "_COMPILE_FEATURES");
+
+ if (!featuresKnown || !*featuresKnown)
+ {
+ // We know of no features for the compiler at all.
+ return true;
+ }
+
+ std::vector<std::string> availableFeatures;
+ cmSystemTools::ExpandListArgument(featuresKnown, availableFeatures);
+ if (std::find(availableFeatures.begin(),
+ availableFeatures.end(),
+ feature) == availableFeatures.end())
+ {
+ cmOStringStream e;
+ e << "The compiler feature \"" << feature
+ << "\" is not known to compiler\n\""
+ << this->GetDefinition("CMAKE_" + lang + "_COMPILER_ID")
+ << "\"\nversion "
+ << this->GetDefinition("CMAKE_" + lang + "_COMPILER_VERSION") << ".";
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+
+ target->AppendProperty("COMPILE_FEATURES", feature.c_str());
+
+ bool needCxx11 = false;
+
+ if (const char *propCxx11 =
+ this->GetDefinition("CMAKE_CXX11_COMPILE_FEATURES"))
+ {
+ std::vector<std::string> props;
+ cmSystemTools::ExpandListArgument(propCxx11, props);
+ needCxx11 = std::find(props.begin(), props.end(), feature) != props.end();
+ }
+
+ const char *existingCxxStandard = target->GetProperty("CXX_STANDARD");
+ if (existingCxxStandard)
+ {
+ if (std::find_if(cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS),
+ cmStrCmp(existingCxxStandard)) == cmArrayEnd(CXX_STANDARDS))
+ {
+ cmOStringStream e;
+ e << "The CXX_STANDARD property on target \"" << target->GetName()
+ << "\" contained an invalid value: \"" << existingCxxStandard << "\".";
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ }
+ const char * const *existingCxxIt = existingCxxStandard
+ ? std::find_if(cmArrayBegin(CXX_STANDARDS),
+ cmArrayEnd(CXX_STANDARDS),
+ cmStrCmp(existingCxxStandard))
+ : cmArrayEnd(CXX_STANDARDS);
+
+ bool setCxx11 = needCxx11 && !existingCxxStandard;
+
+ if (needCxx11 && existingCxxStandard && existingCxxIt <
+ std::find_if(cmArrayBegin(CXX_STANDARDS),
+ cmArrayEnd(CXX_STANDARDS),
+ cmStrCmp("11")))
+ {
+ setCxx11 = true;
+ }
+
+ if (setCxx11)
+ {
+ target->SetProperty("CXX_STANDARD", "11");
+ }
+ return true;
+}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 7695d6e..3bccb63 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -885,6 +885,10 @@ public:
bool PolicyOptionalWarningEnabled(std::string const& var);
+ bool AddRequiredTargetFeature(cmTarget *target,
+ const std::string& feature,
+ std::string *error = 0) const;
+
protected:
// add link libraries and directories to the target
void AddGlobalLinkInformation(const std::string& name, cmTarget& target);
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 6a87342..ee6cb44 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -153,6 +153,7 @@ public:
};
std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
std::vector<TargetPropertyEntry*> CompileOptionsEntries;
+ std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
std::vector<TargetPropertyEntry*> SourceEntries;
std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries;
@@ -165,11 +166,14 @@ public:
CachedLinkInterfaceCompileDefinitionsEntries;
mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
CachedLinkInterfaceSourcesEntries;
+ mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
+ CachedLinkInterfaceCompileFeaturesEntries;
mutable std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone;
mutable std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone;
mutable std::map<std::string, bool> CacheLinkInterfaceCompileOptionsDone;
mutable std::map<std::string, bool> CacheLinkInterfaceSourcesDone;
+ mutable std::map<std::string, bool> CacheLinkInterfaceCompileFeaturesDone;
};
//----------------------------------------------------------------------------
@@ -204,6 +208,7 @@ cmTargetInternals::~cmTargetInternals()
{
deleteAndClear(this->CachedLinkInterfaceIncludeDirectoriesEntries);
deleteAndClear(this->CachedLinkInterfaceCompileOptionsEntries);
+ deleteAndClear(this->CachedLinkInterfaceCompileFeaturesEntries);
deleteAndClear(this->CachedLinkInterfaceCompileDefinitionsEntries);
deleteAndClear(this->CachedLinkInterfaceSourcesEntries);
}
@@ -227,6 +232,7 @@ cmTarget::cmTarget()
this->BuildInterfaceIncludesAppended = false;
this->DebugIncludesDone = false;
this->DebugCompileOptionsDone = false;
+ this->DebugCompileFeaturesDone = false;
this->DebugCompileDefinitionsDone = false;
this->DebugSourcesDone = false;
this->LinkImplementationLanguageIsContextDependent = true;
@@ -308,6 +314,8 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->SetPropertyDefault("MACOSX_BUNDLE", 0);
this->SetPropertyDefault("MACOSX_RPATH", 0);
this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0);
+ this->SetPropertyDefault("CXX_STANDARD", 0);
+ this->SetPropertyDefault("CXX_EXTENSIONS", 0);
}
// Collect the set of configuration types.
@@ -1803,6 +1811,17 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
new cmTargetInternals::TargetPropertyEntry(cge));
return;
}
+ if(prop == "COMPILE_FEATURES")
+ {
+ cmListFileBacktrace lfbt;
+ this->Makefile->GetBacktrace(lfbt);
+ cmGeneratorExpression ge(lfbt);
+ deleteAndClear(this->Internal->CompileFeaturesEntries);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
+ this->Internal->CompileFeaturesEntries.push_back(
+ new cmTargetInternals::TargetPropertyEntry(cge));
+ return;
+ }
if(prop == "COMPILE_DEFINITIONS")
{
cmListFileBacktrace lfbt;
@@ -1893,6 +1912,15 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
return;
}
+ if(prop == "COMPILE_FEATURES")
+ {
+ cmListFileBacktrace lfbt;
+ this->Makefile->GetBacktrace(lfbt);
+ cmGeneratorExpression ge(lfbt);
+ this->Internal->CompileFeaturesEntries.push_back(
+ new cmTargetInternals::TargetPropertyEntry(ge.Parse(value)));
+ return;
+ }
if(prop == "COMPILE_DEFINITIONS")
{
cmListFileBacktrace lfbt;
@@ -2677,6 +2705,118 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
}
//----------------------------------------------------------------------------
+static void processCompileFeatures(cmTarget const* tgt,
+ const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
+ std::vector<std::string> &options,
+ std::set<std::string> &uniqueOptions,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ const std::string& config, bool debugOptions)
+{
+ processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+ dagChecker, config, debugOptions, "features");
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::GetCompileFeatures(std::vector<std::string> &result,
+ const std::string& config) const
+{
+ std::set<std::string> uniqueFeatures;
+ cmListFileBacktrace lfbt;
+
+ cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+ this->GetName(),
+ "COMPILE_FEATURES",
+ 0, 0);
+
+ std::vector<std::string> debugProperties;
+ const char *debugProp =
+ this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+ if (debugProp)
+ {
+ cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ }
+
+ bool debugFeatures = !this->DebugCompileFeaturesDone
+ && std::find(debugProperties.begin(),
+ debugProperties.end(),
+ "COMPILE_FEATURES")
+ != debugProperties.end();
+
+ if (this->Makefile->IsGeneratingBuildSystem())
+ {
+ this->DebugCompileFeaturesDone = true;
+ }
+
+ processCompileFeatures(this,
+ this->Internal->CompileFeaturesEntries,
+ result,
+ uniqueFeatures,
+ &dagChecker,
+ config,
+ debugFeatures);
+
+ if (!this->Internal->CacheLinkInterfaceCompileFeaturesDone[config])
+ {
+ for (std::vector<cmValueWithOrigin>::const_iterator
+ it = this->Internal->LinkImplementationPropertyEntries.begin(),
+ end = this->Internal->LinkImplementationPropertyEntries.end();
+ it != end; ++it)
+ {
+ if (!cmGeneratorExpression::IsValidTargetName(it->Value)
+ && cmGeneratorExpression::Find(it->Value) == std::string::npos)
+ {
+ continue;
+ }
+ {
+ cmGeneratorExpression ge(lfbt);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(it->Value);
+ std::string targetResult = cge->Evaluate(this->Makefile, config,
+ false, this, 0, 0);
+ if (!this->Makefile->FindTargetToUse(targetResult))
+ {
+ continue;
+ }
+ }
+ std::string featureGenex = "$<TARGET_PROPERTY:" +
+ it->Value + ",INTERFACE_COMPILE_FEATURES>";
+ if (cmGeneratorExpression::Find(it->Value) != std::string::npos)
+ {
+ // Because it->Value is a generator expression, ensure that it
+ // evaluates to the non-empty string before being used in the
+ // TARGET_PROPERTY expression.
+ featureGenex = "$<$<BOOL:" + it->Value + ">:" + featureGenex + ">";
+ }
+ cmGeneratorExpression ge(it->Backtrace);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
+ featureGenex);
+
+ this->Internal
+ ->CachedLinkInterfaceCompileFeaturesEntries[config].push_back(
+ new cmTargetInternals::TargetPropertyEntry(cge,
+ it->Value));
+ }
+ }
+
+ processCompileFeatures(this,
+ this->Internal->CachedLinkInterfaceCompileFeaturesEntries[config],
+ result,
+ uniqueFeatures,
+ &dagChecker,
+ config,
+ debugFeatures);
+
+ if (!this->Makefile->IsGeneratingBuildSystem())
+ {
+ deleteAndClear(this->Internal->CachedLinkInterfaceCompileFeaturesEntries);
+ }
+ else
+ {
+ this->Internal->CacheLinkInterfaceCompileFeaturesDone[config] = true;
+ }
+}
+
+//----------------------------------------------------------------------------
void cmTarget::MaybeInvalidatePropertyCache(const std::string& prop)
{
// Wipe out maps caching information affected by this property.
@@ -3190,6 +3330,24 @@ const char *cmTarget::GetProperty(const std::string& prop,
}
return output.c_str();
}
+ if(prop == "COMPILE_FEATURES")
+ {
+ static std::string output;
+ output = "";
+ std::string sep;
+ typedef cmTargetInternals::TargetPropertyEntry
+ TargetPropertyEntry;
+ for (std::vector<TargetPropertyEntry*>::const_iterator
+ it = this->Internal->CompileFeaturesEntries.begin(),
+ end = this->Internal->CompileFeaturesEntries.end();
+ it != end; ++it)
+ {
+ output += sep;
+ output += (*it)->ge->GetInput();
+ sep = ";";
+ }
+ return output.c_str();
+ }
if(prop == "COMPILE_DEFINITIONS")
{
static std::string output;
@@ -6987,6 +7145,7 @@ cmTargetInternalPointer::~cmTargetInternalPointer()
{
deleteAndClear(this->Pointer->IncludeDirectoriesEntries);
deleteAndClear(this->Pointer->CompileOptionsEntries);
+ deleteAndClear(this->Pointer->CompileFeaturesEntries);
deleteAndClear(this->Pointer->CompileDefinitionsEntries);
deleteAndClear(this->Pointer->SourceEntries);
delete this->Pointer;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 0a086cb..4d8022e 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -549,6 +549,8 @@ public:
const std::string& config) const;
void GetAutoUicOptions(std::vector<std::string> &result,
const std::string& config) const;
+ void GetCompileFeatures(std::vector<std::string> &features,
+ const std::string& config) const;
bool IsNullImpliedByLinkLibraries(const std::string &p) const;
bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
@@ -715,6 +717,7 @@ private:
mutable bool DebugCompileOptionsDone;
mutable bool DebugCompileDefinitionsDone;
mutable bool DebugSourcesDone;
+ mutable bool DebugCompileFeaturesDone;
mutable std::set<std::string> LinkImplicitNullProperties;
bool BuildInterfaceIncludesAppended;
diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx
index b567252..66d8ad3 100644
--- a/Source/cmTargetCompileDefinitionsCommand.cxx
+++ b/Source/cmTargetCompileDefinitionsCommand.cxx
@@ -58,9 +58,10 @@ std::string cmTargetCompileDefinitionsCommand
}
//----------------------------------------------------------------------------
-void cmTargetCompileDefinitionsCommand
+bool cmTargetCompileDefinitionsCommand
::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
bool, bool)
{
tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content).c_str());
+ return true;
}
diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h
index 5ba9e03..b548c70 100644
--- a/Source/cmTargetCompileDefinitionsCommand.h
+++ b/Source/cmTargetCompileDefinitionsCommand.h
@@ -44,7 +44,7 @@ private:
virtual void HandleImportedTarget(const std::string &tgt);
virtual void HandleMissingTarget(const std::string &name);
- virtual void HandleDirectContent(cmTarget *tgt,
+ virtual bool HandleDirectContent(cmTarget *tgt,
const std::vector<std::string> &content,
bool prepend, bool system);
virtual std::string Join(const std::vector<std::string> &content);
diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx
new file mode 100644
index 0000000..10daad4
--- /dev/null
+++ b/Source/cmTargetCompileFeaturesCommand.cxx
@@ -0,0 +1,70 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2013 Stephen Kelly <steveire@gmail.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmTargetCompileFeaturesCommand.h"
+
+bool cmTargetCompileFeaturesCommand::InitialPass(
+ std::vector<std::string> const& args,
+ cmExecutionStatus &)
+{
+ return this->HandleArguments(args, "COMPILE_FEATURES", NO_FLAGS);
+}
+
+void cmTargetCompileFeaturesCommand
+::HandleImportedTarget(const std::string &tgt)
+{
+ cmOStringStream e;
+ e << "Cannot specify compile features for imported target \""
+ << tgt << "\".";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+void cmTargetCompileFeaturesCommand
+::HandleMissingTarget(const std::string &name)
+{
+ cmOStringStream e;
+ e << "Cannot specify compile features for target \"" << name << "\" "
+ "which is not built by this project.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+//----------------------------------------------------------------------------
+std::string cmTargetCompileFeaturesCommand
+::Join(const std::vector<std::string> &content)
+{
+ std::string defs;
+ std::string sep;
+ for(std::vector<std::string>::const_iterator it = content.begin();
+ it != content.end(); ++it)
+ {
+ defs += sep + *it;
+ sep = ";";
+ }
+ return defs;
+}
+
+//----------------------------------------------------------------------------
+bool cmTargetCompileFeaturesCommand
+::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
+ bool, bool)
+{
+ for(std::vector<std::string>::const_iterator it = content.begin();
+ it != content.end(); ++it)
+ {
+ std::string error;
+ if(!this->Makefile->AddRequiredTargetFeature(tgt, *it, &error))
+ {
+ this->SetError(error);
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/Source/cmTargetCompileFeaturesCommand.h b/Source/cmTargetCompileFeaturesCommand.h
new file mode 100644
index 0000000..fa7ae8d
--- /dev/null
+++ b/Source/cmTargetCompileFeaturesCommand.h
@@ -0,0 +1,41 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2013 Stephen Kelly <steveire@gmail.com>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmTargetCompileFeaturesCommand_h
+#define cmTargetCompileFeaturesCommand_h
+
+#include "cmTargetPropCommandBase.h"
+
+class cmTargetCompileFeaturesCommand : public cmTargetPropCommandBase
+{
+ virtual cmCommand* Clone()
+ {
+ return new cmTargetCompileFeaturesCommand;
+ }
+
+ virtual bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &status);
+
+ virtual std::string GetName() const { return "target_compile_features";}
+
+ cmTypeMacro(cmTargetCompileFeaturesCommand, cmTargetPropCommandBase);
+
+private:
+ virtual void HandleImportedTarget(const std::string &tgt);
+ virtual void HandleMissingTarget(const std::string &name);
+
+ virtual bool HandleDirectContent(cmTarget *tgt,
+ const std::vector<std::string> &content,
+ bool prepend, bool system);
+ virtual std::string Join(const std::vector<std::string> &content);
+};
+
+#endif
diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx
index 254acc7..18499fd 100644
--- a/Source/cmTargetCompileOptionsCommand.cxx
+++ b/Source/cmTargetCompileOptionsCommand.cxx
@@ -51,7 +51,7 @@ std::string cmTargetCompileOptionsCommand
}
//----------------------------------------------------------------------------
-void cmTargetCompileOptionsCommand
+bool cmTargetCompileOptionsCommand
::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
bool, bool)
{
@@ -59,4 +59,5 @@ void cmTargetCompileOptionsCommand
this->Makefile->GetBacktrace(lfbt);
cmValueWithOrigin entry(this->Join(content), lfbt);
tgt->InsertCompileOption(entry);
+ return true;
}
diff --git a/Source/cmTargetCompileOptionsCommand.h b/Source/cmTargetCompileOptionsCommand.h
index d58dc07..d43534d 100644
--- a/Source/cmTargetCompileOptionsCommand.h
+++ b/Source/cmTargetCompileOptionsCommand.h
@@ -44,7 +44,7 @@ private:
virtual void HandleImportedTarget(const std::string &tgt);
virtual void HandleMissingTarget(const std::string &name);
- virtual void HandleDirectContent(cmTarget *tgt,
+ virtual bool HandleDirectContent(cmTarget *tgt,
const std::vector<std::string> &content,
bool prepend, bool system);
virtual std::string Join(const std::vector<std::string> &content);
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index f8e1188..caec7eb 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -66,7 +66,7 @@ std::string cmTargetIncludeDirectoriesCommand
}
//----------------------------------------------------------------------------
-void cmTargetIncludeDirectoriesCommand
+bool cmTargetIncludeDirectoriesCommand
::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
bool prepend, bool system)
{
@@ -78,6 +78,7 @@ void cmTargetIncludeDirectoriesCommand
{
tgt->AddSystemIncludeDirectories(content);
}
+ return true;
}
//----------------------------------------------------------------------------
diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h
index c8b22fb..2a7814e 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.h
+++ b/Source/cmTargetIncludeDirectoriesCommand.h
@@ -45,7 +45,7 @@ private:
virtual void HandleImportedTarget(const std::string &tgt);
virtual void HandleMissingTarget(const std::string &name);
- virtual void HandleDirectContent(cmTarget *tgt,
+ virtual bool HandleDirectContent(cmTarget *tgt,
const std::vector<std::string> &content,
bool prepend, bool system);
virtual void HandleInterfaceContent(cmTarget *tgt,
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index d356611..4696de4 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -132,29 +132,31 @@ bool cmTargetPropCommandBase
|| args[i] == "PRIVATE"
|| args[i] == "INTERFACE" )
{
- this->PopulateTargetProperies(scope, content, prepend, system);
- return true;
+ return this->PopulateTargetProperies(scope, content, prepend, system);
}
content.push_back(args[i]);
}
- this->PopulateTargetProperies(scope, content, prepend, system);
- return true;
+ return this->PopulateTargetProperies(scope, content, prepend, system);
}
//----------------------------------------------------------------------------
-void cmTargetPropCommandBase
+bool cmTargetPropCommandBase
::PopulateTargetProperies(const std::string &scope,
const std::vector<std::string> &content,
bool prepend, bool system)
{
if (scope == "PRIVATE" || scope == "PUBLIC")
{
- this->HandleDirectContent(this->Target, content, prepend, system);
+ if (!this->HandleDirectContent(this->Target, content, prepend, system))
+ {
+ return false;
+ }
}
if (scope == "INTERFACE" || scope == "PUBLIC")
{
this->HandleInterfaceContent(this->Target, content, prepend, system);
}
+ return true;
}
//----------------------------------------------------------------------------
diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h
index 555a08a..d42b588 100644
--- a/Source/cmTargetPropCommandBase.h
+++ b/Source/cmTargetPropCommandBase.h
@@ -44,7 +44,7 @@ private:
virtual void HandleImportedTarget(const std::string &tgt) = 0;
virtual void HandleMissingTarget(const std::string &name) = 0;
- virtual void HandleDirectContent(cmTarget *tgt,
+ virtual bool HandleDirectContent(cmTarget *tgt,
const std::vector<std::string> &content,
bool prepend, bool system) = 0;
@@ -52,7 +52,7 @@ private:
bool ProcessContentArgs(std::vector<std::string> const& args,
unsigned int &argIndex, bool prepend, bool system);
- void PopulateTargetProperies(const std::string &scope,
+ bool PopulateTargetProperies(const std::string &scope,
const std::vector<std::string> &content,
bool prepend, bool system);
};
diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx
index e82b36d..ce3b11e 100644
--- a/Source/cmTargetSourcesCommand.cxx
+++ b/Source/cmTargetSourcesCommand.cxx
@@ -56,9 +56,10 @@ std::string cmTargetSourcesCommand
}
//----------------------------------------------------------------------------
-void cmTargetSourcesCommand
+bool cmTargetSourcesCommand
::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
bool, bool)
{
tgt->AppendProperty("SOURCES", this->Join(content).c_str());
+ return true;
}
diff --git a/Source/cmTargetSourcesCommand.h b/Source/cmTargetSourcesCommand.h
index dae78c4..a170e36 100644
--- a/Source/cmTargetSourcesCommand.h
+++ b/Source/cmTargetSourcesCommand.h
@@ -45,7 +45,7 @@ private:
virtual void HandleImportedTarget(const std::string &tgt);
virtual void HandleMissingTarget(const std::string &name);
- virtual void HandleDirectContent(cmTarget *tgt,
+ virtual bool HandleDirectContent(cmTarget *tgt,
const std::vector<std::string> &content,
bool prepend, bool system);
diff --git a/Tests/CMakeCommands/target_compile_features/CMakeLists.txt b/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
new file mode 100644
index 0000000..ad76411
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.0)
+project(target_compile_features)
+
+set(CMAKE_VERBOSE_MAKEFILE ON)
+
+add_executable(target_compile_features main.cpp)
+target_compile_features(target_compile_features
+ PRIVATE cxx_auto_type
+)
+
+add_library(lib_auto_type lib_auto_type.cpp)
+target_compile_features(lib_auto_type
+ PUBLIC cxx_auto_type
+)
+
+add_executable(lib_user lib_user.cpp)
+target_link_libraries(lib_user lib_auto_type)
diff --git a/Tests/CMakeCommands/target_compile_features/dummy.cpp b/Tests/CMakeCommands/target_compile_features/dummy.cpp
new file mode 100644
index 0000000..341aaaf
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/dummy.cpp
@@ -0,0 +1,5 @@
+
+int main(int, char **)
+{
+ return 0;
+}
diff --git a/Tests/CMakeCommands/target_compile_features/lib_auto_type.cpp b/Tests/CMakeCommands/target_compile_features/lib_auto_type.cpp
new file mode 100644
index 0000000..71b2215
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/lib_auto_type.cpp
@@ -0,0 +1,6 @@
+
+int getAutoTypeImpl()
+{
+ auto i = 0;
+ return i;
+}
diff --git a/Tests/CMakeCommands/target_compile_features/lib_auto_type.h b/Tests/CMakeCommands/target_compile_features/lib_auto_type.h
new file mode 100644
index 0000000..c825b10
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/lib_auto_type.h
@@ -0,0 +1,8 @@
+
+int getAutoTypeImpl();
+
+int getAutoType()
+{
+ auto i = getAutoTypeImpl();
+ return i;
+}
diff --git a/Tests/CMakeCommands/target_compile_features/lib_user.cpp b/Tests/CMakeCommands/target_compile_features/lib_user.cpp
new file mode 100644
index 0000000..976068a
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/lib_user.cpp
@@ -0,0 +1,7 @@
+
+#include "lib_auto_type.h"
+
+int main(int argc, char **argv)
+{
+ return getAutoType();
+}
diff --git a/Tests/CMakeCommands/target_compile_features/main.cpp b/Tests/CMakeCommands/target_compile_features/main.cpp
new file mode 100644
index 0000000..fe29b04
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/main.cpp
@@ -0,0 +1,6 @@
+
+int main(int, char **)
+{
+ auto i = 0;
+ return i;
+}
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 7d4e8b4..12bd3b2 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -197,6 +197,11 @@ if(BUILD_TESTING)
ADD_TEST_MACRO(TarTest TarTest)
ADD_TEST_MACRO(SystemInformation SystemInformation)
ADD_TEST_MACRO(MathTest MathTest)
+ if(CMAKE_CXX_COMPILER_ID STREQUAL GNU
+ AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
+ ADD_TEST_MACRO(CompileFeatures CompileFeatures)
+ ADD_TEST_MACRO(CMakeCommands.target_compile_features target_compile_features)
+ endif()
# assume no resources building to test
set(TEST_RESOURCES FALSE)
# for windows and cygwin assume we have resources
@@ -283,6 +288,19 @@ if(BUILD_TESTING)
ADD_TEST_MACRO(ConfigSources ConfigSources)
endif()
ADD_TEST_MACRO(SourcesProperty SourcesProperty)
+ if(CMAKE_CXX_COMPILER_ID STREQUAL GNU
+ AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
+ set(runCxxDialectTest 1)
+ endif()
+ if(CMAKE_CXX_COMPILER_ID STREQUAL Clang
+ AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.9)
+ if(NOT APPLE OR POLICY CMP0025)
+ set(runCxxDialectTest 1)
+ endif()
+ endif()
+ if(runCxxDialectTest)
+ ADD_TEST_MACRO(CxxDialect CxxDialect)
+ endif()
set_tests_properties(EmptyLibrary PROPERTIES
PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target: test")
ADD_TEST_MACRO(CrossCompile CrossCompile)
diff --git a/Tests/CompileFeatures/CMakeLists.txt b/Tests/CompileFeatures/CMakeLists.txt
new file mode 100644
index 0000000..bceb6bb
--- /dev/null
+++ b/Tests/CompileFeatures/CMakeLists.txt
@@ -0,0 +1,36 @@
+
+cmake_minimum_required(VERSION 3.0)
+
+project(CompileFeatures)
+
+macro(run_test feature)
+ if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ${feature})
+ add_library(test_${feature} OBJECT ${feature}.cpp)
+ set_property(TARGET test_${feature}
+ PROPERTY COMPILE_FEATURES "${feature}"
+ )
+ else()
+ message("Not supported: ${feature}")
+ endif()
+endmacro()
+
+foreach(feature ${CMAKE_CXX_KNOWN_FEATURES})
+ run_test(${feature})
+endforeach()
+
+add_executable(CompileFeatures main.cpp)
+set_property(TARGET CompileFeatures
+ PROPERTY COMPILE_FEATURES "cxx_auto_type"
+)
+
+add_executable(GenexCompileFeatures main.cpp)
+set_property(TARGET GenexCompileFeatures
+ PROPERTY COMPILE_FEATURES "$<1:cxx_auto_type>;$<0:not_a_feature>"
+)
+
+add_library(iface INTERFACE)
+set_property(TARGET iface
+ PROPERTY INTERFACE_COMPILE_FEATURES "cxx_auto_type"
+)
+add_executable(IfaceCompileFeatures main.cpp)
+target_link_libraries(IfaceCompileFeatures iface)
diff --git a/Tests/CompileFeatures/cxx_auto_type.cpp b/Tests/CompileFeatures/cxx_auto_type.cpp
new file mode 100644
index 0000000..7dbf04f
--- /dev/null
+++ b/Tests/CompileFeatures/cxx_auto_type.cpp
@@ -0,0 +1,5 @@
+
+void someFunc()
+{
+ auto x = 3.14;
+}
diff --git a/Tests/CompileFeatures/main.cpp b/Tests/CompileFeatures/main.cpp
new file mode 100644
index 0000000..3a8e0fc
--- /dev/null
+++ b/Tests/CompileFeatures/main.cpp
@@ -0,0 +1,6 @@
+
+int main(int,char**)
+{
+ auto value = 0;
+ return value;
+}
diff --git a/Tests/CxxDialect/CMakeLists.txt b/Tests/CxxDialect/CMakeLists.txt
new file mode 100644
index 0000000..0eb6f8f
--- /dev/null
+++ b/Tests/CxxDialect/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 2.8.12)
+cmake_policy(SET CMP0025 NEW)
+project(CxxDialect)
+
+add_executable(use_typeof use_typeof.cxx)
+set_property(TARGET use_typeof PROPERTY CXX_STANDARD 98)
+set_property(TARGET use_typeof PROPERTY CXX_EXTENSIONS ON)
+
+add_executable(use_constexpr use_constexpr.cxx)
+set_property(TARGET use_constexpr PROPERTY CXX_STANDARD 11)
+
+add_executable(CxxDialect use_constexpr_and_typeof.cxx)
+set_property(TARGET CxxDialect PROPERTY CXX_STANDARD 11)
+set_property(TARGET CxxDialect PROPERTY CXX_EXTENSIONS ON)
diff --git a/Tests/CxxDialect/use_constexpr.cxx b/Tests/CxxDialect/use_constexpr.cxx
new file mode 100644
index 0000000..30ccc4c
--- /dev/null
+++ b/Tests/CxxDialect/use_constexpr.cxx
@@ -0,0 +1,10 @@
+
+constexpr int foo()
+{
+ return 0;
+}
+
+int main(int argc, char**)
+{
+ return foo();
+}
diff --git a/Tests/CxxDialect/use_constexpr_and_typeof.cxx b/Tests/CxxDialect/use_constexpr_and_typeof.cxx
new file mode 100644
index 0000000..af217b6
--- /dev/null
+++ b/Tests/CxxDialect/use_constexpr_and_typeof.cxx
@@ -0,0 +1,11 @@
+
+constexpr int foo()
+{
+ return 0;
+}
+
+int main(int argc, char**)
+{
+ typeof(argc) ret = foo();
+ return ret;
+}
diff --git a/Tests/CxxDialect/use_typeof.cxx b/Tests/CxxDialect/use_typeof.cxx
new file mode 100644
index 0000000..dabb61f
--- /dev/null
+++ b/Tests/CxxDialect/use_typeof.cxx
@@ -0,0 +1,6 @@
+
+int main(int argc, char**)
+{
+ typeof(argc) ret = 0;
+ return ret;
+}
diff --git a/Tests/ExportImport/Export/Interface/CMakeLists.txt b/Tests/ExportImport/Export/Interface/CMakeLists.txt
index 9d4793d..1b653eb 100644
--- a/Tests/ExportImport/Export/Interface/CMakeLists.txt
+++ b/Tests/ExportImport/Export/Interface/CMakeLists.txt
@@ -23,7 +23,10 @@ set_property(TARGET sharedlib PROPERTY INTERFACE_COMPILE_DEFINITIONS "SHAREDLIB_
add_library(sharediface INTERFACE)
target_link_libraries(sharediface INTERFACE sharedlib)
-install(TARGETS headeronly sharediface
+add_library(use_auto_type INTERFACE)
+target_compile_features(use_auto_type INTERFACE cxx_auto_type)
+
+install(TARGETS headeronly sharediface use_auto_type
EXPORT expInterface
)
install(TARGETS sharedlib
diff --git a/Tests/ExportImport/Import/CMakeLists.txt b/Tests/ExportImport/Import/CMakeLists.txt
index 5e809a2..189f7a2 100644
--- a/Tests/ExportImport/Import/CMakeLists.txt
+++ b/Tests/ExportImport/Import/CMakeLists.txt
@@ -1,4 +1,5 @@
cmake_minimum_required (VERSION 2.7.20090711)
+cmake_policy(SET CMP0025 NEW)
project(Import C CXX)
# Import everything in a subdirectory.
diff --git a/Tests/ExportImport/Import/Interface/CMakeLists.txt b/Tests/ExportImport/Import/Interface/CMakeLists.txt
index cf7e2bc..1f30c67 100644
--- a/Tests/ExportImport/Import/Interface/CMakeLists.txt
+++ b/Tests/ExportImport/Import/Interface/CMakeLists.txt
@@ -40,6 +40,23 @@ macro(do_try_compile prefix)
if(NOT ${prefix}IFACE_TRY_COMPILE)
message(SEND_ERROR "${prefix} try_compile with IMPORTED INTERFACE target failed!\n\n${OUTPUT}")
endif()
+
+ if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";cxx_auto_type;")
+ set(CMAKE_REQUIRED_LIBRARIES ${prefix}::use_auto_type)
+ check_cxx_source_compiles(
+ "
+ int main(int,char**)
+ {
+ auto value = 0;
+ return value;
+ }
+ " ${prefix}IMPORTED_IFACE_CONSTEXPR)
+
+ if(NOT ${prefix}IMPORTED_IFACE_CONSTEXPR)
+ message(SEND_ERROR "${prefix} try_compile with IMPORTED INTERFACE target failed!\n\n${OUTPUT}")
+ endif()
+ endif()
+
endmacro()
do_try_compile(bld)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 851de42..00e6702 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -53,6 +53,7 @@ add_RunCMake_test(ObjectLibrary)
add_RunCMake_test(TargetObjects)
add_RunCMake_test(TargetSources)
add_RunCMake_test(find_dependency)
+add_RunCMake_test(CompileFeatures)
if(NOT WIN32)
add_RunCMake_test(PositionIndependentCode)
set(SKIP_VISIBILITY 0)
@@ -124,6 +125,10 @@ endif()
add_RunCMake_test(File_Generate)
add_RunCMake_test(ExportWithoutLanguage)
add_RunCMake_test(target_link_libraries)
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL GNU AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
+ add_RunCMake_test(target_compile_features)
+endif()
add_RunCMake_test(CheckModules)
add_RunCMake_test(CommandLine)
diff --git a/Tests/RunCMake/CompileFeatures/CMakeLists.txt b/Tests/RunCMake/CompileFeatures/CMakeLists.txt
new file mode 100644
index 0000000..3482e6b
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature-result.txt b/Tests/RunCMake/CompileFeatures/NotAFeature-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature-stderr.txt b/Tests/RunCMake/CompileFeatures/NotAFeature-stderr.txt
new file mode 100644
index 0000000..ff60e50
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error in CMakeLists.txt:
+ Specified unknown feature "not_a_feature" for target "somelib".
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature.cmake b/Tests/RunCMake/CompileFeatures/NotAFeature.cmake
new file mode 100644
index 0000000..35246c8
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature.cmake
@@ -0,0 +1,3 @@
+
+add_library(somelib STATIC empty.cpp)
+set_property(TARGET somelib PROPERTY COMPILE_FEATURES "not_a_feature")
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeatureGenex-result.txt b/Tests/RunCMake/CompileFeatures/NotAFeatureGenex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeatureGenex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeatureGenex-stderr.txt b/Tests/RunCMake/CompileFeatures/NotAFeatureGenex-stderr.txt
new file mode 100644
index 0000000..ff60e50
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeatureGenex-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error in CMakeLists.txt:
+ Specified unknown feature "not_a_feature" for target "somelib".
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeatureGenex.cmake b/Tests/RunCMake/CompileFeatures/NotAFeatureGenex.cmake
new file mode 100644
index 0000000..ad2bd37
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeatureGenex.cmake
@@ -0,0 +1,3 @@
+
+add_library(somelib STATIC empty.cpp)
+set_property(TARGET somelib PROPERTY COMPILE_FEATURES "$<1:not_a_feature>")
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-result.txt b/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-stderr.txt b/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-stderr.txt
new file mode 100644
index 0000000..ff60e50
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error in CMakeLists.txt:
+ Specified unknown feature "not_a_feature" for target "somelib".
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive.cmake b/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive.cmake
new file mode 100644
index 0000000..7311aec
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeatureTransitive.cmake
@@ -0,0 +1,6 @@
+
+add_library(iface INTERFACE)
+set_property(TARGET iface PROPERTY INTERFACE_COMPILE_FEATURES "not_a_feature")
+
+add_library(somelib STATIC empty.cpp)
+target_link_libraries(somelib iface)
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-result.txt b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-stderr.txt b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-stderr.txt
new file mode 100644
index 0000000..60a8e51
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-stderr.txt
@@ -0,0 +1,11 @@
+CMake Debug Log at NotAFeature_OriginDebug.cmake:4 \(set_property\):
+ Used compile features for target somelib:
+
+ \* not_a_feature
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+
+
+CMake Error in CMakeLists.txt:
+ Specified unknown feature "not_a_feature" for target "somelib".
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug.cmake b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug.cmake
new file mode 100644
index 0000000..350c2ea
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug.cmake
@@ -0,0 +1,4 @@
+
+set(CMAKE_DEBUG_TARGET_PROPERTIES COMPILE_FEATURES)
+add_library(somelib STATIC empty.cpp)
+set_property(TARGET somelib PROPERTY COMPILE_FEATURES "not_a_feature")
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-result.txt b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-stderr.txt b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-stderr.txt
new file mode 100644
index 0000000..08e20a8
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-stderr.txt
@@ -0,0 +1,11 @@
+CMake Debug Log at NotAFeature_OriginDebugGenex.cmake:4 \(set_property\):
+ Used compile features for target somelib:
+
+ \* not_a_feature
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+
+
+CMake Error in CMakeLists.txt:
+ Specified unknown feature "not_a_feature" for target "somelib".
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex.cmake b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex.cmake
new file mode 100644
index 0000000..2122981
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex.cmake
@@ -0,0 +1,4 @@
+
+set(CMAKE_DEBUG_TARGET_PROPERTIES COMPILE_FEATURES)
+add_library(somelib STATIC empty.cpp)
+set_property(TARGET somelib PROPERTY COMPILE_FEATURES "$<1:not_a_feature>")
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-result.txt b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-stderr.txt b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-stderr.txt
new file mode 100644
index 0000000..23c3305
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-stderr.txt
@@ -0,0 +1,11 @@
+CMake Debug Log at NotAFeature_OriginDebugTransitive.cmake:6 \(target_link_libraries\):
+ Used compile features for target somelib:
+
+ \* not_a_feature
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+
+
+CMake Error in CMakeLists.txt:
+ Specified unknown feature "not_a_feature" for target "somelib".
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive.cmake b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive.cmake
new file mode 100644
index 0000000..05d0073
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive.cmake
@@ -0,0 +1,6 @@
+
+set(CMAKE_DEBUG_TARGET_PROPERTIES COMPILE_FEATURES)
+add_library(iface INTERFACE)
+set_property(TARGET iface PROPERTY INTERFACE_COMPILE_FEATURES "not_a_feature")
+add_library(somelib STATIC empty.cpp)
+target_link_libraries(somelib iface)
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug_target_compile_features-result.txt b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug_target_compile_features-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug_target_compile_features-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug_target_compile_features-stderr.txt b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug_target_compile_features-stderr.txt
new file mode 100644
index 0000000..d819d15
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug_target_compile_features-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at NotAFeature_OriginDebug_target_compile_features.cmake:4 \(target_compile_features\):
+ target_compile_features specified unknown feature "not_a_feature" for
+ target "somelib".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug_target_compile_features.cmake b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug_target_compile_features.cmake
new file mode 100644
index 0000000..467d9a1
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug_target_compile_features.cmake
@@ -0,0 +1,4 @@
+
+set(CMAKE_DEBUG_TARGET_PROPERTIES COMPILE_FEATURES)
+add_library(somelib STATIC empty.cpp)
+target_compile_features(somelib PRIVATE not_a_feature)
diff --git a/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake b/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake
new file mode 100644
index 0000000..a6aeeee
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake
@@ -0,0 +1,9 @@
+include(RunCMake)
+
+run_cmake(NotAFeature)
+run_cmake(NotAFeatureGenex)
+run_cmake(NotAFeatureTransitive)
+run_cmake(NotAFeature_OriginDebug)
+run_cmake(NotAFeature_OriginDebugGenex)
+run_cmake(NotAFeature_OriginDebugTransitive)
+run_cmake(NotAFeature_OriginDebug_target_compile_features)
diff --git a/Tests/RunCMake/CompileFeatures/empty.cpp b/Tests/RunCMake/CompileFeatures/empty.cpp
new file mode 100644
index 0000000..bfbbdde
--- /dev/null
+++ b/Tests/RunCMake/CompileFeatures/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/target_compile_features/CMakeLists.txt b/Tests/RunCMake/target_compile_features/CMakeLists.txt
new file mode 100644
index 0000000..3482e6b
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake b/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake
new file mode 100644
index 0000000..f2abef7
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake
@@ -0,0 +1,11 @@
+include(RunCMake)
+
+run_cmake(not_enough_args)
+run_cmake(alias_target)
+run_cmake(utility_target)
+run_cmake(invalid_args)
+run_cmake(invalid_args_on_interface)
+run_cmake(imported_target)
+run_cmake(no_target)
+run_cmake(not_a_cxx_feature)
+run_cmake(no_matching_cxx_feature)
diff --git a/Tests/RunCMake/target_compile_features/alias_target-result.txt b/Tests/RunCMake/target_compile_features/alias_target-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/alias_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/alias_target-stderr.txt b/Tests/RunCMake/target_compile_features/alias_target-stderr.txt
new file mode 100644
index 0000000..417bf62
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/alias_target-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at alias_target.cmake:4 \(target_compile_features\):
+ target_compile_features can not be used on an ALIAS target.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/alias_target.cmake b/Tests/RunCMake/target_compile_features/alias_target.cmake
new file mode 100644
index 0000000..d35ddba
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/alias_target.cmake
@@ -0,0 +1,4 @@
+
+add_executable(main empty.cpp)
+add_executable(Alias::Main ALIAS main)
+target_compile_features(Alias::Main PRIVATE cxx_delegating_constructors)
diff --git a/Tests/RunCMake/target_compile_features/empty.cpp b/Tests/RunCMake/target_compile_features/empty.cpp
new file mode 100644
index 0000000..bfbbdde
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/target_compile_features/imported_target-result.txt b/Tests/RunCMake/target_compile_features/imported_target-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/imported_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/imported_target-stderr.txt b/Tests/RunCMake/target_compile_features/imported_target-stderr.txt
new file mode 100644
index 0000000..c6ff5ec
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/imported_target-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at imported_target.cmake:3 \(target_compile_features\):
+ Cannot specify compile features for imported target "main".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/imported_target.cmake b/Tests/RunCMake/target_compile_features/imported_target.cmake
new file mode 100644
index 0000000..e248c2f
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/imported_target.cmake
@@ -0,0 +1,3 @@
+
+add_library(main INTERFACE IMPORTED)
+target_compile_features(main INTERFACE cxx_delegating_constructors)
diff --git a/Tests/RunCMake/target_compile_features/invalid_args-result.txt b/Tests/RunCMake/target_compile_features/invalid_args-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/invalid_args-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/invalid_args-stderr.txt b/Tests/RunCMake/target_compile_features/invalid_args-stderr.txt
new file mode 100644
index 0000000..bd5b7b9
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/invalid_args-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at invalid_args.cmake:3 \(target_compile_features\):
+ target_compile_features called with invalid arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/invalid_args.cmake b/Tests/RunCMake/target_compile_features/invalid_args.cmake
new file mode 100644
index 0000000..1a7fb37
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/invalid_args.cmake
@@ -0,0 +1,3 @@
+
+add_executable(main empty.cpp)
+target_compile_features(main INVALID cxx_delegating_constructors)
diff --git a/Tests/RunCMake/target_compile_features/invalid_args_on_interface-result.txt b/Tests/RunCMake/target_compile_features/invalid_args_on_interface-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/invalid_args_on_interface-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/invalid_args_on_interface-stderr.txt b/Tests/RunCMake/target_compile_features/invalid_args_on_interface-stderr.txt
new file mode 100644
index 0000000..c30209a
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/invalid_args_on_interface-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at invalid_args_on_interface.cmake:3 \(target_compile_features\):
+ target_compile_features may only be set INTERFACE properties on INTERFACE
+ targets
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/invalid_args_on_interface.cmake b/Tests/RunCMake/target_compile_features/invalid_args_on_interface.cmake
new file mode 100644
index 0000000..324d0f3
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/invalid_args_on_interface.cmake
@@ -0,0 +1,3 @@
+
+add_library(main INTERFACE)
+target_compile_features(main PRIVATE cxx_delegating_constructors)
diff --git a/Tests/RunCMake/target_compile_features/no_matching_cxx_feature-result.txt b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/no_matching_cxx_feature-stderr.txt b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature-stderr.txt
new file mode 100644
index 0000000..4c76c7a
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at no_matching_cxx_feature.cmake:[0-9][0-9]? \((target_compile_features|message)\):
+ The compiler feature "[^"]+" is not known to compiler
+
+ "[^"]*"
+
+ version *[.0-9]+\.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/no_matching_cxx_feature.cmake b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature.cmake
new file mode 100644
index 0000000..0452dbf
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature.cmake
@@ -0,0 +1,26 @@
+
+if (NOT ";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";gnu_cxx_typeof;"
+ AND NOT ";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";msvc_cxx_sealed;" )
+ # Simulate passing the test.
+ message(SEND_ERROR
+ "The compiler feature \"gnu_cxx_dummy\" is not known to compiler\n\"GNU\"\nversion 4.8.1."
+ )
+ return()
+endif()
+
+if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";gnu_cxx_typeof;")
+ set(feature msvc_cxx_sealed)
+ if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";msvc_cxx_sealed;")
+ # If a compiler supports both extensions, remove one of them.
+ list(REMOVE_ITEM CMAKE_CXX_COMPILE_FEATURES msvc_cxx_sealed)
+ endif()
+else()
+ set(feature gnu_cxx_typeof)
+endif()
+
+add_executable(main empty.cpp)
+
+target_compile_features(main
+ PRIVATE
+ ${feature}
+)
diff --git a/Tests/RunCMake/target_compile_features/no_target-result.txt b/Tests/RunCMake/target_compile_features/no_target-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/no_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/no_target-stderr.txt b/Tests/RunCMake/target_compile_features/no_target-stderr.txt
new file mode 100644
index 0000000..323ba7a
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/no_target-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at no_target.cmake:2 \(target_compile_features\):
+ Cannot specify compile features for target "main" which is not built by
+ this project.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/no_target.cmake b/Tests/RunCMake/target_compile_features/no_target.cmake
new file mode 100644
index 0000000..3f0afe2
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/no_target.cmake
@@ -0,0 +1,2 @@
+
+target_compile_features(main INTERFACE cxx_delegating_constructors)
diff --git a/Tests/RunCMake/target_compile_features/not_a_cxx_feature-result.txt b/Tests/RunCMake/target_compile_features/not_a_cxx_feature-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/not_a_cxx_feature-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/not_a_cxx_feature-stderr.txt b/Tests/RunCMake/target_compile_features/not_a_cxx_feature-stderr.txt
new file mode 100644
index 0000000..efa2bad
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/not_a_cxx_feature-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at not_a_cxx_feature.cmake:3 \(target_compile_features\):
+ target_compile_features specified unknown feature "cxx_not_a_feature" for
+ target "main".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/not_a_cxx_feature.cmake b/Tests/RunCMake/target_compile_features/not_a_cxx_feature.cmake
new file mode 100644
index 0000000..0207b72
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/not_a_cxx_feature.cmake
@@ -0,0 +1,6 @@
+
+add_executable(main empty.cpp)
+target_compile_features(main
+ PRIVATE
+ cxx_not_a_feature
+)
diff --git a/Tests/RunCMake/target_compile_features/not_enough_args-result.txt b/Tests/RunCMake/target_compile_features/not_enough_args-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/not_enough_args-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/not_enough_args-stderr.txt b/Tests/RunCMake/target_compile_features/not_enough_args-stderr.txt
new file mode 100644
index 0000000..2f8d812
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/not_enough_args-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at not_enough_args.cmake:3 \(target_compile_features\):
+ target_compile_features called with incorrect number of arguments
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/not_enough_args.cmake b/Tests/RunCMake/target_compile_features/not_enough_args.cmake
new file mode 100644
index 0000000..9561230
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/not_enough_args.cmake
@@ -0,0 +1,3 @@
+
+add_executable(main empty.cpp)
+target_compile_features(main)
diff --git a/Tests/RunCMake/target_compile_features/utility_target-result.txt b/Tests/RunCMake/target_compile_features/utility_target-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/utility_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_compile_features/utility_target-stderr.txt b/Tests/RunCMake/target_compile_features/utility_target-stderr.txt
new file mode 100644
index 0000000..d239059
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/utility_target-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at utility_target.cmake:4 \(target_compile_features\):
+ target_compile_features called with non-compilable target type
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_compile_features/utility_target.cmake b/Tests/RunCMake/target_compile_features/utility_target.cmake
new file mode 100644
index 0000000..8919056
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/utility_target.cmake
@@ -0,0 +1,4 @@
+
+add_custom_target(utility)
+
+target_compile_features(utility PRIVATE cxx_delegating_constructors)
diff --git a/Tests/SystemInformation/CMakeLists.txt b/Tests/SystemInformation/CMakeLists.txt
index c33380f..db54612 100644
--- a/Tests/SystemInformation/CMakeLists.txt
+++ b/Tests/SystemInformation/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required (VERSION 2.6)
+cmake_minimum_required (VERSION 3.0)
project(SystemInformation)
include_directories("This does not exists")
diff --git a/Tests/SystemInformation/SystemInformation.in b/Tests/SystemInformation/SystemInformation.in
index df3bf49..954a2fe 100644
--- a/Tests/SystemInformation/SystemInformation.in
+++ b/Tests/SystemInformation/SystemInformation.in
@@ -21,6 +21,12 @@ CMAKE_C_COMPILER_ID == "${CMAKE_C_COMPILER_ID}"
CMAKE_C_COMPILER_VERSION == "${CMAKE_C_COMPILER_VERSION}"
CMAKE_CXX_COMPILER_ID == "${CMAKE_CXX_COMPILER_ID}"
CMAKE_CXX_COMPILER_VERSION == "${CMAKE_CXX_COMPILER_VERSION}"
+CMAKE_CXX98_STANDARD_COMPILE_OPTION == "${CMAKE_CXX98_STANDARD_COMPILE_OPTION}"
+CMAKE_CXX11_STANDARD_COMPILE_OPTION == "${CMAKE_CXX11_STANDARD_COMPILE_OPTION}"
+CMAKE_CXX98_EXTENSION_COMPILE_OPTION == "${CMAKE_CXX98_EXTENSION_COMPILE_OPTION}"
+CMAKE_CXX11_EXTENSION_COMPILE_OPTION == "${CMAKE_CXX11_EXTENSION_COMPILE_OPTION}"
+CMAKE_CXX_COMPILE_FEATURES == "${CMAKE_CXX_COMPILE_FEATURES}"
+CMAKE_CXX11_COMPILE_FEATURES == "${CMAKE_CXX11_COMPILE_FEATURES}"
// C shared library flag
CMAKE_SHARED_LIBRARY_C_FLAGS == "${CMAKE_SHARED_LIBRARY_C_FLAGS}"