Bläddra i källkod

Merge topic 'target_compile_features'

9eaf3755 Export: Populate INTERFACE_COMPILE_FEATURES property.
8ed59fc2 Add target_compile_features command.
4e6ca504 cmTargetPropCommandBase: Change the interface to return bool.
5412dede cmTarget: Transitively evaluate compiler features.
baff4434 cmTarget: Allow populating COMPILE_FEATURES using generator expressions.
f97bf437 Features: Add cxx_auto_type.
03355d6b cmTarget: Add COMPILE_FEATURES target property.
faeddf64 project: Add infrastructure for recording CXX compiler features
913394af cmTarget: Add CXX_STANDARD and CXX_EXTENSION target properties.
8238a6cd Add some COMPILE_OPTIONS for specifying C++ dialect.
892243fc Tests: Require CMake 3.0 for the SystemInformation test.
59b5fdd3 Don't load Clang-CXX from AppleClang-CXX.
Brad King 11 år sedan
förälder
incheckning
b56a9ae7f1
100 ändrade filer med 1127 tillägg och 20 borttagningar
  1. 30 0
      Help/command/target_compile_features.rst
  2. 1 0
      Help/manual/cmake-commands.7.rst
  3. 4 0
      Help/manual/cmake-properties.7.rst
  4. 4 0
      Help/manual/cmake-variables.7.rst
  5. 11 0
      Help/prop_tgt/COMPILE_FEATURES.rst
  6. 8 0
      Help/prop_tgt/CXX_EXTENSIONS.rst
  7. 14 0
      Help/prop_tgt/CXX_STANDARD.rst
  8. 14 0
      Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
  9. 18 0
      Help/release/dev/compile-language-features.rst
  10. 8 0
      Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
  11. 8 0
      Help/variable/CMAKE_CXX_EXTENSIONS.rst
  12. 18 0
      Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
  13. 8 0
      Help/variable/CMAKE_CXX_STANDARD.rst
  14. 1 1
      Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst
  15. 3 0
      Modules/CMakeCXXCompiler.cmake.in
  16. 43 0
      Modules/CMakeDetermineCompileFeatures.cmake
  17. 3 0
      Modules/CMakeTestCXXCompiler.cmake
  18. 6 1
      Modules/Compiler/AppleClang-CXX.cmake
  19. 18 0
      Modules/Compiler/Clang-CXX.cmake
  20. 8 0
      Modules/Compiler/GNU-CXX-FeatureTests.cmake
  21. 25 0
      Modules/Compiler/GNU-CXX.cmake
  22. 57 0
      Modules/Internal/FeatureTesting.cmake
  23. 1 0
      Source/CMakeLists.txt
  24. 3 0
      Source/cmExportBuildFileGenerator.cxx
  25. 4 0
      Source/cmExportInstallFileGenerator.cxx
  26. 2 1
      Source/cmGeneratorExpressionDAGChecker.h
  27. 39 0
      Source/cmLocalGenerator.cxx
  28. 2 0
      Source/cmLocalGenerator.h
  29. 133 0
      Source/cmMakefile.cxx
  30. 4 0
      Source/cmMakefile.h
  31. 159 0
      Source/cmTarget.cxx
  32. 3 0
      Source/cmTarget.h
  33. 2 1
      Source/cmTargetCompileDefinitionsCommand.cxx
  34. 1 1
      Source/cmTargetCompileDefinitionsCommand.h
  35. 70 0
      Source/cmTargetCompileFeaturesCommand.cxx
  36. 41 0
      Source/cmTargetCompileFeaturesCommand.h
  37. 2 1
      Source/cmTargetCompileOptionsCommand.cxx
  38. 1 1
      Source/cmTargetCompileOptionsCommand.h
  39. 2 1
      Source/cmTargetIncludeDirectoriesCommand.cxx
  40. 1 1
      Source/cmTargetIncludeDirectoriesCommand.h
  41. 8 6
      Source/cmTargetPropCommandBase.cxx
  42. 2 2
      Source/cmTargetPropCommandBase.h
  43. 2 1
      Source/cmTargetSourcesCommand.cxx
  44. 1 1
      Source/cmTargetSourcesCommand.h
  45. 17 0
      Tests/CMakeCommands/target_compile_features/CMakeLists.txt
  46. 5 0
      Tests/CMakeCommands/target_compile_features/dummy.cpp
  47. 6 0
      Tests/CMakeCommands/target_compile_features/lib_auto_type.cpp
  48. 8 0
      Tests/CMakeCommands/target_compile_features/lib_auto_type.h
  49. 7 0
      Tests/CMakeCommands/target_compile_features/lib_user.cpp
  50. 6 0
      Tests/CMakeCommands/target_compile_features/main.cpp
  51. 18 0
      Tests/CMakeLists.txt
  52. 36 0
      Tests/CompileFeatures/CMakeLists.txt
  53. 5 0
      Tests/CompileFeatures/cxx_auto_type.cpp
  54. 6 0
      Tests/CompileFeatures/main.cpp
  55. 14 0
      Tests/CxxDialect/CMakeLists.txt
  56. 10 0
      Tests/CxxDialect/use_constexpr.cxx
  57. 11 0
      Tests/CxxDialect/use_constexpr_and_typeof.cxx
  58. 6 0
      Tests/CxxDialect/use_typeof.cxx
  59. 4 1
      Tests/ExportImport/Export/Interface/CMakeLists.txt
  60. 1 0
      Tests/ExportImport/Import/CMakeLists.txt
  61. 17 0
      Tests/ExportImport/Import/Interface/CMakeLists.txt
  62. 5 0
      Tests/RunCMake/CMakeLists.txt
  63. 3 0
      Tests/RunCMake/CompileFeatures/CMakeLists.txt
  64. 1 0
      Tests/RunCMake/CompileFeatures/NotAFeature-result.txt
  65. 2 0
      Tests/RunCMake/CompileFeatures/NotAFeature-stderr.txt
  66. 3 0
      Tests/RunCMake/CompileFeatures/NotAFeature.cmake
  67. 1 0
      Tests/RunCMake/CompileFeatures/NotAFeatureGenex-result.txt
  68. 2 0
      Tests/RunCMake/CompileFeatures/NotAFeatureGenex-stderr.txt
  69. 3 0
      Tests/RunCMake/CompileFeatures/NotAFeatureGenex.cmake
  70. 1 0
      Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-result.txt
  71. 2 0
      Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-stderr.txt
  72. 6 0
      Tests/RunCMake/CompileFeatures/NotAFeatureTransitive.cmake
  73. 1 0
      Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-result.txt
  74. 11 0
      Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-stderr.txt
  75. 4 0
      Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug.cmake
  76. 1 0
      Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-result.txt
  77. 11 0
      Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-stderr.txt
  78. 4 0
      Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex.cmake
  79. 1 0
      Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-result.txt
  80. 11 0
      Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-stderr.txt
  81. 6 0
      Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive.cmake
  82. 1 0
      Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug_target_compile_features-result.txt
  83. 5 0
      Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug_target_compile_features-stderr.txt
  84. 4 0
      Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug_target_compile_features.cmake
  85. 9 0
      Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake
  86. 7 0
      Tests/RunCMake/CompileFeatures/empty.cpp
  87. 3 0
      Tests/RunCMake/target_compile_features/CMakeLists.txt
  88. 11 0
      Tests/RunCMake/target_compile_features/RunCMakeTest.cmake
  89. 1 0
      Tests/RunCMake/target_compile_features/alias_target-result.txt
  90. 4 0
      Tests/RunCMake/target_compile_features/alias_target-stderr.txt
  91. 4 0
      Tests/RunCMake/target_compile_features/alias_target.cmake
  92. 7 0
      Tests/RunCMake/target_compile_features/empty.cpp
  93. 1 0
      Tests/RunCMake/target_compile_features/imported_target-result.txt
  94. 4 0
      Tests/RunCMake/target_compile_features/imported_target-stderr.txt
  95. 3 0
      Tests/RunCMake/target_compile_features/imported_target.cmake
  96. 1 0
      Tests/RunCMake/target_compile_features/invalid_args-result.txt
  97. 4 0
      Tests/RunCMake/target_compile_features/invalid_args-stderr.txt
  98. 3 0
      Tests/RunCMake/target_compile_features/invalid_args.cmake
  99. 1 0
      Tests/RunCMake/target_compile_features/invalid_args_on_interface-result.txt
  100. 5 0
      Tests/RunCMake/target_compile_features/invalid_args_on_interface-stderr.txt

+ 30 - 0
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.

+ 1 - 0
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

+ 4 - 0
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

+ 4 - 0
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

+ 11 - 0
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.

+ 8 - 0
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.

+ 14 - 0
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.

+ 14 - 0
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.

+ 18 - 0
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.

+ 8 - 0
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.

+ 8 - 0
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.

+ 18 - 0
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

+ 8 - 0
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.

+ 1 - 1
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.

+ 3 - 0
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@")

+ 43 - 0
Modules/CMakeDetermineCompileFeatures.cmake

@@ -0,0 +1,43 @@
+
+#=============================================================================
+# Copyright 2013 Stephen Kelly <[email protected]>
+#
+# 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()

+ 3 - 0
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(

+ 6 - 1
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()

+ 18 - 0
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()

+ 8 - 0
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)

+ 25 - 0
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()

+ 57 - 0
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()

+ 1 - 0
Source/CMakeLists.txt

@@ -346,6 +346,7 @@ foreach(command_file
     cmSourceGroupCommand
     cmSubdirDependsCommand
     cmTargetCompileDefinitionsCommand
+    cmTargetCompileFeaturesCommand
     cmTargetCompileOptionsCommand
     cmTargetIncludeDirectoriesCommand
     cmTargetSourcesCommand

+ 3 - 0
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 =

+ 4 - 0
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

+ 2 - 1
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)

+ 39 - 0
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)

+ 2 - 0
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,

+ 133 - 0
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;
+}

+ 4 - 0
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);

+ 159 - 0
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;
@@ -2676,6 +2704,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)
 {
@@ -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;

+ 3 - 0
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;
 

+ 2 - 1
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;
 }

+ 1 - 1
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);

+ 70 - 0
Source/cmTargetCompileFeaturesCommand.cxx

@@ -0,0 +1,70 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2013 Stephen Kelly <[email protected]>
+
+  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;
+}

+ 41 - 0
Source/cmTargetCompileFeaturesCommand.h

@@ -0,0 +1,41 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2013 Stephen Kelly <[email protected]>
+
+  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

+ 2 - 1
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;
 }

+ 1 - 1
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);

+ 2 - 1
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;
 }
 
 //----------------------------------------------------------------------------

+ 1 - 1
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,

+ 8 - 6
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;
 }
 
 //----------------------------------------------------------------------------

+ 2 - 2
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);
 };

+ 2 - 1
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;
 }

+ 1 - 1
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);
 

+ 17 - 0
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)

+ 5 - 0
Tests/CMakeCommands/target_compile_features/dummy.cpp

@@ -0,0 +1,5 @@
+
+int main(int, char **)
+{
+  return 0;
+}

+ 6 - 0
Tests/CMakeCommands/target_compile_features/lib_auto_type.cpp

@@ -0,0 +1,6 @@
+
+int getAutoTypeImpl()
+{
+  auto i = 0;
+  return i;
+}

+ 8 - 0
Tests/CMakeCommands/target_compile_features/lib_auto_type.h

@@ -0,0 +1,8 @@
+
+int getAutoTypeImpl();
+
+int getAutoType()
+{
+  auto i = getAutoTypeImpl();
+  return i;
+}

+ 7 - 0
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();
+}

+ 6 - 0
Tests/CMakeCommands/target_compile_features/main.cpp

@@ -0,0 +1,6 @@
+
+int main(int, char **)
+{
+  auto i = 0;
+  return i;
+}

+ 18 - 0
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)

+ 36 - 0
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)

+ 5 - 0
Tests/CompileFeatures/cxx_auto_type.cpp

@@ -0,0 +1,5 @@
+
+void someFunc()
+{
+  auto x = 3.14;
+}

+ 6 - 0
Tests/CompileFeatures/main.cpp

@@ -0,0 +1,6 @@
+
+int main(int,char**)
+{
+  auto value = 0;
+  return value;
+}

+ 14 - 0
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)

+ 10 - 0
Tests/CxxDialect/use_constexpr.cxx

@@ -0,0 +1,10 @@
+
+constexpr int foo()
+{
+  return 0;
+}
+
+int main(int argc, char**)
+{
+  return foo();
+}

+ 11 - 0
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;
+}

+ 6 - 0
Tests/CxxDialect/use_typeof.cxx

@@ -0,0 +1,6 @@
+
+int main(int argc, char**)
+{
+  typeof(argc) ret = 0;
+  return ret;
+}

+ 4 - 1
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

+ 1 - 0
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.

+ 17 - 0
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)

+ 5 - 0
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)
 

+ 3 - 0
Tests/RunCMake/CompileFeatures/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)

+ 1 - 0
Tests/RunCMake/CompileFeatures/NotAFeature-result.txt

@@ -0,0 +1 @@
+1

+ 2 - 0
Tests/RunCMake/CompileFeatures/NotAFeature-stderr.txt

@@ -0,0 +1,2 @@
+CMake Error in CMakeLists.txt:
+  Specified unknown feature "not_a_feature" for target "somelib".

+ 3 - 0
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")

+ 1 - 0
Tests/RunCMake/CompileFeatures/NotAFeatureGenex-result.txt

@@ -0,0 +1 @@
+1

+ 2 - 0
Tests/RunCMake/CompileFeatures/NotAFeatureGenex-stderr.txt

@@ -0,0 +1,2 @@
+CMake Error in CMakeLists.txt:
+  Specified unknown feature "not_a_feature" for target "somelib".

+ 3 - 0
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>")

+ 1 - 0
Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-result.txt

@@ -0,0 +1 @@
+1

+ 2 - 0
Tests/RunCMake/CompileFeatures/NotAFeatureTransitive-stderr.txt

@@ -0,0 +1,2 @@
+CMake Error in CMakeLists.txt:
+  Specified unknown feature "not_a_feature" for target "somelib".

+ 6 - 0
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)

+ 1 - 0
Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug-result.txt

@@ -0,0 +1 @@
+1

+ 11 - 0
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".

+ 4 - 0
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")

+ 1 - 0
Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugGenex-result.txt

@@ -0,0 +1 @@
+1

+ 11 - 0
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".

+ 4 - 0
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>")

+ 1 - 0
Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebugTransitive-result.txt

@@ -0,0 +1 @@
+1

+ 11 - 0
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".

+ 6 - 0
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)

+ 1 - 0
Tests/RunCMake/CompileFeatures/NotAFeature_OriginDebug_target_compile_features-result.txt

@@ -0,0 +1 @@
+1

+ 5 - 0
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\)

+ 4 - 0
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)

+ 9 - 0
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)

+ 7 - 0
Tests/RunCMake/CompileFeatures/empty.cpp

@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+  return 0;
+}

+ 3 - 0
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)

+ 11 - 0
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)

+ 1 - 0
Tests/RunCMake/target_compile_features/alias_target-result.txt

@@ -0,0 +1 @@
+1

+ 4 - 0
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\)

+ 4 - 0
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)

+ 7 - 0
Tests/RunCMake/target_compile_features/empty.cpp

@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+  return 0;
+}

+ 1 - 0
Tests/RunCMake/target_compile_features/imported_target-result.txt

@@ -0,0 +1 @@
+1

+ 4 - 0
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\)

+ 3 - 0
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)

+ 1 - 0
Tests/RunCMake/target_compile_features/invalid_args-result.txt

@@ -0,0 +1 @@
+1

+ 4 - 0
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\)

+ 3 - 0
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)

+ 1 - 0
Tests/RunCMake/target_compile_features/invalid_args_on_interface-result.txt

@@ -0,0 +1 @@
+1

+ 5 - 0
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\)

Vissa filer visades inte eftersom för många filer har ändrats