[Cmake-commits] CMake branch, next, updated. v3.0.0-rc2-1352-g3e45853

Stephen Kelly steveire at gmail.com
Thu Mar 20 16:53:31 EDT 2014


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  3e45853194400320ddb8a78a78ba2fddf8d1be5f (commit)
       via  310e203213b2de3c0e8cffa5de2360cdf17654e3 (commit)
       via  6696b57426868e1dd1f9b6f9d1fc1d2994e65832 (commit)
       via  03b29748f2a93baa2cec4aaf9dcf55cda59c937c (commit)
       via  47917d2485870965d2a6df5c50d3d7b5bad9fd67 (commit)
       via  4e5c275c341c4f4af45b100c4eca245424de9f32 (commit)
       via  48be47970c0648256c5decff7c8636b692c9e537 (commit)
       via  c3ddd19ef7763d1212b8c8a218beec112f4058bd (commit)
       via  48e747c5cf48612dd2b1241e190f769253c48cc8 (commit)
       via  9f8f986e87cdeff8d5694e0d7a6911c2033b8163 (commit)
       via  91af9ad4ca8dfbe9fb34c3eb5393e7f360e7d49c (commit)
       via  973087d34bca375835c675afe5be82c9d79daa54 (commit)
       via  76164d8beacea4171be5f0dc8375df9191e1eb7a (commit)
       via  6e6cd7441ac884c2a015d21e82d85bd110e5bc70 (commit)
       via  bb43b3c2262edce04698939431e5ba6925624116 (commit)
       via  459ae487afdf68dd47ed44b7587c202dabbc6cdb (commit)
       via  129caf8f9de717d6ccc95516057e67141bb4e362 (commit)
       via  20594685256692cf4222e59774ce39fdfa21b576 (commit)
       via  490877363b06aef81cda193ecbeb4660ec44dc9b (commit)
       via  a6ea37fab08a8d01ad54c1982eb2285de58eb019 (commit)
       via  91329bec297cb3e5480e16d9b68896ff25ffb2b4 (commit)
       via  7713cce6e6765d4c5963d77c30e3ca6ec32e9f7e (commit)
       via  ce63e5cd29aa409a2334964f8925d99c06ab6869 (commit)
      from  784a1772d4d856ce41c2e6f4da36e0f9c246fb17 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3e45853194400320ddb8a78a78ba2fddf8d1be5f
commit 3e45853194400320ddb8a78a78ba2fddf8d1be5f
Merge: 784a177 310e203
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Mar 20 16:53:26 2014 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Thu Mar 20 16:53:26 2014 -0400

    Merge topic 'target_compile_features' into next
    
    310e2032 Help: Add a manual for compiler feature control.
    6696b574 Add the WriteCompilerDetectionHeader module.
    03b29748 Add cxx_override feature.
    47917d24 Add cxx_final feature.
    4e5c275c Add cxx_static_assert feature.
    48be4797 Add a cxx_binary_literals feature.
    c3ddd19e Export INTERFACE_COMPILE_FEATURES property.
    48e747c5 Add cxx_constexpr feature.
    9f8f986e Genex: Add $<HAVE_COMPILER_FEATURE:FEATURE> genex.
    91af9ad4 Add a cxx_variadic_templates feature.
    973087d3 Base the target_compile_features command on cmTargetPropCommandBase.
    76164d8b cmTargetPropCommandBase: Change the interface to return bool.
    6e6cd744 cmTarget: Transitively evaluate compiler features.
    bb43b3c2 cmTarget: Allow populating COMPILE_FEATURES using generator expressions.
    459ae487 cmTarget: Make COMPILE_FEATURES available as a target property.
    129caf8f Add target_compile_features command.
    ...

diff --cc Source/cmGeneratorExpression.h
index da64515,d1eca25..cc46732
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@@ -134,9 -132,9 +137,10 @@@ private
    mutable std::set<cmTarget*> DependTargets;
    mutable std::set<cmTarget const*> AllTargetsSeen;
    mutable std::set<std::string> SeenTargetProperties;
+   mutable std::set<std::string> SeenCompileNonFeatures;
    mutable std::string Output;
    mutable bool HadContextSensitiveCondition;
 +  bool EvaluateForBuildsystem;
  };
  
  #endif
diff --cc Source/cmTarget.cxx
index aeb477d,51aed5b..3ad6c43
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@@ -149,8 -149,8 +149,9 @@@ 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;
  
    mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
@@@ -6582,8 -6573,8 +6761,9 @@@ cmTargetInternalPointer::~cmTargetInter
  {
    deleteAndClear(this->Pointer->IncludeDirectoriesEntries);
    deleteAndClear(this->Pointer->CompileOptionsEntries);
+   deleteAndClear(this->Pointer->CompileFeaturesEntries);
    deleteAndClear(this->Pointer->CompileDefinitionsEntries);
 +  deleteAndClear(this->Pointer->SourceEntries);
    delete this->Pointer;
  }
  
diff --cc Tests/RunCMake/CMakeLists.txt
index 31e7805,54d837e..853a870
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@@ -49,8 -49,10 +49,11 @@@ add_RunCMake_test(GeneratorToolset
  add_RunCMake_test(TargetPropertyGeneratorExpressions)
  add_RunCMake_test(Languages)
  add_RunCMake_test(ObjectLibrary)
 +add_RunCMake_test(TargetObjects)
  add_RunCMake_test(find_dependency)
+ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
+   add_RunCMake_test(have_feature)
+ endif()
  if(NOT WIN32)
    add_RunCMake_test(PositionIndependentCode)
    set(SKIP_VISIBILITY 0)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=310e203213b2de3c0e8cffa5de2360cdf17654e3
commit 310e203213b2de3c0e8cffa5de2360cdf17654e3
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Mar 18 23:50:18 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:46 2014 +0100

    Help: Add a manual for compiler feature control.
    
    Link to it from the documentation of related properties, variables
    and commands.
    
    Extend the cmake-developer(7) documentation with notes on
    extending feature support for compilers.

diff --git a/Help/command/target_compile_features.rst b/Help/command/target_compile_features.rst
index f8e5c54..5e9b1b2 100644
--- a/Help/command/target_compile_features.rst
+++ b/Help/command/target_compile_features.rst
@@ -27,4 +27,5 @@ 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.
+expressions.  See the :manual:`cmake-compile-features(7)` manual for
+information on required and optional compile features.
diff --git a/Help/index.rst b/Help/index.rst
index a4abfbf..2d3f156 100644
--- a/Help/index.rst
+++ b/Help/index.rst
@@ -27,6 +27,7 @@ Reference Manuals
 
    /manual/cmake-buildsystem.7
    /manual/cmake-commands.7
+   /manual/cmake-compile-features.7
    /manual/cmake-developer.7
    /manual/cmake-generator-expressions.7
    /manual/cmake-generators.7
diff --git a/Help/manual/cmake-compile-features.7.rst b/Help/manual/cmake-compile-features.7.rst
new file mode 100644
index 0000000..c947cb5
--- /dev/null
+++ b/Help/manual/cmake-compile-features.7.rst
@@ -0,0 +1,344 @@
+.. cmake-manual-description: CMake Compile Features Reference
+
+cmake-compile-features(7)
+*************************
+
+.. only:: html or latex
+
+   .. contents::
+
+Introduction
+============
+
+Project source code may depend on, or be conditional on, the availability
+of certain features of the compiler.  There are three use-cases which arise:
+`Compile Feature Requirements`_, `Optional Compile Features`_
+and `Conditional Compilation Options`_.
+
+While features are typically specified in programming language standards,
+CMake provides a primary user interface based on handling the features,
+not the language standard that introduced the feature.
+
+The :variable:`CMAKE_CXX_KNOWN_FEATURES` variable contains all the features
+known to CMake, regardless of compiler support for the feature.  The
+:variable:`CMAKE_CXX_COMPILE_FEATURES` variable contains all features
+known to the compiler, regardless of language standard or compile flags
+needed to use them.
+
+Features known to CMake are named mostly following the same convention
+as the clang feature test macros.  The are some execptions, such as
+CMake using ``cxx_final`` and ``cxx_override`` instead of the single
+``cxx_override_control`` used by clang.  Compiler-specific extensions
+are named with a prefix denoting the id of the compiler, such as
+``gnuxx_typeof`` and ``msvcxx_sealed``.
+
+Compile Feature Requirements
+============================
+
+Compile feature requirements may be specified with the
+:command:`target_compile_features` command.  For example, if a target must
+be compiled with compiler support for the
+:variable:`cxx_constexpr <CMAKE_CXX_KNOWN_FEATURES>` feature:
+
+.. code-block:: cmake
+
+  add_library(mylib requires_constexpr.cpp)
+  target_compile_features(mylib PRIVATE cxx_constexpr)
+
+In processing the requirement for the ``cxx_constexpr`` feature,
+:manual:`cmake(1)` will ensure that the in-use C++ compiler is capable
+of the feature, and will add any necessary flags such as ``-std=c++11``
+to the compile lines of C++ files in the ``mylib`` target.  A
+``FATAL_ERROR`` is issued if the compiler is not capable of the
+feature.
+
+The exact compile flags and language standard are deliberately not part
+of the user interface for this use-case.  CMake will compute the
+appropriate compile flags to use by considering the features specified
+for each target.  For example, a target may require the ``cxx_constexpr``
+feature, and CMake will add the ``-std=c++11`` flag if using GNU. A
+target may require the ``gnuxx_typeof`` feature, a GNU extension
+which requires the ``-std=gnu++98`` flag. If the target additionally
+requires the ``cxx_constexpr`` feature, then the ``-std=gnu++11`` flag
+will be used instead of ``-std=c++11`` for that compiler.
+
+Such compile flags are added even if the compiler supports the
+particular feature without the flag. For example, the GNU compiler
+supports variadic templates (with a warning) even if ``-std=c++98`` is
+used.  CMake adds the ``-std=c++11`` flag if ``cxx_variadic_templates``
+is specified as a requirement.
+
+In the above example, ``mylib`` requires ``cxx_constexpr`` when it
+is built itself, but consumers of ``mylib`` are not required to use a
+compiler which supports ``cxx_constexpr``.  If the interface of
+``mylib`` does require the ``cxx_constexpr`` feature (or any other
+known feature), that may be specified with the ``PUBLIC`` or
+``INTERFACE`` signatures of :command:`target_compile_features`:
+
+.. code-block:: cmake
+
+  add_library(mylib requires_constexpr.cpp)
+  target_compile_features(mylib PUBLIC cxx_constexpr)
+
+  # main.cpp will be compiled with -std=c++11 on GNU for cxx_constexpr.
+  add_executable(myexe main.cpp)
+  target_link_libraries(myexe mylib)
+
+  # gnu_main.cpp will be compiled with -std=gnu++11 on GNU
+  # for cxx_constexpr and gnuxx_typeof combined.
+  add_executable(myextenstion_exe gnu_main.cpp)
+  target_link_libraries(myextenstion_exe mylib)
+  target_compile_features(myextenstion_exe PRIVATE gnuxx_typeof)
+
+Feature requirements are evaluated transitively by consuming the link
+implementation.  See :manual:`cmake-buildsystem(7)` for more on
+transitive behavior of build properties.
+
+Note that new use of compile feature requirements may expose
+cross-platform bugs in user code.  For example, the GNU compiler uses the
+``gnu++98`` language by default as of GCC version 4.8.  User code may
+be relying on that and expecting the ``typeof`` extension to work.
+However, if the :command:`target_compile_features` command is used to
+specify the requirement for ``cxx_constexpr``, a ``-std=c++11`` flag may
+be added, and the ``typeof`` extension would no longer be available. The
+solution is to specify extensions which are relied upon when starting to
+use the :command:`target_compile_features` command and, in this case,
+specify the ``gnuxx_typeof`` feature too.
+
+If the compiler in use is newer than the :manual:`cmake(1)` in use, the
+compiler may support features which are not recorded as supported by
+CMake.  In such cases, if the version of CMake generally
+:variable:`supports <CMAKE_CXX_KNOWN_FEATURES>`, the feature, it is
+possible to extend the :variable:`CMAKE_CXX_COMPILE_FEATURES` variable
+to allow use of the compiler feature. For example:
+
+.. code-block:: cmake
+
+  cmake_minimum_required(VERSION 3.2)
+
+  if (NOT MSVC_VERSION VERSION_LESS 1900
+      # CMake 3.3 records support for this feature. Add it temporarily
+      # as a workaround here.
+      AND CMAKE_VERSION VERSION_LESS 3.3)
+    list(APPEND CMAKE_CXX_COMPILE_FEATURES cxx_some_known_feature)
+  endif()
+
+  add_library(some_lib some_lib.cpp)
+  target_compile_features(some_lib PRIVATE
+    cxx_some_known_feature) # No error with MSVC 1900 and CMake 3.2.
+
+
+Optional Compile Features
+=========================
+
+Compile features may be preferred if available, without creating a hard
+requirement.  For example, a library may provides alternative
+implementations depending on whether the ``cxx_variadic_templates``
+feature is available:
+
+.. code-block:: c++
+
+  #if Foo_COMPILER_CXX_VARIADIC_TEMPLATES
+  template<int I, int... Is>
+  struct Interface;
+
+  template<int I>
+  struct Interface<I>
+  {
+    static int accumulate()
+    {
+      return I;
+    }
+  };
+
+  template<int I, int... Is>
+  struct Interface
+  {
+    static int accumulate()
+    {
+      return I + Interface<Is...>::accumulate();
+    }
+  };
+  #else
+  template<int I1, int I2 = 0, int I3 = 0, int I4 = 0>
+  struct Interface
+  {
+    static int accumulate() { return I1 + I2 + I3 + I4; }
+  };
+  #endif
+
+Such an interface depends on using the correct preprocessor defines for the
+compiler features.  CMake can generate a header file containing such
+defines using the :module:`WriteCompilerDetectionHeader` module.  The
+module contains the ``write_compiler_detection_header`` function which
+accepts parameters to control the content of the generated header file:
+
+.. code-block:: cmake
+
+  write_compiler_detection_header(
+    FILE "${CMAKE_CURRENT_BINARY_DIR}/foo_compiler_detection.h"
+    PREFIX Foo
+    COMPILERS GNU Clang MSVC
+    FEATURES
+      cxx_variadic_templates
+  )
+
+Such a header file may be used internally in the source code of a project,
+and it may be installed and used in the interface of library code.
+
+For each feature listed in ``FEATURES``, a preprocessor definition
+matching ``${PREFIX}_COMPILER_${FEATURE_NAME_UPPER}`` is created in the
+header file, and defined to either ``1`` or ``0``.
+
+Additionally, some features call for additional defines, such as the
+``cxx_final`` and ``cxx_override`` features. Rather than being used in
+``#ifdef`` code, the ``final`` keyword should be abstracted by a symbol
+which is defined to either ``final``, a compiler-specific equivalent, or
+to empty.  That way, C++ code can be written to unconditionally use the
+symbol, and compiler support determines what it is expanded to:
+
+.. code-block:: c++
+
+  struct Interface {
+    virtual void Execute() = 0;
+  };
+
+  struct Concrete Foo_DECL_CXX_FINAL {
+    void Execute() Foo_DECL_CXX_OVERRIDE;
+  };
+
+In this case, ``Foo_DECL_CXX_FINAL`` will expand to ``final`` if the
+compiler supports the keyword, or to ``sealed`` if certain versions
+of ``MSVC`` are used which do not support ``final``, but use ``sealed``
+in the same position and with the same meaning, or to empty otherwise.
+
+Such symbol definitions match the
+pattern ``${PREFIX}_DECL_${FEATURE_NAME_UPPER}``.
+
+In this use-case, the CMake code will wish to enable a particular language
+standard if available from the compiler. The :prop_tgt:`CXX_STANDARD`
+target property variable may be set to the desired language standard
+for a particular target, and the :variable:`CMAKE_CXX_STANDARD` may be
+set to influence all following targets:
+
+.. code-block:: cmake
+
+  write_compiler_detection_header(
+    FILE "${CMAKE_CURRENT_BINARY_DIR}/foo_compiler_detection.h"
+    PREFIX Foo
+    COMPILERS GNU Clang MSVC
+    FEATURES
+      cxx_final cxx_override
+  )
+
+  # Includes foo_compiler_detection.h and uses the Foo_DECL_CXX_FINAL symbol
+  # which will expand to 'final' if the compiler supports the requested
+  # CXX_STANDARD.
+  add_library(foo foo.cpp)
+  set_property(TARGET foo PROPERTY CXX_STANDARD 11)
+
+  # Includes foo_compiler_detection.h and uses the Foo_DECL_CXX_FINAL symbol
+  # which will expand to 'final' if the compiler supports the feature,
+  # even though CXX_STANDARD is not set explicitly. The requirement of
+  # cxx_constexpr causes CMake to set CXX_STANDARD internally, which
+  # affects the compile flags.
+  add_library(foo_impl foo_impl.cpp)
+  target_compile_features(foo_impl PRIVATE cxx_constexpr)
+
+The ``write_compiler_detection_header`` function also creates compatibility
+code for other features which have standard equivalents.  For example, the
+``cxx_static_assert`` feature is emulated with a template and abstracted
+via the ``${PREFIX}_STATIC_ASSERT`` and ``${PREFIX}_STATIC_ASSERT_MSG``
+function-macros.
+
+Conditional Compilation Options
+===============================
+
+Libraries may provide entirely different header files depending on
+requested compiler features.
+
+For example, a header at ``with_variadics/interface.h`` may contain:
+
+.. code-block:: c++
+
+  template<int I, int... Is>
+  struct Interface;
+
+  template<int I>
+  struct Interface<I>
+  {
+    static int accumulate()
+    {
+      return I;
+    }
+  };
+
+  template<int I, int... Is>
+  struct Interface
+  {
+    static int accumulate()
+    {
+      return I + Interface<Is...>::accumulate();
+    }
+  };
+
+while a header at ``no_variadics/interface.h`` may contain:
+
+.. code-block:: c++
+
+  template<int I1, int I2 = 0, int I3 = 0, int I4 = 0>
+  struct Interface
+  {
+    static int accumulate() { return I1 + I2 + I3 + I4; }
+  };
+
+It would be possible to write a abstraction ``interface.h`` header
+containing something like:
+
+.. code-block:: c++
+
+  #include "foo_compiler_detection.h"
+  #if Foo_COMPILER_CXX_VARIADIC_TEMPLATES
+  #include "with_variadics/interface.h"
+  #else
+  #include "no_variadics/interface.h"
+  #endif
+
+However this could be unmaintainable if there are many files to
+abstract. What is needed is to use alternative include directories
+depending on the compiler capabilities.
+
+CMake provides a ``HAVE_COMPILE_FEATURE``
+:manual:`generator expression <cmake-generator-expressions(7)>` to implement
+such conditions.  This may be used with the
+:command:`target_include_directories`, or :command:`target_link_libraries`
+to set the appropriate :manual:`buildsystem <cmake-buildsystem(7)>`
+properties:
+
+.. code-block:: cmake
+
+  add_library(with_variadics INTERFACE)
+  target_include_directories(with_variadics
+    INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/with_variadics")
+
+  add_library(no_variadics INTERFACE)
+  target_include_directories(no_variadics
+    INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/no_variadics")
+
+  add_library(foo INTERFACE)
+  target_link_libraries(foo
+    INTERFACE
+      $<$<HAVE_COMPILER_FEATURE:cxx_variadic_templates>:have_variadics>
+      $<$<NOT:$<HAVE_COMPILER_FEATURE:cxx_variadic_templates>>:no_variadics>)
+
+Consuming code then simply links to the ``foo`` target as usual and uses
+the feature-appropriate include directory
+
+.. code-block:: cmake
+
+  add_executable(consumer_with consumer_with.cpp)
+  target_link_libraries(consumer_with foo)
+  set_property(TARGET consumer_with CXX_STANDARD 11)
+
+  add_executable(consumer_no consumer_no.cpp)
+  target_link_libraries(consumer_no foo)
diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst
index d025d63..bed7741 100644
--- a/Help/manual/cmake-developer.7.rst
+++ b/Help/manual/cmake-developer.7.rst
@@ -197,6 +197,33 @@ Templates
 Some template code is permitted, but with some limitations. Member templates
 may not be used, and template friends may not be used.
 
+Adding Compile Features
+=======================
+
+CMake reports an error if a compiler whose features are known does not report
+support for a particular requested feature.  A compiler is considered to have
+known features if it reports support for at least one feature.
+
+When adding a new compile feature to CMake, it is therefore necessary to list
+support for the feature for all CompilerIds which already have one or more
+feature supported, if the new feature is available for any version of the
+compiler.
+
+When adding the first supported feature to a particular CompilerId, it is
+necessary to list support for all features
+:variable:`known to cmake <CMAKE_CXX_COMPILE_FEATURES>`, where available for
+the compiler.
+
+When a new version of a known compiler is made available, and there are
+already known features for that compiler, the feature should be listed as
+supported in CMake as soon as reasonably possible.  The feature should only
+be supported after the final release of the new version of the compiler.
+
+Standard-specific variables such ``CMAKE_CXX98_COMPILE_FEATURES`` are
+deliberately not documented.  They only exist for the compiler-specific
+implementation of adding the ``-std`` compile flag for compilers
+which need that.
+
 Help
 ====
 
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index e5d5eaa..fa26e8f 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -84,7 +84,8 @@ otherwise expands to nothing.
   will be emitted. This generator expression only works for a subset of
   policies.
 ``$<HAVE_COMPILE_FEATURE:feature>``
-  ``1`` if the relevant compiler supports ``feature``, otherwise ``0``.
+  ``1`` if the relevant compiler supports the ``feature``
+  :manual:`compile feature <cmake-compile-features(7)>` , otherwise ``0``.
 
 Informational Expressions
 =========================
diff --git a/Help/prop_tgt/CXX_EXTENSIONS.rst b/Help/prop_tgt/CXX_EXTENSIONS.rst
index b9c9931..14e312f 100644
--- a/Help/prop_tgt/CXX_EXTENSIONS.rst
+++ b/Help/prop_tgt/CXX_EXTENSIONS.rst
@@ -6,3 +6,6 @@ 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.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+required and optional compile features.
diff --git a/Help/prop_tgt/CXX_STANDARD.rst b/Help/prop_tgt/CXX_STANDARD.rst
index e1b6e78..719c60d 100644
--- a/Help/prop_tgt/CXX_STANDARD.rst
+++ b/Help/prop_tgt/CXX_STANDARD.rst
@@ -9,6 +9,9 @@ flag such as ``-std=c++11`` to the compile line.
 
 Supported values are ``98`` and ``11``.
 
+See the :manual:`cmake-compile-features(7)` manual for information on
+required and optional compile features.
+
 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
index a98e362..2290a27 100644
--- a/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
+++ b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
@@ -11,4 +11,6 @@ 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.
+manual for available expressions.  See the
+:manual:`cmake-compile-features(7)` manual for information on required and
+optional compile features.
diff --git a/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
index 386f5c0..15ace87 100644
--- a/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
+++ b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
@@ -9,3 +9,6 @@ variable.
 
 The features listed here may be used with the :command:`target_compile_features`
 command.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+required and optional compile features.
diff --git a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
index ed0722e..34a1aad 100644
--- a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
+++ b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
@@ -7,6 +7,9 @@ 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.
 
+See the :manual:`cmake-compile-features(7)` manual for information on
+required and optional compile features.
+
 The features known to this version of CMake are:
 
 ``cxx_delegating_constructors``
diff --git a/Help/variable/CMAKE_CXX_STANDARD.rst b/Help/variable/CMAKE_CXX_STANDARD.rst
index 5fd4138..014ad42 100644
--- a/Help/variable/CMAKE_CXX_STANDARD.rst
+++ b/Help/variable/CMAKE_CXX_STANDARD.rst
@@ -6,3 +6,6 @@ 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.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+required and optional compile features.

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6696b57426868e1dd1f9b6f9d1fc1d2994e65832
commit 6696b57426868e1dd1f9b6f9d1fc1d2994e65832
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Oct 21 16:59:40 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:46 2014 +0100

    Add the WriteCompilerDetectionHeader module.
    
    Provide a function to write a portable header to detect compiler
    features.

diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst
index 2bbe622..ecc9cc4 100644
--- a/Help/manual/cmake-modules.7.rst
+++ b/Help/manual/cmake-modules.7.rst
@@ -232,3 +232,4 @@ All Modules
    /module/UsewxWidgets
    /module/Use_wxWindows
    /module/WriteBasicConfigVersionFile
+   /module/WriteCompilerDetectionHeader
diff --git a/Help/module/WriteCompilerDetectionHeader.rst b/Help/module/WriteCompilerDetectionHeader.rst
new file mode 100644
index 0000000..4c81b48
--- /dev/null
+++ b/Help/module/WriteCompilerDetectionHeader.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/WriteCompilerDetectionHeader.cmake
diff --git a/Modules/Compiler/Clang-CXX-FeatureTests.cmake b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
index cb7f091..487333b 100644
--- a/Modules/Compiler/Clang-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
@@ -1,4 +1,6 @@
 
+set(_cmake_compiler_test_macro "defined(__clang__) && !defined(__apple_build_version__)")
+
 set(testable_features
   cxx_delegating_constructors
   cxx_variadic_templates
diff --git a/Modules/Compiler/GNU-CXX-FeatureTests.cmake b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
index a9dddd8..6e835a8 100644
--- a/Modules/Compiler/GNU-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
@@ -1,4 +1,6 @@
 
+set(_cmake_compiler_test_macro "defined(__GNUC__)")
+
 set(_cmake_feature_test_gnuxx_typeof "!defined(__STRICT_ANSI__)")
 
 # For GCC 4.7, we can test the standard __cplusplus macro, ...
diff --git a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
index 79f40e2..45c23c9 100644
--- a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
@@ -1,4 +1,6 @@
 
+set(_cmake_compiler_test_macro "defined(_MSC_VER)")
+
 set(_cmake_feature_test_cxx_delegating_constructors "_MSC_VER >= 1800")
 set(_cmake_feature_test_cxx_variadic_templates "_MSC_VER >= 1800")
 
@@ -8,3 +10,6 @@ set(_cmake_feature_test_cxx_static_assert "_MSC_VER >= 1600")
 
 set(_cmake_feature_test_cxx_final "_MSC_VER >= 1700")
 set(_cmake_feature_test_cxx_override "_MSC_VER >= 1400")
+
+set(_cmake_symbol_alternative_cxx_final "sealed")
+set(_cmake_symbol_alternative_test_cxx_final "_MSC_VER >= 1400")
diff --git a/Modules/Compiler/QCC-CXX-FeatureTests.cmake b/Modules/Compiler/QCC-CXX-FeatureTests.cmake
new file mode 100644
index 0000000..23e312c
--- /dev/null
+++ b/Modules/Compiler/QCC-CXX-FeatureTests.cmake
@@ -0,0 +1,4 @@
+
+include(Compiler/GNU-CXX-FeatureTests)
+
+set(_cmake_compiler_test_macro "defined(__QNXNTO__)")
diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake
new file mode 100644
index 0000000..7fcd047
--- /dev/null
+++ b/Modules/WriteCompilerDetectionHeader.cmake
@@ -0,0 +1,270 @@
+#.rst:
+# WriteCompilerDetectionHeader
+# ----------------------------
+#
+# Function for generation of compile feature conditionals
+#
+# This module provides the function write_compiler_detection_header().
+#
+# The ``GENERATE_EXPORT_HEADER`` function can be used to generate a file
+# suitable for preprocessor inclusion which contains macros to be
+# used in source code::
+#
+#    write_compiler_detection_header(
+#              FILE <file>
+#              PREFIX <prefix>
+#              [VERSION <version>]
+#              COMPILERS <compiler> [...]
+#              FEATURES <feature> [...]
+#    )
+#
+# The ``write_compiler_detection_header`` function generates the
+# file ``<file>`` with macros which all have the prefix ``<prefix>``.
+#
+# ``VERSION`` may be used to specify a generation compatibility with older
+# CMake versions.  By default, a file is generated with compatibility with
+# the :variable:`CMAKE_MINIMUM_REQUIRED_VERSION`.  Newer CMake versions may
+# generate additional code, and the ``VERSION`` may be used to maintain
+# compatibility in the generated file while allowing the minimum CMake
+# version of the project to be changed indepenendently.
+#
+# At least one ``<compiler>`` and one ``<feature>`` must be listed.
+#
+# Feature Test Macros
+# ===================
+#
+# For each compiler, a preprocessor test of the compiler version is generated
+# denoting whether the each feature is enabled.  A preprocessor macro
+# matching ``${PREFIX}_COMPILER_${FEATURE_NAME_UPPER}`` is generated to
+# contain the value ``0`` or ``1`` depending on whether the compiler in
+# use supports the feature:
+#
+# .. code-block:: cmake
+#
+#    write_compiler_detection_header(
+#      FILE climbingstats_compiler_detection.h
+#      PREFIX ClimbingStats
+#      COMPILERS GNU Clang MSVC
+#      FEATURES cxx_variadic_templates
+#    )
+#
+# .. code-block:: c++
+#
+#    #if ClimbingStats_COMPILER_CXX_VARIADIC_TEMPLATES
+#    template<typename... T>
+#    void someInterface(T t...) { /* ... */ }
+#    #else
+#    // Compatibility versions
+#    template<typename T1>
+#    void someInterface(T1 t1) { /* ... */ }
+#    template<typename T1, typename T2>
+#    void someInterface(T1 t1, T2 t2) { /* ... */ }
+#    template<typename T1, typename T2, typename T3>
+#    void someInterface(T1 t1, T2 t2, T3 t3) { /* ... */ }
+#    #endif
+#
+# Symbol Macros
+# =============
+#
+# Some additional symbol-defines are created for particular features for
+# use as symbols which are conditionally defined empty. The macros for
+# such symbol defines match ``${PREFIX}_DECL_${FEATURE_NAME_UPPER}``:
+#
+# .. code-block:: c++
+#
+#    class MyClass ClimbingStats_DECL_CXX_FINAL
+#    {
+#        ClimbingStats_DECL_CXX_CONSTEXPR int someInterface() { return 42; }
+#    };
+#
+# The ``ClimbingStats_DECL_CXX_FINAL`` macro will expand to ``final`` if the
+# compiler (and its flags) support the ``cxx_final`` feature, and the
+# ``ClimbingStats_DECL_CXX_CONSTEXPR`` macro will expand to ``constexpr``
+# if ``cxx_constexpr`` is supported.
+#
+# In the case of the ``cxx_final`` feature with a version of MSVC which
+# does not support ``final``, the ``ClimbingStats_DECL_CXX_FINAL`` macro
+# expands to ``sealed`` if using a MSVC version which supports that
+# extension.  The MSVC ``sealed`` keyword is an extension which is
+# supported in the same position and meaning as the standardised ``final``
+# keyword.
+#
+# The following features generate corresponding symbol defines:
+#
+# * ``cxx_final``
+# * ``cxx_override``
+# * ``cxx_constexpr``
+#
+# Compatibility Implemetation Macros
+# ==================================
+#
+# Some features are suitable for wrapping in a macro with a backward
+# compatibility implementation if the compiler does not support the feature.
+#
+# When the ``cxx_static_assert`` feature is not provided by the compiler,
+# a compatibility implementation is available via the
+# ``${PREFIX}_STATIC_ASSERT`` and ``${PREFIX}_STATIC_ASSERT_MSG``
+# function-like macros. The macros expand to ``static_assert`` where that
+# compiler feature is available, and to a compatibility implementation
+# otherwise.
+
+#=============================================================================
+# Copyright 2013 Stephen Kelly <steveire at 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.)
+
+include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake)
+
+function(_load_compiler_variables CompilerId lang)
+  include("${CMAKE_ROOT}/Modules/Compiler/${CompilerId}-${lang}-FeatureTests.cmake" OPTIONAL)
+  if (NOT _cmake_compiler_test_macro)
+    message(FATAL_ERROR "Compiler ${CompilerId} does not define _cmake_compiler_test_macro")
+  endif()
+  set(COMPILER_TEST_${CompilerId} "${_cmake_compiler_test_macro}" PARENT_SCOPE)
+  foreach(feature ${ARGN})
+    set(_cmake_feature_test_${CompilerId}_${feature} ${_cmake_feature_test_${feature}} PARENT_SCOPE)
+    if (_cmake_symbol_alternative_${feature})
+      set(_cmake_symbol_alternative_${CompilerId}_${feature} ${_cmake_symbol_alternative_${feature}} PARENT_SCOPE)
+      set(_cmake_symbol_alternative_test_${CompilerId}_${feature} ${_cmake_symbol_alternative_test_${feature}} PARENT_SCOPE)
+    endif()
+  endforeach()
+endfunction()
+
+function(write_compiler_detection_header
+    file_keyword file_arg
+    prefix_keyword prefix_arg
+    )
+  if (NOT file_keyword STREQUAL FILE)
+    message(FATAL_ERROR "Wrong parameters for function.")
+  endif()
+  if (NOT prefix_keyword STREQUAL PREFIX)
+    message(FATAL_ERROR "Wrong parameters for function.")
+  endif()
+  set(options)
+  set(oneValueArgs VERSION)
+  set(multiValueArgs COMPILERS FEATURES)
+  cmake_parse_arguments(_WCD "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+  if(NOT _WCD_COMPILERS OR NOT _WCD_FEATURES)
+    message(FATAL_ERROR "Invalid arguments.")
+  endif()
+
+  if(_WCD_UNPARSED_ARGUMENTS)
+    message(FATAL_ERROR "Unparsed arguments: ${_WCD_UNPARSED_ARGUMENTS}")
+  endif()
+
+  if(NOT _WCD_VERSION)
+    set(_WCD_VERSION ${CMAKE_MINIMUM_REQUIRED_VERSION})
+  endif()
+#   if (_WCD_VERSION VERSION_LESS 3.0.0) # Version which introduced this function
+#     message(FATAL_ERROR "VERSION parameter too low.")
+#   endif()
+  cmake_policy(GET CMP0025 setting_25)
+  if(NOT setting_25 STREQUAL NEW)
+    message(FATAL_ERROR "Policy CMP0025 must be NEW to use this function.")
+  endif()
+  cmake_policy(GET CMP0046 setting_46)
+  if(NOT setting_46 STREQUAL NEW)
+    message(FATAL_ERROR "Policy CMP0046 must be NEW to use this function.")
+  endif()
+
+  set(ordered_compilers
+    # Order is relevant here. We need to list the compilers which pretend to
+    # be GNU/MSVC before the actual GNU/MSVC compiler.
+    QCC
+    Clang
+    GNU
+    MSVC
+  )
+  foreach(_comp ${_WCD_COMPILERS})
+    list(FIND ordered_compilers ${_comp} idx)
+    if (idx EQUAL -1)
+      message(FATAL_ERROR "Unsupported compiler ${_comp}.")
+    endif()
+  endforeach()
+
+  file(WRITE ${file_arg} "
+// This is a generated file. Do not edit!
+
+#ifndef ${prefix_arg}_COMPILER_DETECTION_H
+#define ${prefix_arg}_COMPILER_DETECTION_H
+
+#if !defined (__clang__)
+#  define __has_extension(ext) 0
+#endif
+")
+
+  foreach(_lang CXX)
+
+    if(_lang STREQUAL CXX)
+      file(APPEND "${file_arg}" "\n#ifdef __cplusplus\n")
+    endif()
+
+    set(pp_if "if")
+    foreach(ordered_compiler ${ordered_compilers})
+      list(FIND _WCD_COMPILERS ${ordered_compiler} idx)
+      if (NOT idx EQUAL -1)
+        _load_compiler_variables(${ordered_compiler} ${_lang} ${_WCD_FEATURES})
+        file(APPEND "${file_arg}" "\n#  ${pp_if} ${COMPILER_TEST_${ordered_compiler}}\n")
+        set(pp_if "elif")
+        foreach(feature ${_WCD_FEATURES})
+          list(FIND CMAKE_${_lang}_KNOWN_FEATURES ${feature} idx)
+          if (NOT idx EQUAL -1)
+            set(_define_check "\n#    define ${prefix_arg}_${CMAKE_PP_NAME_${feature}} 0\n")
+            if (_cmake_feature_test_${ordered_compiler}_${feature} STREQUAL "1")
+              set(_define_check "\n#    define ${prefix_arg}_${CMAKE_PP_NAME_${feature}} 1\n")
+            elseif (_cmake_feature_test_${ordered_compiler}_${feature})
+              set(_define_check "\n#      define ${prefix_arg}_${CMAKE_PP_NAME_${feature}} 0\n")
+              set(_define_check "\n#    if ${_cmake_feature_test_${ordered_compiler}_${feature}}\n#      define ${prefix_arg}_${CMAKE_PP_NAME_${feature}} 1\n#    else${_define_check}#    endif\n")
+            endif()
+            file(APPEND "${file_arg}" "${_define_check}")
+          endif()
+        endforeach()
+      endif()
+    endforeach()
+    if(pp_if STREQUAL "elif")
+      file(APPEND "${file_arg}" "\n#  else\n")
+      foreach(feature ${_WCD_FEATURES})
+        file(APPEND "${file_arg}" "\n#    define ${prefix_arg}_${CMAKE_PP_NAME_${feature}} 0\n")
+      endforeach()
+      file(APPEND "${file_arg}" "\n#  endif\n\n")
+    endif()
+    foreach(feature ${_WCD_FEATURES})
+      set(def_value ${CMAKE_SYMBOL_DEFINE_${feature}})
+      if (def_value)
+        set(def_name ${prefix_arg}_${CMAKE_PP_DECL_${feature}})
+        foreach(ordered_compiler ${ordered_compilers})
+          if (_cmake_symbol_alternative_test_${ordered_compiler}_${feature})
+            set(alternatives "${alternatives}#  elif ${_cmake_symbol_alternative_test_${ordered_compiler}_${feature}}\n#    define ${def_name} ${_cmake_symbol_alternative_${ordered_compiler}_${feature}}\n")
+          endif()
+        endforeach()
+        file(APPEND "${file_arg}" "#  if ${prefix_arg}_${CMAKE_PP_NAME_${feature}}\n#    define ${def_name} ${def_value}\n${alternatives}#  else\n#    define ${def_name}\n#  endif\n\n")
+      endif()
+    endforeach()
+    foreach(feature ${_WCD_FEATURES})
+      if (feature STREQUAL cxx_static_assert)
+        set(def_name ${prefix_arg}_${CMAKE_PP_NAME_cxx_static_assert})
+        set(def_value "${prefix_arg}_STATIC_ASSERT(X)")
+        set(def_value_msg "${prefix_arg}_STATIC_ASSERT_MSG(X, MSG)")
+        set(static_assert_struct "template<bool> struct ${prefix_arg}StaticAssert;\ntemplate<> struct ${prefix_arg}StaticAssert<true>{};\n")
+        set(def_standard "#    define ${def_value} static_assert(X, #X)\n#    define ${def_value_msg} static_assert(X, MSG)")
+        set(def_alternative "${static_assert_struct}#    define ${def_value} sizeof(CMakeStaticAssert<X>)\n#    define ${def_value_msg} sizeof(CMakeStaticAssert<X>)")
+        file(APPEND "${file_arg}" "#  if ${def_name}\n${def_standard}\n#  else\n${def_alternative}\n#  endif\n\n")
+      endif()
+    endforeach()
+    if(_lang STREQUAL CXX)
+      file(APPEND "${file_arg}" "#endif\n")
+    endif()
+
+  endforeach()
+
+  file(APPEND ${file_arg} "\n#endif\n")
+endfunction()
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 08f61b4..b3ed9ac 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -2476,6 +2476,25 @@ const char* cmMakefile::GetDefinition(const std::string& name) const
     }
   FOR_EACH_CXX_FEATURE(PP_FEATURE_NAME)
 #undef PP_FEATURE_NAME
+
+#define FOR_EACH_CXX_DECL_FEATURE(F) \
+  F(final) \
+  F(override) \
+  F(constexpr)
+
+#define PP_DECL_NAME(F) \
+  if (name == "CMAKE_PP_DECL_cxx_" #F) \
+    { \
+    static std::string val = ("DECL_CXX_" + cmSystemTools::UpperCase(#F)); \
+    return val.c_str(); \
+    } \
+  if (name == "CMAKE_SYMBOL_DEFINE_cxx_" #F) \
+    { \
+    return #F; \
+    }
+  FOR_EACH_CXX_DECL_FEATURE(PP_DECL_NAME)
+#undef PP_DECL_NAME
+
   const char* def = this->Internal->VarStack.top().Get(name);
   if(!def)
     {
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index b39b728..8245f61 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -403,6 +403,17 @@ if(BUILD_TESTING)
   ADD_TEST_MACRO(Module.GenerateExportHeader GenerateExportHeader)
   ADD_TEST_MACRO(Module.FindDependency FindDependency)
 
+  if ((CMAKE_CXX_COMPILER_ID STREQUAL GNU AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.3)
+      OR CMAKE_CXX_COMPILER_ID STREQUAL Clang
+      OR (x${CMAKE_CXX_COMPILER_ID} STREQUAL xMSVC AND NOT MSVC_VERSION VERSION_LESS 1400))
+    if(NOT APPLE OR POLICY CMP0025)
+      set(runCompilerDetectionTest 1)
+    endif()
+  endif()
+
+  if (runCompilerDetectionTest)
+    ADD_TEST_MACRO(Module.WriteCompilerDetectionHeader WriteCompilerDetectionHeader)
+  endif()
   if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
     include(CheckCXXCompilerFlag)
     check_cxx_compiler_flag(-fPIE run_pic_test)
diff --git a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt
new file mode 100644
index 0000000..c658942
--- /dev/null
+++ b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt
@@ -0,0 +1,100 @@
+cmake_minimum_required(VERSION 3.0.0)
+project(WriteCompilerDetectionHeader)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+include(WriteCompilerDetectionHeader)
+
+write_compiler_detection_header(
+  FILE "${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection.h"
+  PREFIX TEST
+  COMPILERS GNU Clang MSVC
+  FEATURES
+    ${CMAKE_CXX_KNOWN_FEATURES}
+)
+
+macro(set_defines target true_defs false_defs)
+  set(defines)
+  foreach(def ${true_defs})
+    list(APPEND defines ${def}=1)
+  endforeach()
+  foreach(def ${false_defs})
+    list(APPEND defines ${def}=0)
+  endforeach()
+  target_compile_definitions(${target}
+    PRIVATE
+      ${defines}
+  )
+endmacro()
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL GNU
+    OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
+  list(APPEND true_defs EXPECTED_COMPILER_CXX_BINARY_LITERALS)
+  list(APPEND false_defs EXPECTED_COMPILER_MSVCXX_SEALED)
+elseif(x${CMAKE_CXX_COMPILER_ID} STREQUAL xMSVC)
+  list(APPEND false_defs EXPECTED_COMPILER_CXX_BINARY_LITERALS)
+  list(APPEND true_defs EXPECTED_COMPILER_MSVCXX_SEALED)
+else()
+  list(APPEND false_defs EXPECTED_COMPILER_CXX_BINARY_LITERALS)
+  list(APPEND false_defs EXPECTED_COMPILER_MSVCXX_SEALED)
+endif()
+
+list(APPEND false_defs EXPECTED_COMPILER_GNUXX_TYPEOF)
+list(APPEND false_defs EXPECTED_COMPILER_CXX_DELEGATING_CONSTRUCTORS)
+list(APPEND false_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES)
+
+add_executable(WriteCompilerDetectionHeader main.cpp)
+set_property(TARGET WriteCompilerDetectionHeader PROPERTY CXX_STANDARD 98)
+set_defines(WriteCompilerDetectionHeader "${true_defs}" "${false_defs}")
+
+if(MSVC)
+  return() # MSVC has only one mode.
+endif()
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL GNU
+    OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
+  list(APPEND true_defs EXPECTED_COMPILER_GNUXX_TYPEOF)
+  list(REMOVE_ITEM false_defs EXPECTED_COMPILER_GNUXX_TYPEOF)
+endif()
+
+add_executable(WriteCompilerDetectionHeader_98ext main.cpp)
+set_property(TARGET WriteCompilerDetectionHeader_98ext PROPERTY CXX_STANDARD 98)
+set_property(TARGET WriteCompilerDetectionHeader_98ext PROPERTY CXX_EXTENSIONS 1)
+set_defines(WriteCompilerDetectionHeader_98ext "${true_defs}" "${false_defs}")
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL GNU
+    OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
+  list(APPEND false_defs  EXPECTED_COMPILER_GNUXX_TYPEOF)
+  list(REMOVE_ITEM true_defs EXPECTED_COMPILER_GNUXX_TYPEOF)
+endif()
+
+if ((CMAKE_CXX_COMPILER_ID STREQUAL GNU
+      AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7.0)
+    OR (CMAKE_CXX_COMPILER_ID STREQUAL Clang
+      AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.0.0))
+  list(APPEND true_defs EXPECTED_COMPILER_CXX_DELEGATING_CONSTRUCTORS)
+  list(REMOVE_ITEM false_defs EXPECTED_COMPILER_CXX_DELEGATING_CONSTRUCTORS)
+endif()
+
+if ((CMAKE_CXX_COMPILER_ID STREQUAL GNU
+      AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4.0)
+    OR (CMAKE_CXX_COMPILER_ID STREQUAL Clang
+      AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.0.0))
+  list(APPEND true_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES)
+  list(REMOVE_ITEM false_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES)
+endif()
+
+add_executable(WriteCompilerDetectionHeader_11 main.cpp)
+set_property(TARGET WriteCompilerDetectionHeader_11 PROPERTY CXX_STANDARD 11)
+set_defines(WriteCompilerDetectionHeader_11 "${true_defs}" "${false_defs}")
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL GNU
+    OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
+  list(APPEND true_defs EXPECTED_COMPILER_GNUXX_TYPEOF)
+  list(REMOVE_ITEM false_defs EXPECTED_COMPILER_GNUXX_TYPEOF)
+endif()
+
+add_executable(WriteCompilerDetectionHeader_11ext main.cpp)
+set_property(TARGET WriteCompilerDetectionHeader_11ext PROPERTY CXX_STANDARD 11)
+set_property(TARGET WriteCompilerDetectionHeader_11ext PROPERTY CXX_EXTENSIONS 1)
+set_defines(WriteCompilerDetectionHeader_11ext "${true_defs}" "${false_defs}")
diff --git a/Tests/Module/WriteCompilerDetectionHeader/main.cpp b/Tests/Module/WriteCompilerDetectionHeader/main.cpp
new file mode 100644
index 0000000..cccd19d
--- /dev/null
+++ b/Tests/Module/WriteCompilerDetectionHeader/main.cpp
@@ -0,0 +1,31 @@
+
+#include "test_compiler_detection.h"
+
+#define JOIN_IMPL(A, B) A ## B
+#define JOIN(A, B) JOIN_IMPL(A, B)
+#define CHECK(FEATURE) (JOIN(TEST_COMPILER_, FEATURE) == JOIN(EXPECTED_COMPILER_, FEATURE))
+
+#if !CHECK(CXX_BINARY_LITERALS)
+#error cxx_binary_literals expected availability did not match.
+#endif
+
+#if !CHECK(CXX_DELEGATING_CONSTRUCTORS)
+#error cxx_delegating_constructors expected availability did not match.
+#endif
+
+#if !CHECK(CXX_VARIADIC_TEMPLATES)
+#error cxx_variadic_templates expected availability did not match.
+#endif
+
+#if !CHECK(GNUXX_TYPEOF)
+#error gnuxx_typeof expected availability did not match.
+#endif
+
+#if !CHECK(MSVCXX_SEALED)
+#error msvcxx_sealed expected availability did not match.
+#endif
+
+int main(int argc, char **argv)
+{
+  return 0;
+}

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=03b29748f2a93baa2cec4aaf9dcf55cda59c937c
commit 03b29748f2a93baa2cec4aaf9dcf55cda59c937c
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Mar 19 13:32:59 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:46 2014 +0100

    Add cxx_override feature.

diff --git a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
index 6c1b04f..ed0722e 100644
--- a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
+++ b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
@@ -39,6 +39,11 @@ The features known to this version of CMake are:
 
 .. _N2928: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm
 
+``cxx_override``
+  Override control ``override`` keyword, as defined in N2928_.
+
+.. _N2928: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm
+
 ``gnuxx_typeof``
   The GNU typeof extension.
 
diff --git a/Modules/Compiler/Clang-CXX-FeatureTests.cmake b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
index 58248b9..cb7f091 100644
--- a/Modules/Compiler/Clang-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
@@ -13,4 +13,5 @@ unset(testable_features)
 
 set(_cmake_feature_test_gnuxx_typeof "!defined(__STRICT_ANSI__)")
 set(_cmake_feature_test_cxx_final "__has_extension(cxx_override_control)")
+set(_cmake_feature_test_cxx_override "__has_extension(cxx_override_control)")
 set(_cmake_feature_test_cxx_binary_literals "1")
diff --git a/Modules/Compiler/GNU-CXX-FeatureTests.cmake b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
index a2cbf41..a9dddd8 100644
--- a/Modules/Compiler/GNU-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
@@ -13,5 +13,6 @@ set(_cmake_feature_test_cxx_delegating_constructors "(__GNUC__ * 100 + __GNUC_MI
 set(_cmake_feature_test_cxx_variadic_templates "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && defined(__GXX_EXPERIMENTAL_CXX0X__)")
 set(_cmake_feature_test_cxx_static_assert "(__GNUC__ * 100 + __GNUC_MINOR__) >= 403 && defined(__GXX_EXPERIMENTAL_CXX0X__)")
 set(_cmake_feature_test_cxx_final "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L")
+set(_cmake_feature_test_cxx_override "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L")
 set(_cmake_feature_test_cxx_constexpr "(__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && defined(__GXX_EXPERIMENTAL_CXX0X__)")
 set(_cmake_feature_test_cxx_binary_literals "1")
diff --git a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
index 7458ddd..79f40e2 100644
--- a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
@@ -7,3 +7,4 @@ set(_cmake_feature_test_msvcxx_sealed "_MSC_VER >= 1400")
 set(_cmake_feature_test_cxx_static_assert "_MSC_VER >= 1600")
 
 set(_cmake_feature_test_cxx_final "_MSC_VER >= 1700")
+set(_cmake_feature_test_cxx_override "_MSC_VER >= 1400")
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index d68656a..08f61b4 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -48,6 +48,7 @@
   F(cxx_binary_literals) \
   F(cxx_static_assert) \
   F(cxx_final) \
+  F(cxx_override) \
   F(gnuxx_typeof) \
   F(msvcxx_sealed)
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=47917d2485870965d2a6df5c50d3d7b5bad9fd67
commit 47917d2485870965d2a6df5c50d3d7b5bad9fd67
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Mar 18 23:42:05 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:46 2014 +0100

    Add cxx_final feature.

diff --git a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
index 226bf06..6c1b04f 100644
--- a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
+++ b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
@@ -34,6 +34,11 @@ The features known to this version of CMake are:
 
 .. _N1720: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html
 
+``cxx_final``
+  Override control ``final`` keyword, as defined in N2928_.
+
+.. _N2928: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm
+
 ``gnuxx_typeof``
   The GNU typeof extension.
 
diff --git a/Modules/Compiler/Clang-CXX-FeatureTests.cmake b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
index c90614b..58248b9 100644
--- a/Modules/Compiler/Clang-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
@@ -12,4 +12,5 @@ endforeach()
 unset(testable_features)
 
 set(_cmake_feature_test_gnuxx_typeof "!defined(__STRICT_ANSI__)")
+set(_cmake_feature_test_cxx_final "__has_extension(cxx_override_control)")
 set(_cmake_feature_test_cxx_binary_literals "1")
diff --git a/Modules/Compiler/GNU-CXX-FeatureTests.cmake b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
index b391f6a..a2cbf41 100644
--- a/Modules/Compiler/GNU-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
@@ -12,5 +12,6 @@ set(_cmake_feature_test_gnuxx_typeof "!defined(__STRICT_ANSI__)")
 set(_cmake_feature_test_cxx_delegating_constructors "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L")
 set(_cmake_feature_test_cxx_variadic_templates "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && defined(__GXX_EXPERIMENTAL_CXX0X__)")
 set(_cmake_feature_test_cxx_static_assert "(__GNUC__ * 100 + __GNUC_MINOR__) >= 403 && defined(__GXX_EXPERIMENTAL_CXX0X__)")
+set(_cmake_feature_test_cxx_final "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L")
 set(_cmake_feature_test_cxx_constexpr "(__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && defined(__GXX_EXPERIMENTAL_CXX0X__)")
 set(_cmake_feature_test_cxx_binary_literals "1")
diff --git a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
index a0b8c7e..7458ddd 100644
--- a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
@@ -5,3 +5,5 @@ set(_cmake_feature_test_cxx_variadic_templates "_MSC_VER >= 1800")
 set(_cmake_feature_test_msvcxx_sealed "_MSC_VER >= 1400")
 
 set(_cmake_feature_test_cxx_static_assert "_MSC_VER >= 1600")
+
+set(_cmake_feature_test_cxx_final "_MSC_VER >= 1700")
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 7003429..d68656a 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -47,6 +47,7 @@
   F(cxx_constexpr) \
   F(cxx_binary_literals) \
   F(cxx_static_assert) \
+  F(cxx_final) \
   F(gnuxx_typeof) \
   F(msvcxx_sealed)
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4e5c275c341c4f4af45b100c4eca245424de9f32
commit 4e5c275c341c4f4af45b100c4eca245424de9f32
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Mar 19 01:20:01 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:46 2014 +0100

    Add cxx_static_assert feature.

diff --git a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
index 1a05fa8..226bf06 100644
--- a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
+++ b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
@@ -29,6 +29,11 @@ The features known to this version of CMake are:
 
 .. _N3472: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3472.pdf
 
+``cxx_static_assert``
+  Static assert, as defined in N1720_.
+
+.. _N1720: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html
+
 ``gnuxx_typeof``
   The GNU typeof extension.
 
diff --git a/Modules/Compiler/Clang-CXX-FeatureTests.cmake b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
index 2be818c..c90614b 100644
--- a/Modules/Compiler/Clang-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
@@ -3,6 +3,7 @@ set(testable_features
   cxx_delegating_constructors
   cxx_variadic_templates
   cxx_constexpr
+  cxx_static_assert
 )
 foreach(feature ${testable_features})
   set(_cmake_feature_test_${feature} "__has_extension(${feature})")
diff --git a/Modules/Compiler/GNU-CXX-FeatureTests.cmake b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
index 95ac30a..b391f6a 100644
--- a/Modules/Compiler/GNU-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
@@ -11,5 +11,6 @@ set(_cmake_feature_test_gnuxx_typeof "!defined(__STRICT_ANSI__)")
 
 set(_cmake_feature_test_cxx_delegating_constructors "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L")
 set(_cmake_feature_test_cxx_variadic_templates "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && defined(__GXX_EXPERIMENTAL_CXX0X__)")
+set(_cmake_feature_test_cxx_static_assert "(__GNUC__ * 100 + __GNUC_MINOR__) >= 403 && defined(__GXX_EXPERIMENTAL_CXX0X__)")
 set(_cmake_feature_test_cxx_constexpr "(__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && defined(__GXX_EXPERIMENTAL_CXX0X__)")
 set(_cmake_feature_test_cxx_binary_literals "1")
diff --git a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
index ff8084f..a0b8c7e 100644
--- a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
@@ -3,3 +3,5 @@ set(_cmake_feature_test_cxx_delegating_constructors "_MSC_VER >= 1800")
 set(_cmake_feature_test_cxx_variadic_templates "_MSC_VER >= 1800")
 
 set(_cmake_feature_test_msvcxx_sealed "_MSC_VER >= 1400")
+
+set(_cmake_feature_test_cxx_static_assert "_MSC_VER >= 1600")
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index ecb0bbe..7003429 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -46,6 +46,7 @@
   F(cxx_variadic_templates) \
   F(cxx_constexpr) \
   F(cxx_binary_literals) \
+  F(cxx_static_assert) \
   F(gnuxx_typeof) \
   F(msvcxx_sealed)
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=48be47970c0648256c5decff7c8636b692c9e537
commit 48be47970c0648256c5decff7c8636b692c9e537
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Sun Oct 13 10:42:02 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:46 2014 +0100

    Add a cxx_binary_literals feature.
    
    Supported by GCC in c++98 mode, though it is a c++1y standard feature.

diff --git a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
index 950a08f..1a05fa8 100644
--- a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
+++ b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
@@ -24,6 +24,11 @@ The features known to this version of CMake are:
 
 .. _N2235: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf
 
+``cxx_binary_literals``
+  Binary literals, as defined in N3472_.
+
+.. _N3472: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3472.pdf
+
 ``gnuxx_typeof``
   The GNU typeof extension.
 
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index 62b7f76..5dfd0d1 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -3,6 +3,7 @@ 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_CXX98_COMPILE_FEATURES "@CMAKE_CXX98_COMPILE_FEATURES@")
 set(CMAKE_CXX98_COMPILE_EXTENSIONS "@CMAKE_CXX98_COMPILE_EXTENSIONS@")
 set(CMAKE_CXX11_COMPILE_FEATURES "@CMAKE_CXX11_COMPILE_FEATURES@")
 set(CMAKE_CXX11_COMPILE_EXTENSIONS "@CMAKE_CXX11_COMPILE_EXTENSIONS@")
diff --git a/Modules/CMakeDetermineCompileFeatures.cmake b/Modules/CMakeDetermineCompileFeatures.cmake
index f93e21e..4595cf7 100644
--- a/Modules/CMakeDetermineCompileFeatures.cmake
+++ b/Modules/CMakeDetermineCompileFeatures.cmake
@@ -17,6 +17,7 @@ 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_CXX98_COMPILE_FEATURES)
     set(CMAKE_CXX98_COMPILE_EXTENSIONS)
     set(CMAKE_CXX11_COMPILE_FEATURES)
     set(CMAKE_CXX11_COMPILE_EXTENSIONS)
@@ -30,11 +31,15 @@ function(cmake_determine_compile_features lang)
       return()
     endif()
 
+    string(REPLACE "${CMAKE_CXX98_COMPILE_FEATURES}" "" CMAKE_CXX98_COMPILE_EXTENSIONS "${CMAKE_CXX98_COMPILE_EXTENSIONS}")
     string(REPLACE "${CMAKE_CXX98_COMPILE_EXTENSIONS}" "" CMAKE_CXX11_COMPILE_EXTENSIONS "${CMAKE_CXX11_COMPILE_EXTENSIONS}")
     string(REPLACE "${CMAKE_CXX11_COMPILE_FEATURES}" "" CMAKE_CXX11_COMPILE_EXTENSIONS "${CMAKE_CXX11_COMPILE_EXTENSIONS}")
+    string(REPLACE "${CMAKE_CXX98_COMPILE_FEATURES}" "" CMAKE_CXX11_COMPILE_FEATURES "${CMAKE_CXX11_COMPILE_FEATURES}")
+    string(REPLACE "${CMAKE_CXX98_COMPILE_FEATURES}" "" CMAKE_CXX98_COMPILE_EXTENSIONS "${CMAKE_CXX98_COMPILE_EXTENSIONS}")
 
     if(NOT CMAKE_CXX_COMPILE_FEATURES)
       set(CMAKE_CXX_COMPILE_FEATURES
+        ${CMAKE_CXX98_COMPILE_FEATURES}
         ${CMAKE_CXX98_COMPILE_EXTENSIONS}
         ${CMAKE_CXX11_COMPILE_FEATURES}
         ${CMAKE_CXX11_COMPILE_EXTENSIONS}
@@ -42,6 +47,7 @@ function(cmake_determine_compile_features lang)
     endif()
 
     set(CMAKE_CXX_COMPILE_FEATURES ${CMAKE_CXX_COMPILE_FEATURES} PARENT_SCOPE)
+    set(CMAKE_CXX98_COMPILE_FEATURES ${CMAKE_CXX98_COMPILE_FEATURES} PARENT_SCOPE)
     set(CMAKE_CXX98_COMPILE_EXTENSIONS ${CMAKE_CXX98_COMPILE_EXTENSIONS} PARENT_SCOPE)
     set(CMAKE_CXX11_COMPILE_FEATURES ${CMAKE_CXX11_COMPILE_FEATURES} PARENT_SCOPE)
     set(CMAKE_CXX11_COMPILE_EXTENSIONS ${CMAKE_CXX11_COMPILE_EXTENSIONS} PARENT_SCOPE)
diff --git a/Modules/Compiler/Clang-CXX-FeatureTests.cmake b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
index c46e894..2be818c 100644
--- a/Modules/Compiler/Clang-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
@@ -11,3 +11,4 @@ endforeach()
 unset(testable_features)
 
 set(_cmake_feature_test_gnuxx_typeof "!defined(__STRICT_ANSI__)")
+set(_cmake_feature_test_cxx_binary_literals "1")
diff --git a/Modules/Compiler/GNU-CXX-FeatureTests.cmake b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
index e39569a..95ac30a 100644
--- a/Modules/Compiler/GNU-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
@@ -12,3 +12,4 @@ set(_cmake_feature_test_gnuxx_typeof "!defined(__STRICT_ANSI__)")
 set(_cmake_feature_test_cxx_delegating_constructors "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L")
 set(_cmake_feature_test_cxx_variadic_templates "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && defined(__GXX_EXPERIMENTAL_CXX0X__)")
 set(_cmake_feature_test_cxx_constexpr "(__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && defined(__GXX_EXPERIMENTAL_CXX0X__)")
+set(_cmake_feature_test_cxx_binary_literals "1")
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 9fd0657..ecb0bbe 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -45,6 +45,7 @@
   F(cxx_delegating_constructors) \
   F(cxx_variadic_templates) \
   F(cxx_constexpr) \
+  F(cxx_binary_literals) \
   F(gnuxx_typeof) \
   F(msvcxx_sealed)
 
diff --git a/Tests/CMakeCommands/target_compile_features/CMakeLists.txt b/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
index ab79b29..35fcd43 100644
--- a/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
@@ -32,4 +32,11 @@ target_compile_features(lib_delegating_constructors
 add_executable(lib_user lib_user.cpp)
 target_link_libraries(lib_user lib_delegating_constructors)
 
+if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang")
+  add_executable(binary_literals binary_literals.cpp)
+  target_compile_features(binary_literals
+    PRIVATE cxx_binary_literals
+  )
+endif()
+
 add_subdirectory(feature_conditional_link)
diff --git a/Tests/CMakeCommands/target_compile_features/binary_literals.cpp b/Tests/CMakeCommands/target_compile_features/binary_literals.cpp
new file mode 100644
index 0000000..3956e73
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/binary_literals.cpp
@@ -0,0 +1,6 @@
+
+int main(int, char **)
+{
+  int i = 0b0101;
+  return i - 5;
+}
diff --git a/Tests/SystemInformation/SystemInformation.in b/Tests/SystemInformation/SystemInformation.in
index 97298dc..669a6f9 100644
--- a/Tests/SystemInformation/SystemInformation.in
+++ b/Tests/SystemInformation/SystemInformation.in
@@ -26,6 +26,7 @@ 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_CXX98_COMPILE_FEATURES == "${CMAKE_CXX98_COMPILE_FEATURES}"
 CMAKE_CXX98_COMPILE_EXTENSIONS == "${CMAKE_CXX98_COMPILE_EXTENSIONS}"
 CMAKE_CXX11_COMPILE_FEATURES == "${CMAKE_CXX11_COMPILE_FEATURES}"
 CMAKE_CXX11_COMPILE_EXTENSIONS == "${CMAKE_CXX11_COMPILE_EXTENSIONS}"

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c3ddd19ef7763d1212b8c8a218beec112f4058bd
commit c3ddd19ef7763d1212b8c8a218beec112f4058bd
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Dec 17 19:23:40 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:46 2014 +0100

    Export INTERFACE_COMPILE_FEATURES property.

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/Tests/ExportImport/Export/Interface/CMakeLists.txt b/Tests/ExportImport/Export/Interface/CMakeLists.txt
index 9d4793d..b058a80 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_constexpr INTERFACE)
+target_compile_features(use_constexpr INTERFACE cxx_constexpr)
+
+install(TARGETS headeronly sharediface use_constexpr
   EXPORT expInterface
 )
 install(TARGETS sharedlib
diff --git a/Tests/ExportImport/Import/Interface/CMakeLists.txt b/Tests/ExportImport/Import/Interface/CMakeLists.txt
index cf7e2bc..b5c2215 100644
--- a/Tests/ExportImport/Import/Interface/CMakeLists.txt
+++ b/Tests/ExportImport/Import/Interface/CMakeLists.txt
@@ -40,6 +40,30 @@ 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()
+
+  set(CMAKE_REQUIRED_LIBRARIES ${prefix}::use_constexpr)
+  check_cxx_source_compiles(
+    "
+  constexpr int getValue()
+  {
+    return 0;
+  };
+  int main(int,char**)
+  {
+    return getValue();
+  }
+  " ${prefix}IMPORTED_IFACE_CONSTEXPR)
+
+  if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";cxx_constexpr;")
+    if(NOT ${prefix}IMPORTED_IFACE_CONSTEXPR)
+      message(SEND_ERROR "${prefix} try_compile with IMPORTED INTERFACE target failed!\n\n${OUTPUT}")
+    endif()
+  else()
+    if(${prefix}IMPORTED_IFACE_CONSTEXPR)
+      message(SEND_ERROR "${prefix} try_compile with IMPORTED INTERFACE target succeeded where it should fail!\n\n${OUTPUT}")
+    endif()
+  endif()
+
 endmacro()
 
 do_try_compile(bld)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=48e747c5cf48612dd2b1241e190f769253c48cc8
commit 48e747c5cf48612dd2b1241e190f769253c48cc8
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Mar 18 12:53:01 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:45 2014 +0100

    Add cxx_constexpr feature.

diff --git a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
index f8921ca..950a08f 100644
--- a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
+++ b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
@@ -19,6 +19,11 @@ The features known to this version of CMake are:
 
 .. _N2242: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf
 
+``cxx_constexpr``
+  Constant expressions, as defined in N2235_.
+
+.. _N2235: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf
+
 ``gnuxx_typeof``
   The GNU typeof extension.
 
diff --git a/Modules/Compiler/Clang-CXX-FeatureTests.cmake b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
index 0b2ceca..c46e894 100644
--- a/Modules/Compiler/Clang-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
@@ -2,6 +2,7 @@
 set(testable_features
   cxx_delegating_constructors
   cxx_variadic_templates
+  cxx_constexpr
 )
 foreach(feature ${testable_features})
   set(_cmake_feature_test_${feature} "__has_extension(${feature})")
diff --git a/Modules/Compiler/GNU-CXX-FeatureTests.cmake b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
index 393c126..e39569a 100644
--- a/Modules/Compiler/GNU-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
@@ -11,3 +11,4 @@ set(_cmake_feature_test_gnuxx_typeof "!defined(__STRICT_ANSI__)")
 
 set(_cmake_feature_test_cxx_delegating_constructors "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L")
 set(_cmake_feature_test_cxx_variadic_templates "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && defined(__GXX_EXPERIMENTAL_CXX0X__)")
+set(_cmake_feature_test_cxx_constexpr "(__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && defined(__GXX_EXPERIMENTAL_CXX0X__)")
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index d35ead7..9fd0657 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -44,6 +44,7 @@
 #define FOR_EACH_CXX_FEATURE(F) \
   F(cxx_delegating_constructors) \
   F(cxx_variadic_templates) \
+  F(cxx_constexpr) \
   F(gnuxx_typeof) \
   F(msvcxx_sealed)
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9f8f986e87cdeff8d5694e0d7a6911c2033b8163
commit 9f8f986e87cdeff8d5694e0d7a6911c2033b8163
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Oct 22 01:51:34 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:45 2014 +0100

    Genex: Add $<HAVE_COMPILER_FEATURE:FEATURE> genex.
    
    Implement a consistency check similar to the existing check for
    target properties seen when evaluating the link implementation.
    A compile feature may not both determine and be determined by
    the link implementation.
    
    Record a set of features which are available by default for
    a compiler if not features are requested explicitly for a target.

diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index ac8c3f8..e5d5eaa 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -83,6 +83,8 @@ otherwise expands to nothing.
   else ``0``.  If the policy was not set, the warning message for the policy
   will be emitted. This generator expression only works for a subset of
   policies.
+``$<HAVE_COMPILE_FEATURE:feature>``
+  ``1`` if the relevant compiler supports ``feature``, otherwise ``0``.
 
 Informational Expressions
 =========================
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index 28bd1cf..62b7f76 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -6,6 +6,7 @@ set(CMAKE_CXX_COMPILE_FEATURES "@CMAKE_CXX_COMPILE_FEATURES@")
 set(CMAKE_CXX98_COMPILE_EXTENSIONS "@CMAKE_CXX98_COMPILE_EXTENSIONS@")
 set(CMAKE_CXX11_COMPILE_FEATURES "@CMAKE_CXX11_COMPILE_FEATURES@")
 set(CMAKE_CXX11_COMPILE_EXTENSIONS "@CMAKE_CXX11_COMPILE_EXTENSIONS@")
+set(CMAKE_CXX_DEFAULT_COMPILE_FEATURES "@CMAKE_CXX_DEFAULT_COMPILE_FEATURES@")
 
 set(CMAKE_CXX_PLATFORM_ID "@CMAKE_CXX_PLATFORM_ID@")
 set(CMAKE_CXX_SIMULATE_ID "@CMAKE_CXX_SIMULATE_ID@")
diff --git a/Modules/CMakeDetermineCompileFeatures.cmake b/Modules/CMakeDetermineCompileFeatures.cmake
index 7950144..f93e21e 100644
--- a/Modules/CMakeDetermineCompileFeatures.cmake
+++ b/Modules/CMakeDetermineCompileFeatures.cmake
@@ -46,6 +46,8 @@ function(cmake_determine_compile_features lang)
     set(CMAKE_CXX11_COMPILE_FEATURES ${CMAKE_CXX11_COMPILE_FEATURES} PARENT_SCOPE)
     set(CMAKE_CXX11_COMPILE_EXTENSIONS ${CMAKE_CXX11_COMPILE_EXTENSIONS} PARENT_SCOPE)
 
+    set(CMAKE_CXX_DEFAULT_COMPILE_FEATURES ${CMAKE_CXX_DEFAULT_COMPILE_FEATURES} PARENT_SCOPE)
+
     message(STATUS "Detecting ${lang} compile features - done")
   endif()
 
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index 1a6b485..966bae2 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -23,6 +23,11 @@ elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1)
   set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x")
 endif()
 
+set(CMAKE_CXX_DEFAULT_COMPILE_FEATURES
+  CMAKE_CXX98_COMPILE_FEATURES
+  CMAKE_CXX98_COMPILE_EXTENSIONS
+)
+
 macro(cmake_record_cxx_compile_features)
   macro(_get_clang_features std_version list)
     record_compiler_features(CXX "-std=${std_version}" ${list})
@@ -30,6 +35,7 @@ macro(cmake_record_cxx_compile_features)
 
   if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1)
     _get_clang_features(gnu++98 CMAKE_CXX98_COMPILE_EXTENSIONS)
+    _get_clang_features(c++98 CMAKE_CXX98_COMPILE_FEATURES)
   endif()
 
   if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.1)
diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake
index a15c14f..e2aa9f8 100644
--- a/Modules/Compiler/GNU-CXX.cmake
+++ b/Modules/Compiler/GNU-CXX.cmake
@@ -24,6 +24,11 @@ elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.3)
   set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x")
 endif()
 
+set(CMAKE_CXX_DEFAULT_COMPILE_FEATURES
+  CMAKE_CXX98_COMPILE_FEATURES
+  CMAKE_CXX98_COMPILE_EXTENSIONS
+)
+
 macro(cmake_record_cxx_compile_features)
   macro(_get_gcc_features std_version list)
     record_compiler_features(CXX "-std=${std_version}" ${list})
@@ -31,6 +36,7 @@ macro(cmake_record_cxx_compile_features)
 
   if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.3)
     _get_gcc_features(gnu++98 CMAKE_CXX98_COMPILE_EXTENSIONS)
+    _get_gcc_features(c++98 CMAKE_CXX98_COMPILE_FEATURES)
   endif()
 
   if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
diff --git a/Modules/Platform/Windows-MSVC-CXX.cmake b/Modules/Platform/Windows-MSVC-CXX.cmake
index 89885b8..a61b04a 100644
--- a/Modules/Platform/Windows-MSVC-CXX.cmake
+++ b/Modules/Platform/Windows-MSVC-CXX.cmake
@@ -5,6 +5,10 @@ if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0)
 endif()
 __windows_compiler_msvc(CXX)
 
+set(CMAKE_COMPILER_DEFAULT_FEATURES
+  CMAKE_CXX_COMPILE_FEATURES
+)
+
 macro(cmake_record_cxx_compile_features)
   record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES)
 endmacro()
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index e127f3a..10bd6b0 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -103,6 +103,12 @@ const char *cmCompiledGeneratorExpression::Evaluate(
       {
       this->SeenTargetProperties.insert(*p);
       }
+    for(std::set<std::string>::const_iterator
+          p = context.SeenCompileNonFeatures.begin();
+          p != context.SeenCompileNonFeatures.end(); ++p)
+      {
+      this->SeenCompileNonFeatures.insert(*p);
+      }
     if (context.HadError)
       {
       this->Output = "";
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index d0a6aef..d1eca25 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -93,6 +93,9 @@ public:
   std::set<std::string> const& GetSeenTargetProperties() const
     { return this->SeenTargetProperties; }
 
+  std::set<std::string> const& GetSeenCompileNonFeatures() const
+    { return this->SeenCompileNonFeatures; }
+
   std::set<cmTarget const*> const& GetAllTargetsSeen() const
     { return this->AllTargetsSeen; }
 
@@ -129,6 +132,7 @@ private:
   mutable std::set<cmTarget*> DependTargets;
   mutable std::set<cmTarget const*> AllTargetsSeen;
   mutable std::set<std::string> SeenTargetProperties;
+  mutable std::set<std::string> SeenCompileNonFeatures;
   mutable std::string Output;
   mutable bool HadContextSensitiveCondition;
 };
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 14b2a1a..d626445 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -677,6 +677,45 @@ static const struct LinkOnlyNode : public cmGeneratorExpressionNode
 } linkOnlyNode;
 
 //----------------------------------------------------------------------------
+static const struct HaveFeatureNode : public cmGeneratorExpressionNode
+{
+  HaveFeatureNode() {}
+
+  virtual int NumExpectedParameters() const { return 1; }
+
+  std::string Evaluate(const std::vector<std::string> &parameters,
+                       cmGeneratorExpressionContext *context,
+                       const GeneratorExpressionContent *content,
+                       cmGeneratorExpressionDAGChecker *) const
+  {
+    if (!context->HeadTarget)
+      {
+      reportError(context, content->GetOriginalExpression(),
+          "$<HAVE_COMPILER_FEATURE:feature> may only be used with "
+          "targets.  It may not be used with add_custom_command.");
+      return std::string();
+      }
+
+    bool error = false;
+    const bool result = context->Makefile->HaveFeature(context->HeadTarget,
+                                                  parameters.front(),
+                                                  error);
+    if (error)
+      {
+      reportError(context, content->GetOriginalExpression(),
+          "$<HAVE_COMPILER_FEATURE:feature> used with invalid feature.");
+      return std::string();
+      }
+    context->SeenTargetProperties.insert("COMPILE_FEATURES");
+    if (!result)
+      {
+      context->SeenCompileNonFeatures.insert(parameters.front());
+      }
+    return result ? "1" : "0";
+  }
+} haveFeatureNode;
+
+//----------------------------------------------------------------------------
 static const struct ConfigurationNode : public cmGeneratorExpressionNode
 {
   ConfigurationNode() {}
@@ -1599,6 +1638,7 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
     nodeMap["INSTALL_PREFIX"] = &installPrefixNode;
     nodeMap["JOIN"] = &joinNode;
     nodeMap["LINK_ONLY"] = &linkOnlyNode;
+    nodeMap["HAVE_COMPILER_FEATURE"] = &haveFeatureNode;
     }
   NodeMap::const_iterator i = nodeMap.find(identifier);
   if (i == nodeMap.end())
diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h
index a7099cb..120ebd5 100644
--- a/Source/cmGeneratorExpressionEvaluator.h
+++ b/Source/cmGeneratorExpressionEvaluator.h
@@ -26,6 +26,7 @@ struct cmGeneratorExpressionContext
   std::set<cmTarget*> DependTargets;
   std::set<cmTarget const*> AllTargets;
   std::set<std::string> SeenTargetProperties;
+  std::set<std::string> SeenCompileNonFeatures;
   cmMakefile *Makefile;
   std::string Config;
   cmTarget const* HeadTarget; // The target whose property is being evaluated.
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index b11b585..d35ead7 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -4642,3 +4642,87 @@ AddRequiredTargetFeature(cmTarget *target, const std::string& feature) const
     }
   return true;
 }
+
+bool cmMakefile::HaveFeature(cmTarget const* target,
+                             const std::string& feature,
+                             bool &error) const
+{
+  if (cmGeneratorExpression::Find(feature) != std::string::npos)
+    {
+    error = true;
+    return false;
+    }
+  bool isCxxFeature = std::find_if(cmArrayBegin(CXX_FEATURES) + 1,
+              cmArrayEnd(CXX_FEATURES), cmStrCmp(feature))
+              != cmArrayEnd(CXX_FEATURES);
+  if (!isCxxFeature)
+    {
+    error = true;
+    return false;
+    }
+
+  std::vector<std::string> featuresVec;
+  const char *features = 0;
+  const char *stdProp = target->GetProperty("CXX_STANDARD");
+  if(!stdProp)
+    {
+    const char *featureLists =
+                    this->GetDefinition("CMAKE_CXX_DEFAULT_COMPILE_FEATURES");
+    if (!featureLists)
+      {
+      return false;
+      }
+    std::vector<std::string> featuresLists;
+    cmSystemTools::ExpandListArgument(featureLists, featuresLists);
+
+    for(std::vector<std::string>::const_iterator vi = featuresLists.begin();
+        vi != featuresLists.end(); ++vi)
+      {
+      const char* def = this->GetDefinition(*vi);
+      if (!def)
+        {
+        return false;
+        }
+      cmSystemTools::ExpandListArgument(def, featuresVec);
+      }
+    }
+  else if (this->GetDefinition("CMAKE_CXX"
+          + std::string(stdProp) + "_COMPILE_FEATURES"))
+    {
+    const char* const* end = std::find_if(cmArrayBegin(CXX_STANDARDS),
+                                    cmArrayEnd(CXX_STANDARDS),
+                                    cmStrCmp(stdProp));
+    if (end == cmArrayEnd(CXX_STANDARDS))
+      {
+      error = true;
+      return false;
+      }
+    end++;
+    for (const char* const* it = cmArrayBegin(CXX_STANDARDS); it != end; ++it)
+      {
+      features = this->GetDefinition("CMAKE_CXX"
+          + std::string(*it) + "_COMPILE_FEATURES");
+      if (features)
+        {
+        cmSystemTools::ExpandListArgument(features, featuresVec);
+        }
+      if (target->GetPropertyAsBool("CXX_EXTENSIONS"))
+        {
+        features = this->GetDefinition("CMAKE_CXX"
+            + std::string(*it) + "_COMPILE_EXTENSIONS");
+        if (features)
+          {
+          cmSystemTools::ExpandListArgument(features, featuresVec);
+          }
+        }
+      }
+    }
+  else if (this->GetDefinition("CMAKE_CXX_COMPILE_FEATURES"))
+    {
+    features = this->GetDefinition("CMAKE_CXX_COMPILE_FEATURES");
+    cmSystemTools::ExpandListArgument(features, featuresVec);
+    }
+  return std::find(featuresVec.begin(),
+                   featuresVec.end(),
+                   feature) != featuresVec.end();
+}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 7350bc8..6e9018d 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -882,6 +882,9 @@ public:
 
   bool AddRequiredTargetFeature(cmTarget *target,
                                 const std::string& feature) const;
+  bool HaveFeature(cmTarget const* target,
+                   const std::string& feature,
+                   bool &error) const;
 
 protected:
   // add link libraries and directories to the target
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 8989e57..51aed5b 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -793,6 +793,13 @@ void cmTarget::GetDirectLinkLibraries(const std::string& config,
         this->LinkImplicitNullProperties.insert(*it);
         }
       }
+
+    std::set<std::string> seenFeatures = cge->GetSeenCompileNonFeatures();
+    for (std::set<std::string>::const_iterator it = seenFeatures.begin();
+        it != seenFeatures.end(); ++it)
+      {
+      this->LinkImplicitDisabledFeatures.insert(*it);
+      }
     }
 }
 
@@ -2342,6 +2349,21 @@ void cmTarget::GetCompileFeatures(std::vector<std::string> &result,
   else
     {
     this->Internal->CacheLinkInterfaceCompileFeaturesDone[config] = true;
+    for(std::vector<std::string>::const_iterator it = result.begin();
+        it != result.end(); ++it)
+      {
+      if (this->LinkImplicitDisabledFeatures.find(*it)
+          != this->LinkImplicitDisabledFeatures.end())
+        {
+        cmOStringStream e;
+        e << "Target \"" << this->Name << "\" link implementation was "
+          "evaluated with the feature \"" << *it << "\" disabled, but it is "
+          "enabled by the link implementation.  This is not consistent and "
+          "is not allowed.";
+        this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+        return;
+        }
+      }
     }
 }
 
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 8e6518e..b0f968e 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -712,6 +712,7 @@ private:
   mutable bool DebugCompileDefinitionsDone;
   mutable bool DebugCompileFeaturesDone;
   mutable std::set<std::string> LinkImplicitNullProperties;
+  mutable std::set<std::string> LinkImplicitDisabledFeatures;
   bool BuildInterfaceIncludesAppended;
 
   // Cache target output paths for each configuration.
diff --git a/Tests/CMakeCommands/target_compile_features/CMakeLists.txt b/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
index 3a42088..ab79b29 100644
--- a/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
@@ -31,3 +31,5 @@ target_compile_features(lib_delegating_constructors
 
 add_executable(lib_user lib_user.cpp)
 target_link_libraries(lib_user lib_delegating_constructors)
+
+add_subdirectory(feature_conditional_link)
diff --git a/Tests/CMakeCommands/target_compile_features/feature_conditional_link/CMakeLists.txt b/Tests/CMakeCommands/target_compile_features/feature_conditional_link/CMakeLists.txt
new file mode 100644
index 0000000..6dc7608
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/feature_conditional_link/CMakeLists.txt
@@ -0,0 +1,26 @@
+
+add_library(no_variadics INTERFACE)
+target_include_directories(no_variadics INTERFACE no_variadics)
+add_library(have_variadics INTERFACE)
+target_include_directories(have_variadics INTERFACE have_variadics)
+
+add_library(maybe_variadics INTERFACE)
+target_link_libraries(maybe_variadics INTERFACE
+  $<$<HAVE_COMPILER_FEATURE:cxx_variadic_templates>:have_variadics>
+  $<$<NOT:$<HAVE_COMPILER_FEATURE:cxx_variadic_templates>>:no_variadics>
+)
+
+# Upstream publishes maybe_variadics, we use it below.
+
+add_executable(template_user_with_variadics template_user.cpp)
+target_compile_features(template_user_with_variadics PRIVATE cxx_variadic_templates)
+
+target_link_libraries(template_user_with_variadics
+  maybe_variadics
+)
+
+add_executable(template_user_no_variadics template_user.cpp)
+
+target_link_libraries(template_user_no_variadics
+  maybe_variadics
+)
diff --git a/Tests/CMakeCommands/target_compile_features/feature_conditional_link/have_variadics/interface.h b/Tests/CMakeCommands/target_compile_features/feature_conditional_link/have_variadics/interface.h
new file mode 100644
index 0000000..a4f87c0
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/feature_conditional_link/have_variadics/interface.h
@@ -0,0 +1,20 @@
+template<int I, int... Is>
+struct Interface;
+
+template<int I>
+struct Interface<I>
+{
+  static int accumulate()
+  {
+    return I;
+  }
+};
+
+template<int I, int... Is>
+struct Interface
+{
+  static int accumulate()
+  {
+    return I + Interface<Is...>::accumulate();
+  }
+};
diff --git a/Tests/CMakeCommands/target_compile_features/feature_conditional_link/no_variadics/interface.h b/Tests/CMakeCommands/target_compile_features/feature_conditional_link/no_variadics/interface.h
new file mode 100644
index 0000000..5c5263a
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/feature_conditional_link/no_variadics/interface.h
@@ -0,0 +1,6 @@
+
+template<int I1, int I2 = 0, int I3 = 0, int I4 = 0>
+struct Interface
+{
+  static int accumulate() { return I1 + I2 + I3 + I4; }
+};
diff --git a/Tests/CMakeCommands/target_compile_features/feature_conditional_link/template_user.cpp b/Tests/CMakeCommands/target_compile_features/feature_conditional_link/template_user.cpp
new file mode 100644
index 0000000..f15362c
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/feature_conditional_link/template_user.cpp
@@ -0,0 +1,8 @@
+
+#include <interface.h>
+
+int main(int argc, char **argv)
+{
+  int result = Interface<1, 2, 3, 4>::accumulate();
+  return result == 10 ? 0 : 1;
+}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 3fdfeda..54d837e 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -50,6 +50,9 @@ add_RunCMake_test(TargetPropertyGeneratorExpressions)
 add_RunCMake_test(Languages)
 add_RunCMake_test(ObjectLibrary)
 add_RunCMake_test(find_dependency)
+if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
+  add_RunCMake_test(have_feature)
+endif()
 if(NOT WIN32)
   add_RunCMake_test(PositionIndependentCode)
   set(SKIP_VISIBILITY 0)
diff --git a/Tests/RunCMake/have_feature/CMakeLists.txt b/Tests/RunCMake/have_feature/CMakeLists.txt
new file mode 100644
index 0000000..be9d403
--- /dev/null
+++ b/Tests/RunCMake/have_feature/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST})
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/have_feature/RunCMakeTest.cmake b/Tests/RunCMake/have_feature/RunCMakeTest.cmake
new file mode 100644
index 0000000..ec844f4
--- /dev/null
+++ b/Tests/RunCMake/have_feature/RunCMakeTest.cmake
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake(inconsistent)
diff --git a/Tests/RunCMake/have_feature/empty.cpp b/Tests/RunCMake/have_feature/empty.cpp
new file mode 100644
index 0000000..bfbbdde
--- /dev/null
+++ b/Tests/RunCMake/have_feature/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/have_feature/inconsistent-result.txt b/Tests/RunCMake/have_feature/inconsistent-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/have_feature/inconsistent-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/have_feature/inconsistent-stderr.txt b/Tests/RunCMake/have_feature/inconsistent-stderr.txt
new file mode 100644
index 0000000..45ecd5d
--- /dev/null
+++ b/Tests/RunCMake/have_feature/inconsistent-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error in CMakeLists.txt:
+  Target "my_exe" link implementation was evaluated with the feature
+  "msvcxx_sealed" disabled, but it is enabled by the link implementation.
+  This is not consistent and is not allowed.
diff --git a/Tests/RunCMake/have_feature/inconsistent.cmake b/Tests/RunCMake/have_feature/inconsistent.cmake
new file mode 100644
index 0000000..f24531f
--- /dev/null
+++ b/Tests/RunCMake/have_feature/inconsistent.cmake
@@ -0,0 +1,8 @@
+
+add_library(iface INTERFACE)
+
+add_library(iface2 INTERFACE)
+target_compile_features(iface2 INTERFACE msvcxx_sealed)
+
+add_executable(my_exe empty.cpp)
+target_link_libraries(my_exe $<$<HAVE_COMPILER_FEATURE:msvcxx_sealed>:iface> iface2)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=91af9ad4ca8dfbe9fb34c3eb5393e7f360e7d49c
commit 91af9ad4ca8dfbe9fb34c3eb5393e7f360e7d49c
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Oct 22 15:19:52 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:45 2014 +0100

    Add a cxx_variadic_templates feature.

diff --git a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
index ba6f027..f8921ca 100644
--- a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
+++ b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
@@ -14,6 +14,11 @@ The features known to this version of CMake are:
 
 .. _N1986: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf
 
+``cxx_variadic_templates``
+  Variadic templates, as defined in N2242_.
+
+.. _N2242: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf
+
 ``gnuxx_typeof``
   The GNU typeof extension.
 
diff --git a/Modules/Compiler/Clang-CXX-FeatureTests.cmake b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
index f1eb031..0b2ceca 100644
--- a/Modules/Compiler/Clang-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
@@ -1,6 +1,7 @@
 
 set(testable_features
   cxx_delegating_constructors
+  cxx_variadic_templates
 )
 foreach(feature ${testable_features})
   set(_cmake_feature_test_${feature} "__has_extension(${feature})")
diff --git a/Modules/Compiler/GNU-CXX-FeatureTests.cmake b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
index 242f19b..393c126 100644
--- a/Modules/Compiler/GNU-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
@@ -1,4 +1,13 @@
 
 set(_cmake_feature_test_gnuxx_typeof "!defined(__STRICT_ANSI__)")
 
+# For GCC 4.7, we can test the standard __cplusplus macro, ...
+# set(isCxx98Mode "__cplusplus >= 199711L")
+# set(isCxx11Mode "__cplusplus >= 201103L")
+# ... but before GCC 4.7, __cplusplus is always defined to 1, so check
+# the old macro.
+# set(isCxx98Mode "!defined(__GXX_EXPERIMENTAL_CXX0X__)")
+# set(isCxx11Mode "defined(__GXX_EXPERIMENTAL_CXX0X__)")
+
 set(_cmake_feature_test_cxx_delegating_constructors "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L")
+set(_cmake_feature_test_cxx_variadic_templates "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && defined(__GXX_EXPERIMENTAL_CXX0X__)")
diff --git a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
index 8983826..ff8084f 100644
--- a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
@@ -1,4 +1,5 @@
 
 set(_cmake_feature_test_cxx_delegating_constructors "_MSC_VER >= 1800")
+set(_cmake_feature_test_cxx_variadic_templates "_MSC_VER >= 1800")
 
 set(_cmake_feature_test_msvcxx_sealed "_MSC_VER >= 1400")
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 091eb4c..b11b585 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -43,6 +43,7 @@
 
 #define FOR_EACH_CXX_FEATURE(F) \
   F(cxx_delegating_constructors) \
+  F(cxx_variadic_templates) \
   F(gnuxx_typeof) \
   F(msvcxx_sealed)
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=973087d34bca375835c675afe5be82c9d79daa54
commit 973087d34bca375835c675afe5be82c9d79daa54
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Oct 30 21:13:44 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:45 2014 +0100

    Base the target_compile_features command on cmTargetPropCommandBase.
    
    This gives us 'free' handling of IMPORTED, ALIAS, INTERFACE,
    non-compilable and missing targets.

diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx
index b285876..2d10e41 100644
--- a/Source/cmTargetCompileFeaturesCommand.cxx
+++ b/Source/cmTargetCompileFeaturesCommand.cxx
@@ -15,49 +15,56 @@ bool cmTargetCompileFeaturesCommand::InitialPass(
   std::vector<std::string> const& args,
   cmExecutionStatus &)
 {
-  if (args.size() < 3)
-    {
-      this->SetError("called with wrong number of arguments.");
-      return false;
-    }
-  cmTarget *target = this->Makefile->FindTargetToUse(args[0]);
+  return this->HandleArguments(args, "COMPILE_FEATURES", NO_FLAGS);
+}
 
-  if(!target)
-    {
-    this->SetError("specified invalid target.");
-    return false;
-    }
+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());
+}
 
-  if(target->IsImported())
-    {
-    this->SetError("may not be used with an IMPORTED target.");
-    return false;
-    }
+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());
+}
 
-  const bool interfaceOnly = args[1] == "INTERFACE";
-  if(args[1] != "PRIVATE" && args[1] != "PUBLIC" && !interfaceOnly)
+//----------------------------------------------------------------------------
+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)
     {
-    this->SetError("called with invalid arguments.");
-    return false;
+    defs += sep + *it;
+    sep = ";";
     }
+  return defs;
+}
 
-  for (size_t i = 2; i < args.size(); ++i)
+//----------------------------------------------------------------------------
+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 feature = args[i];
-
-    if (!interfaceOnly)
-      {
-      if (!this->Makefile->AddRequiredTargetFeature(target, feature))
-        {
-        cmOStringStream e;
-        e << "specified unknown feature \"" << feature << "\".";
-        this->SetError(e.str());
-        return false;
-        }
-      }
-    if (interfaceOnly || args[1] == "PUBLIC")
+    if(!this->Makefile->AddRequiredTargetFeature(tgt, *it))
       {
-      target->AppendProperty("INTERFACE_COMPILE_FEATURES", feature);
+      cmOStringStream e;
+      e << "specified unknown feature \"" << *it << "\".";
+      this->SetError(e.str());
+      return false;
       }
     }
   return true;
diff --git a/Source/cmTargetCompileFeaturesCommand.h b/Source/cmTargetCompileFeaturesCommand.h
index 4e8b146..fa7ae8d 100644
--- a/Source/cmTargetCompileFeaturesCommand.h
+++ b/Source/cmTargetCompileFeaturesCommand.h
@@ -12,9 +12,9 @@
 #ifndef cmTargetCompileFeaturesCommand_h
 #define cmTargetCompileFeaturesCommand_h
 
-#include "cmCommand.h"
+#include "cmTargetPropCommandBase.h"
 
-class cmTargetCompileFeaturesCommand : public cmCommand
+class cmTargetCompileFeaturesCommand : public cmTargetPropCommandBase
 {
   virtual cmCommand* Clone()
     {
@@ -26,7 +26,16 @@ class cmTargetCompileFeaturesCommand : public cmCommand
 
   virtual std::string GetName() const { return "target_compile_features";}
 
-  cmTypeMacro(cmTargetCompileFeaturesCommand, cmCommand);
+  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/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake b/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake
index fd7019c..740a973 100644
--- a/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake
@@ -1,5 +1,12 @@
 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)
 if (NOT NO_UNKNOWN_COMPILER_TEST)
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..3321e3f
--- /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:4 \(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/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..95431b4
--- /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:4 \(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..1242730
--- /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:4 \(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..d7f48b1
--- /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:4 \(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_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..9cd5e6b
--- /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:4 \(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_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..0f27a9c
--- /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:4 \(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..96b0bd7
--- /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:4 \(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)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=76164d8beacea4171be5f0dc8375df9191e1eb7a
commit 76164d8beacea4171be5f0dc8375df9191e1eb7a
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Sat Nov 9 00:18:35 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:45 2014 +0100

    cmTargetPropCommandBase: Change the interface to return bool.
    
    This is needed for the target_compile_features command, which
    may fail at configure time if an invalid feature is specified.

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/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);
 };

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6e6cd7441ac884c2a015d21e82d85bd110e5bc70
commit 6e6cd7441ac884c2a015d21e82d85bd110e5bc70
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Oct 22 01:40:47 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:45 2014 +0100

    cmTarget: Transitively evaluate compiler features.
    
    Extend the interface of the target_compile_features command with
    PUBLIC and INTERFACE keywords. Populate the INTERFACE_COMPILER_FEATURES
    target property if they are set. Consume the INTERFACE_COMPILER_FEATURES
    target property from linked dependent targets to determine the final
    required compiler features and the compile flag, if needed.

diff --git a/Help/command/target_compile_features.rst b/Help/command/target_compile_features.rst
index 9901b8d..f8e5c54 100644
--- a/Help/command/target_compile_features.rst
+++ b/Help/command/target_compile_features.rst
@@ -5,7 +5,7 @@ Add expected compiler features to a target.
 
 ::
 
-  target_compile_features(<target> PRIVATE <feature> [...])
+  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,
@@ -13,6 +13,13 @@ 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.
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 922dab8..a6f1ed0 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -151,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/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/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst b/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst
index 11aed0c..3ec45a4 100644
--- a/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst
+++ b/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst
@@ -6,7 +6,8 @@ Enables tracing output for target properties.
 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:`COMPILE_DEFINITIONS`, :prop_tgt:`COMPILE_OPTIONS`,
+:prop_tgt:`AUTOUIC_OPTIONS`, :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/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index 6cbbd2a..f4155b3 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -25,7 +25,8 @@
   SELECT(F, EvaluatingSystemIncludeDirectories, SYSTEM_INCLUDE_DIRECTORIES) \
   SELECT(F, EvaluatingCompileDefinitions,       COMPILE_DEFINITIONS) \
   SELECT(F, EvaluatingCompileOptions,           COMPILE_OPTIONS) \
-  SELECT(F, EvaluatingAutoUicOptions,           AUTOUIC_OPTIONS)
+  SELECT(F, EvaluatingAutoUicOptions,           AUTOUIC_OPTIONS) \
+  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 2958e9e..c9148e9 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1461,6 +1461,13 @@ 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)
+    {
+    this->Makefile->AddRequiredTargetFeature(target, *it);
+    }
   this->AddCompilerRequirementFlag(flags, target, lang);
 }
 
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index a1cbe99..8989e57 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -159,10 +159,13 @@ public:
                                 CachedLinkInterfaceCompileOptionsEntries;
   mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
                                 CachedLinkInterfaceCompileDefinitionsEntries;
+  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> CacheLinkInterfaceCompileFeaturesDone;
 };
 
 //----------------------------------------------------------------------------
@@ -197,6 +200,7 @@ cmTargetInternals::~cmTargetInternals()
 {
   deleteAndClear(this->CachedLinkInterfaceIncludeDirectoriesEntries);
   deleteAndClear(this->CachedLinkInterfaceCompileOptionsEntries);
+  deleteAndClear(this->CachedLinkInterfaceCompileFeaturesEntries);
   deleteAndClear(this->CachedLinkInterfaceCompileDefinitionsEntries);
 }
 
@@ -219,6 +223,7 @@ cmTarget::cmTarget()
   this->BuildInterfaceIncludesAppended = false;
   this->DebugIncludesDone = false;
   this->DebugCompileOptionsDone = false;
+  this->DebugCompileFeaturesDone = false;
   this->DebugCompileDefinitionsDone = false;
 }
 
@@ -2229,6 +2234,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.
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 3ef853b..8e6518e 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -544,6 +544,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> &result,
+                          const std::string& config) const;
 
   bool IsNullImpliedByLinkLibraries(const std::string &p) const;
   bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
@@ -708,6 +710,7 @@ private:
   mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
   mutable bool DebugCompileOptionsDone;
   mutable bool DebugCompileDefinitionsDone;
+  mutable bool DebugCompileFeaturesDone;
   mutable std::set<std::string> LinkImplicitNullProperties;
   bool BuildInterfaceIncludesAppended;
 
diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx
index 904db81..b285876 100644
--- a/Source/cmTargetCompileFeaturesCommand.cxx
+++ b/Source/cmTargetCompileFeaturesCommand.cxx
@@ -34,7 +34,8 @@ bool cmTargetCompileFeaturesCommand::InitialPass(
     return false;
     }
 
-  if(args[1] != "PRIVATE")
+  const bool interfaceOnly = args[1] == "INTERFACE";
+  if(args[1] != "PRIVATE" && args[1] != "PUBLIC" && !interfaceOnly)
     {
     this->SetError("called with invalid arguments.");
     return false;
@@ -44,12 +45,19 @@ bool cmTargetCompileFeaturesCommand::InitialPass(
     {
     std::string feature = args[i];
 
-    if (!this->Makefile->AddRequiredTargetFeature(target, feature))
+    if (!interfaceOnly)
       {
-      cmOStringStream e;
-      e << "specified unknown feature \"" << feature << "\".";
-      this->SetError(e.str());
-      return false;
+      if (!this->Makefile->AddRequiredTargetFeature(target, feature))
+        {
+        cmOStringStream e;
+        e << "specified unknown feature \"" << feature << "\".";
+        this->SetError(e.str());
+        return false;
+        }
+      }
+    if (interfaceOnly || args[1] == "PUBLIC")
+      {
+      target->AppendProperty("INTERFACE_COMPILE_FEATURES", feature);
       }
     }
   return true;
diff --git a/Tests/CMakeCommands/target_compile_features/CMakeLists.txt b/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
index 947996e..3a42088 100644
--- a/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
@@ -23,3 +23,11 @@ add_executable(target_compile_features main.cpp)
 target_compile_features(target_compile_features
   PRIVATE cxx_delegating_constructors
 )
+
+add_library(lib_delegating_constructors lib_delegating_constructors.cpp)
+target_compile_features(lib_delegating_constructors
+  PUBLIC cxx_delegating_constructors
+)
+
+add_executable(lib_user lib_user.cpp)
+target_link_libraries(lib_user lib_delegating_constructors)
diff --git a/Tests/CMakeCommands/target_compile_features/lib_delegating_constructors.cpp b/Tests/CMakeCommands/target_compile_features/lib_delegating_constructors.cpp
new file mode 100644
index 0000000..e597acd
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/lib_delegating_constructors.cpp
@@ -0,0 +1,8 @@
+
+#include "lib_delegating_constructors.h"
+
+Foo::Foo(int i)
+  : m_i(i)
+{
+
+}
diff --git a/Tests/CMakeCommands/target_compile_features/lib_delegating_constructors.h b/Tests/CMakeCommands/target_compile_features/lib_delegating_constructors.h
new file mode 100644
index 0000000..75be701
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/lib_delegating_constructors.h
@@ -0,0 +1,17 @@
+
+#include <cstring>
+
+class Foo
+{
+public:
+  Foo(int i);
+
+  Foo(const char *a)
+    : Foo(strlen(a))
+  {
+
+  }
+
+private:
+  int m_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..83ad51e
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/lib_user.cpp
@@ -0,0 +1,27 @@
+
+#include "lib_delegating_constructors.h"
+
+class Bar
+{
+  Bar(int i)
+    :m_i(i)
+  {
+
+  }
+
+  Bar(const char *a)
+    : Bar(strlen(a))
+  {
+
+  }
+
+private:
+  int m_i;
+};
+
+int main(int argc, char **argv)
+{
+  Foo f("hello");
+  Foo b("world");
+  return 0;
+}

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bb43b3c2262edce04698939431e5ba6925624116
commit bb43b3c2262edce04698939431e5ba6925624116
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Oct 22 15:05:49 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:45 2014 +0100

    cmTarget: Allow populating COMPILE_FEATURES using generator expressions.

diff --git a/Help/command/target_compile_features.rst b/Help/command/target_compile_features.rst
index 4b09fdb..9901b8d 100644
--- a/Help/command/target_compile_features.rst
+++ b/Help/command/target_compile_features.rst
@@ -16,3 +16,8 @@ automatically.
 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/prop_tgt/COMPILE_FEATURES.rst b/Help/prop_tgt/COMPILE_FEATURES.rst
index b2c6145..dc32825 100644
--- a/Help/prop_tgt/COMPILE_FEATURES.rst
+++ b/Help/prop_tgt/COMPILE_FEATURES.rst
@@ -5,3 +5,7 @@ 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/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 94249f8..091eb4c 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -4512,6 +4512,11 @@ static const char * const CXX_STANDARDS[] = {
 bool cmMakefile::
 AddRequiredTargetFeature(cmTarget *target, const std::string& feature) 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);

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=459ae487afdf68dd47ed44b7587c202dabbc6cdb
commit 459ae487afdf68dd47ed44b7587c202dabbc6cdb
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Oct 22 14:58:21 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:45 2014 +0100

    cmTarget: Make COMPILE_FEATURES available as a target property.

diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index d0a5a77..922dab8 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
diff --git a/Help/prop_tgt/COMPILE_FEATURES.rst b/Help/prop_tgt/COMPILE_FEATURES.rst
new file mode 100644
index 0000000..b2c6145
--- /dev/null
+++ b/Help/prop_tgt/COMPILE_FEATURES.rst
@@ -0,0 +1,7 @@
+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.
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 046405f..94249f8 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -4544,6 +4544,8 @@ AddRequiredTargetFeature(cmTarget *target, const std::string& feature) const
     return false;
     }
 
+  target->AppendProperty("COMPILE_FEATURES", feature.c_str());
+
   bool needCxx98 = true;
   bool needCxx11 = false;
   bool needCxxExt = false;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index c027503..a1cbe99 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -149,6 +149,7 @@ public:
   };
   std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
   std::vector<TargetPropertyEntry*> CompileOptionsEntries;
+  std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
   std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
   std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries;
 
@@ -1373,6 +1374,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;
@@ -1443,6 +1455,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;
@@ -2723,6 +2744,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;
@@ -6395,6 +6434,7 @@ cmTargetInternalPointer::~cmTargetInternalPointer()
 {
   deleteAndClear(this->Pointer->IncludeDirectoriesEntries);
   deleteAndClear(this->Pointer->CompileOptionsEntries);
+  deleteAndClear(this->Pointer->CompileFeaturesEntries);
   deleteAndClear(this->Pointer->CompileDefinitionsEntries);
   delete this->Pointer;
 }

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=129caf8f9de717d6ccc95516057e67141bb4e362
commit 129caf8f9de717d6ccc95516057e67141bb4e362
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Sun Oct 13 14:25:08 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:45 2014 +0100

    Add target_compile_features command.
    
    This can be used to set the compiler features required by particular
    targets. An error is issued at CMake time if the compiler does not
    support the required feature. If a language dialect flag is required
    by the features used, that will be added automatically.

diff --git a/Help/command/target_compile_features.rst b/Help/command/target_compile_features.rst
new file mode 100644
index 0000000..4b09fdb
--- /dev/null
+++ b/Help/command/target_compile_features.rst
@@ -0,0 +1,18 @@
+target_compile_features
+-----------------------
+
+Add expected compiler features to a target.
+
+::
+
+  target_compile_features(<target> PRIVATE <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 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.
diff --git a/Help/manual/cmake-commands.7.rst b/Help/manual/cmake-commands.7.rst
index fb0d2b5..1294873 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/variable/CMAKE_CXX_COMPILE_FEATURES.rst b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
index 6be0124..386f5c0 100644
--- a/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
+++ b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
@@ -6,3 +6,6 @@ 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.
+
+The features listed here may be used with the :command:`target_compile_features`
+command.
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 762470f..1aeb804 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -328,6 +328,7 @@ foreach(command_file
     cmSourceGroupCommand
     cmSubdirDependsCommand
     cmTargetCompileDefinitionsCommand
+    cmTargetCompileFeaturesCommand
     cmTargetCompileOptionsCommand
     cmTargetIncludeDirectoriesCommand
     cmUseMangledMesaCommand
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index eaf6cae..046405f 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -4495,3 +4495,142 @@ 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) const
+{
+  bool isCxxFeature = std::find_if(cmArrayBegin(CXX_FEATURES) + 1,
+              cmArrayEnd(CXX_FEATURES), cmStrCmp(feature))
+              != cmArrayEnd(CXX_FEATURES);
+  if (!isCxxFeature)
+    {
+    return false;
+    }
+
+  const char* cxxFeaturesKnown =
+    this->GetDefinition("CMAKE_CXX_COMPILE_FEATURES");
+
+  if (!cxxFeaturesKnown || !*cxxFeaturesKnown)
+    {
+    // We know of no features for the compiler at all.
+    return true;
+    }
+
+  std::vector<std::string> availableFeatures;
+  cmSystemTools::ExpandListArgument(cxxFeaturesKnown, 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_CXX_COMPILER_ID") << "\"\nversion "
+      << this->GetDefinition("CMAKE_CXX_COMPILER_VERSION") << ".";
+    this->IssueMessage(cmake::FATAL_ERROR, e.str());
+    return false;
+    }
+
+  bool needCxx98 = true;
+  bool needCxx11 = false;
+  bool needCxxExt = false;
+
+  if (const char *propCxx98 =
+                        this->GetDefinition("CMAKE_CXX98_COMPILE_FEATURES"))
+    {
+    std::vector<std::string> props;
+    cmSystemTools::ExpandListArgument(propCxx98, props);
+    needCxx98 = std::find(props.begin(), props.end(), feature) != props.end();
+    }
+  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();
+    }
+
+  if (const char *propCxx98ext =
+          this->GetDefinition("CMAKE_CXX98_COMPILE_EXTENSIONS"))
+    {
+    std::vector<std::string> props;
+    cmSystemTools::ExpandListArgument(propCxx98ext, props);
+    needCxxExt = std::find(props.begin(), props.end(), feature) != props.end();
+    needCxx98 = needCxx98 || needCxxExt;
+    }
+  if (const char *propCxx11ext =
+          this->GetDefinition("CMAKE_CXX11_COMPILE_EXTENSIONS"))
+    {
+    std::vector<std::string> props;
+    cmSystemTools::ExpandListArgument(propCxx11ext, props);
+    bool needCxx11Ext = std::find(props.begin(), props.end(), feature)
+                      != props.end();
+    needCxx11 = needCxx11 || needCxx11Ext;
+    needCxxExt = needCxxExt || needCxx11Ext;
+    }
+
+  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;
+  bool setCxx98 = needCxx98 && !existingCxxStandard;
+
+  if (needCxx11 && existingCxxStandard && existingCxxIt <
+                                    std::find_if(cmArrayBegin(CXX_STANDARDS),
+                                      cmArrayEnd(CXX_STANDARDS),
+                                      cmStrCmp("11")))
+    {
+    setCxx11 = true;
+    }
+  else if(needCxx98 && existingCxxStandard && existingCxxIt <
+                                    std::find_if(cmArrayBegin(CXX_STANDARDS),
+                                      cmArrayEnd(CXX_STANDARDS),
+                                      cmStrCmp("98")))
+    {
+    setCxx98 = true;
+    }
+
+  if (setCxx11)
+    {
+    target->SetProperty("CXX_STANDARD", "11");
+    }
+  else if (setCxx98)
+    {
+    target->SetProperty("CXX_STANDARD", "98");
+    }
+  bool existingCxxExt = target->GetPropertyAsBool("CXX_EXTENSIONS");
+  if (needCxxExt && !existingCxxExt)
+    {
+    target->SetProperty("CXX_EXTENSIONS", "1");
+    }
+  return true;
+}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 460a85c..7350bc8 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -880,6 +880,9 @@ public:
   std::set<std::string> const & GetSystemIncludeDirectories() const
     { return this->SystemIncludeDirectories; }
 
+  bool AddRequiredTargetFeature(cmTarget *target,
+                                const std::string& feature) const;
+
 protected:
   // add link libraries and directories to the target
   void AddGlobalLinkInformation(const std::string& name, cmTarget& target);
diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx
new file mode 100644
index 0000000..904db81
--- /dev/null
+++ b/Source/cmTargetCompileFeaturesCommand.cxx
@@ -0,0 +1,56 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2013 Stephen Kelly <steveire at 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 &)
+{
+  if (args.size() < 3)
+    {
+      this->SetError("called with wrong number of arguments.");
+      return false;
+    }
+  cmTarget *target = this->Makefile->FindTargetToUse(args[0]);
+
+  if(!target)
+    {
+    this->SetError("specified invalid target.");
+    return false;
+    }
+
+  if(target->IsImported())
+    {
+    this->SetError("may not be used with an IMPORTED target.");
+    return false;
+    }
+
+  if(args[1] != "PRIVATE")
+    {
+    this->SetError("called with invalid arguments.");
+    return false;
+    }
+
+  for (size_t i = 2; i < args.size(); ++i)
+    {
+    std::string feature = args[i];
+
+    if (!this->Makefile->AddRequiredTargetFeature(target, feature))
+      {
+      cmOStringStream e;
+      e << "specified unknown feature \"" << feature << "\".";
+      this->SetError(e.str());
+      return false;
+      }
+    }
+  return true;
+}
diff --git a/Source/cmTargetCompileFeaturesCommand.h b/Source/cmTargetCompileFeaturesCommand.h
new file mode 100644
index 0000000..4e8b146
--- /dev/null
+++ b/Source/cmTargetCompileFeaturesCommand.h
@@ -0,0 +1,32 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2013 Stephen Kelly <steveire at 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 "cmCommand.h"
+
+class cmTargetCompileFeaturesCommand : public cmCommand
+{
+  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, cmCommand);
+};
+
+#endif
diff --git a/Tests/CMakeCommands/target_compile_features/CMakeLists.txt b/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
new file mode 100644
index 0000000..947996e
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
@@ -0,0 +1,25 @@
+cmake_minimum_required(VERSION 2.8.12)
+cmake_policy(SET CMP0025 NEW)
+project(target_compile_features)
+
+set(CMAKE_VERBOSE_MAKEFILE ON)
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL GNU
+    OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
+  add_executable(gnuxx_typeof_test gnuxx_typeof_test.cpp)
+  target_compile_features(gnuxx_typeof_test PRIVATE gnuxx_typeof)
+endif()
+if (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
+  add_executable(msvcxx_sealed_test msvcxx_sealed_test.cpp)
+  target_compile_features(msvcxx_sealed_test PRIVATE msvcxx_sealed)
+endif()
+
+if (NOT ";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";cxx_delegating_constructors;")
+  add_executable(target_compile_features dummy.cpp)
+  return()
+endif()
+
+add_executable(target_compile_features main.cpp)
+target_compile_features(target_compile_features
+  PRIVATE cxx_delegating_constructors
+)
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/gnuxx_typeof_test.cpp b/Tests/CMakeCommands/target_compile_features/gnuxx_typeof_test.cpp
new file mode 100644
index 0000000..3b8532e
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/gnuxx_typeof_test.cpp
@@ -0,0 +1,6 @@
+
+int main(int argc, char **argv)
+{
+  typeof(argc) ret = 0;
+  return ret;
+}
diff --git a/Tests/CMakeCommands/target_compile_features/main.cpp b/Tests/CMakeCommands/target_compile_features/main.cpp
new file mode 100644
index 0000000..77671b0
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/main.cpp
@@ -0,0 +1,25 @@
+
+#include <cstring>
+
+class Foo
+{
+  Foo(int i)
+    :m_i(i)
+  {
+
+  }
+
+  Foo(const char *a)
+    : Foo(strlen(a))
+  {
+
+  }
+
+private:
+  int m_i;
+};
+
+int main(int, char **)
+{
+  return 0;
+}
diff --git a/Tests/CMakeCommands/target_compile_features/msvcxx_sealed_test.cpp b/Tests/CMakeCommands/target_compile_features/msvcxx_sealed_test.cpp
new file mode 100644
index 0000000..0127937
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/msvcxx_sealed_test.cpp
@@ -0,0 +1,8 @@
+
+class A sealed {};
+
+int main(int argc, char **argv)
+{
+  A a;
+  return 0;
+}
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 9ad2281..b39b728 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -2222,6 +2222,12 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
   ADD_TEST_MACRO(CMakeCommands.target_compile_definitions target_compile_definitions)
   ADD_TEST_MACRO(CMakeCommands.target_compile_options target_compile_options)
 
+  if ((CMAKE_CXX_COMPILER_ID STREQUAL GNU AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.3)
+      OR CMAKE_CXX_COMPILER_ID STREQUAL Clang
+      OR (x${CMAKE_CXX_COMPILER_ID} STREQUAL xMSVC AND NOT MSVC_VERSION VERSION_LESS 1400))
+    ADD_TEST_MACRO(CMakeCommands.target_compile_features target_compile_features)
+  endif()
+
   configure_file(
     "${CMake_SOURCE_DIR}/Tests/CTestTestCrash/test.cmake.in"
     "${CMake_BINARY_DIR}/Tests/CTestTestCrash/test.cmake"
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 7691f32..3fdfeda 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -121,6 +121,13 @@ endif()
 add_RunCMake_test(File_Generate)
 add_RunCMake_test(ExportWithoutLanguage)
 add_RunCMake_test(target_link_libraries)
+
+if (CMAKE_CXX_COMPILER_ID MATCHES "Borland"
+    OR CMAKE_GENERATOR MATCHES Xcode
+    OR CMAKE_GENERATOR MATCHES "Visual Studio")
+  set(target_compile_features_ARGS -DNO_UNKNOWN_COMPILER_TEST=1)
+endif()
+add_RunCMake_test(target_compile_features)
 add_RunCMake_test(CheckModules)
 add_RunCMake_test(CommandLine)
 
diff --git a/Tests/RunCMake/target_compile_features/CMakeLists.txt b/Tests/RunCMake/target_compile_features/CMakeLists.txt
new file mode 100644
index 0000000..aa7278d
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12)
+cmake_policy(SET CMP0025 NEW)
+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..fd7019c
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/RunCMakeTest.cmake
@@ -0,0 +1,8 @@
+include(RunCMake)
+
+run_cmake(not_a_cxx_feature)
+run_cmake(no_matching_cxx_feature)
+if (NOT NO_UNKNOWN_COMPILER_TEST)
+  set(RunCMake_TEST_OPTIONS "-DCMAKE_CXX_COMPILER_ID=UnknownCompiler")
+  run_cmake(unknown_compiler)
+endif()
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/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..a8f60c7
--- /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:4 \(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..99d04b6
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/no_matching_cxx_feature.cmake
@@ -0,0 +1,26 @@
+
+if (NOT ";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";gnuxx_typeof;"
+    AND NOT ";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";msvcxx_sealed;" )
+  # Simulate passing the test.
+  message(SEND_ERROR
+    "The compiler feature \"gnuxx_dummy\" is not known to compiler\n\"GNU\"\nversion 4.8.1."
+  )
+  return()
+endif()
+
+if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";gnuxx_typeof;")
+  set(feature msvcxx_sealed)
+  if (";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";msvcxx_sealed;")
+    # If a compiler supports both extensions, remove one of them.
+    list(REMOVE_ITEM CMAKE_CXX_COMPILE_FEATURES msvcxx_sealed)
+  endif()
+else()
+  set(feature gnuxx_typeof)
+endif()
+
+add_executable(main empty.cpp)
+
+target_compile_features(main
+  PRIVATE
+    ${feature}
+)
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..1b82258
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/not_a_cxx_feature-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at not_a_cxx_feature.cmake:3 \(target_compile_features\):
+  target_compile_features specified unknown feature "cxx_not_a_feature".
+Call Stack \(most recent call first\):
+  CMakeLists.txt:4 \(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/unknown_compiler-result.txt b/Tests/RunCMake/target_compile_features/unknown_compiler-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/unknown_compiler-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/target_compile_features/unknown_compiler-stderr.txt b/Tests/RunCMake/target_compile_features/unknown_compiler-stderr.txt
new file mode 100644
index 0000000..10f3293
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/unknown_compiler-stderr.txt
@@ -0,0 +1 @@
+^$
diff --git a/Tests/RunCMake/target_compile_features/unknown_compiler.cmake b/Tests/RunCMake/target_compile_features/unknown_compiler.cmake
new file mode 100644
index 0000000..e34d894
--- /dev/null
+++ b/Tests/RunCMake/target_compile_features/unknown_compiler.cmake
@@ -0,0 +1,4 @@
+
+add_library(mylib empty.cpp)
+# The unknown compiler doesn't fail on valid features.
+target_compile_features(mylib PRIVATE cxx_delegating_constructors)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=20594685256692cf4222e59774ce39fdfa21b576
commit 20594685256692cf4222e59774ce39fdfa21b576
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Sat Nov 9 09:18:53 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:45 2014 +0100

    Record compilers capable of msvcxx_sealed feature.
    
    Clang-cl is capable of this feature, but that is not yet released,
    nor have I tested it.

diff --git a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
index e7ba460..ba6f027 100644
--- a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
+++ b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
@@ -16,3 +16,6 @@ The features known to this version of CMake are:
 
 ``gnuxx_typeof``
   The GNU typeof extension.
+
+``msvcxx_sealed``
+  The MSVC sealed extension.
diff --git a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
index 8cd2051..8983826 100644
--- a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
@@ -1,2 +1,4 @@
 
 set(_cmake_feature_test_cxx_delegating_constructors "_MSC_VER >= 1800")
+
+set(_cmake_feature_test_msvcxx_sealed "_MSC_VER >= 1400")
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index d248664..eaf6cae 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -43,7 +43,8 @@
 
 #define FOR_EACH_CXX_FEATURE(F) \
   F(cxx_delegating_constructors) \
-  F(gnuxx_typeof)
+  F(gnuxx_typeof) \
+  F(msvcxx_sealed)
 
 class cmMakefile::Internals
 {

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=490877363b06aef81cda193ecbeb4660ec44dc9b
commit 490877363b06aef81cda193ecbeb4660ec44dc9b
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Sat Nov 9 09:18:32 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:44 2014 +0100

    Record compilers capable of the gnuxx_typeof feature.

diff --git a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
index 2e87bfb..e7ba460 100644
--- a/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
+++ b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
@@ -13,3 +13,6 @@ The features known to this version of CMake are:
   Delegating constructors, as defined in N1986_.
 
 .. _N1986: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf
+
+``gnuxx_typeof``
+  The GNU typeof extension.
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index f64cb66..28bd1cf 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -3,7 +3,9 @@ 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_CXX98_COMPILE_EXTENSIONS "@CMAKE_CXX98_COMPILE_EXTENSIONS@")
 set(CMAKE_CXX11_COMPILE_FEATURES "@CMAKE_CXX11_COMPILE_FEATURES@")
+set(CMAKE_CXX11_COMPILE_EXTENSIONS "@CMAKE_CXX11_COMPILE_EXTENSIONS@")
 
 set(CMAKE_CXX_PLATFORM_ID "@CMAKE_CXX_PLATFORM_ID@")
 set(CMAKE_CXX_SIMULATE_ID "@CMAKE_CXX_SIMULATE_ID@")
diff --git a/Modules/CMakeDetermineCompileFeatures.cmake b/Modules/CMakeDetermineCompileFeatures.cmake
index 40aa9d6..7950144 100644
--- a/Modules/CMakeDetermineCompileFeatures.cmake
+++ b/Modules/CMakeDetermineCompileFeatures.cmake
@@ -17,7 +17,9 @@ 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_CXX98_COMPILE_EXTENSIONS)
     set(CMAKE_CXX11_COMPILE_FEATURES)
+    set(CMAKE_CXX11_COMPILE_EXTENSIONS)
 
     include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake")
 
@@ -28,14 +30,21 @@ function(cmake_determine_compile_features lang)
       return()
     endif()
 
+    string(REPLACE "${CMAKE_CXX98_COMPILE_EXTENSIONS}" "" CMAKE_CXX11_COMPILE_EXTENSIONS "${CMAKE_CXX11_COMPILE_EXTENSIONS}")
+    string(REPLACE "${CMAKE_CXX11_COMPILE_FEATURES}" "" CMAKE_CXX11_COMPILE_EXTENSIONS "${CMAKE_CXX11_COMPILE_EXTENSIONS}")
+
     if(NOT CMAKE_CXX_COMPILE_FEATURES)
       set(CMAKE_CXX_COMPILE_FEATURES
+        ${CMAKE_CXX98_COMPILE_EXTENSIONS}
         ${CMAKE_CXX11_COMPILE_FEATURES}
+        ${CMAKE_CXX11_COMPILE_EXTENSIONS}
       )
     endif()
 
     set(CMAKE_CXX_COMPILE_FEATURES ${CMAKE_CXX_COMPILE_FEATURES} PARENT_SCOPE)
+    set(CMAKE_CXX98_COMPILE_EXTENSIONS ${CMAKE_CXX98_COMPILE_EXTENSIONS} PARENT_SCOPE)
     set(CMAKE_CXX11_COMPILE_FEATURES ${CMAKE_CXX11_COMPILE_FEATURES} PARENT_SCOPE)
+    set(CMAKE_CXX11_COMPILE_EXTENSIONS ${CMAKE_CXX11_COMPILE_EXTENSIONS} PARENT_SCOPE)
 
     message(STATUS "Detecting ${lang} compile features - done")
   endif()
diff --git a/Modules/Compiler/Clang-CXX-FeatureTests.cmake b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
index 940a182..f1eb031 100644
--- a/Modules/Compiler/Clang-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
@@ -7,3 +7,5 @@ foreach(feature ${testable_features})
 endforeach()
 
 unset(testable_features)
+
+set(_cmake_feature_test_gnuxx_typeof "!defined(__STRICT_ANSI__)")
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index 4a72a99..1a6b485 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -28,9 +28,15 @@ macro(cmake_record_cxx_compile_features)
     record_compiler_features(CXX "-std=${std_version}" ${list})
   endmacro()
 
+  if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1)
+    _get_clang_features(gnu++98 CMAKE_CXX98_COMPILE_EXTENSIONS)
+  endif()
+
   if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.1)
+    _get_clang_features(gnu++11 CMAKE_CXX11_COMPILE_EXTENSIONS)
     _get_clang_features(c++11 CMAKE_CXX11_COMPILE_FEATURES)
   elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1)
+    _get_clang_features(gnu++0x CMAKE_CXX11_COMPILE_EXTENSIONS)
     _get_clang_features(c++0x CMAKE_CXX11_COMPILE_FEATURES)
   endif()
 endmacro()
diff --git a/Modules/Compiler/GNU-CXX-FeatureTests.cmake b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
index 7da0563..242f19b 100644
--- a/Modules/Compiler/GNU-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
@@ -1,2 +1,4 @@
 
-set(_cmake_feature_test_cxx_delegating_constructors "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407")
+set(_cmake_feature_test_gnuxx_typeof "!defined(__STRICT_ANSI__)")
+
+set(_cmake_feature_test_cxx_delegating_constructors "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L")
diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake
index 7884eea..a15c14f 100644
--- a/Modules/Compiler/GNU-CXX.cmake
+++ b/Modules/Compiler/GNU-CXX.cmake
@@ -29,9 +29,15 @@ macro(cmake_record_cxx_compile_features)
     record_compiler_features(CXX "-std=${std_version}" ${list})
   endmacro()
 
+  if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.3)
+    _get_gcc_features(gnu++98 CMAKE_CXX98_COMPILE_EXTENSIONS)
+  endif()
+
   if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
     _get_gcc_features(c++11 CMAKE_CXX11_COMPILE_FEATURES)
+    _get_gcc_features(gnu++11 CMAKE_CXX11_COMPILE_EXTENSIONS)
   elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.3)
     _get_gcc_features(c++0x CMAKE_CXX11_COMPILE_FEATURES)
+    _get_gcc_features(gnu++0x CMAKE_CXX11_COMPILE_EXTENSIONS)
   endif()
 endmacro()
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 9376d9f..d248664 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -42,7 +42,8 @@
 #include <assert.h>
 
 #define FOR_EACH_CXX_FEATURE(F) \
-  F(cxx_delegating_constructors)
+  F(cxx_delegating_constructors) \
+  F(gnuxx_typeof)
 
 class cmMakefile::Internals
 {
diff --git a/Tests/SystemInformation/SystemInformation.in b/Tests/SystemInformation/SystemInformation.in
index 954a2fe..97298dc 100644
--- a/Tests/SystemInformation/SystemInformation.in
+++ b/Tests/SystemInformation/SystemInformation.in
@@ -26,7 +26,9 @@ 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_CXX98_COMPILE_EXTENSIONS == "${CMAKE_CXX98_COMPILE_EXTENSIONS}"
 CMAKE_CXX11_COMPILE_FEATURES == "${CMAKE_CXX11_COMPILE_FEATURES}"
+CMAKE_CXX11_COMPILE_EXTENSIONS == "${CMAKE_CXX11_COMPILE_EXTENSIONS}"
 
 // C shared library flag
 CMAKE_SHARED_LIBRARY_C_FLAGS == "${CMAKE_SHARED_LIBRARY_C_FLAGS}"

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a6ea37fab08a8d01ad54c1982eb2285de58eb019
commit a6ea37fab08a8d01ad54c1982eb2285de58eb019
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Oct 17 11:47:29 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:44 2014 +0100

    Record the compilers capable of the cxx_delegating_constructors feature.
    
    Add a feature test using the compiler macros and the preprocessor to
    determine available features. Add a unit test which outputs the
    feature test file compiled. Record the list of features in
    the SystemInformation unit test.
    
    Add a CMAKE_CXX_COMPILE_FEATURES variable which contains all features
    known to the loaded compiler, and a CMAKE_CXX_KNOWN_FEATURES variable
    containing all features known to CMake. Add language standard specific
    variables for internal use to determine the standard-specific compile
    flags to use. Add internal variables matching CMAKE_PP_NAME_<feature>
    for each feature. Those variables are used as preprocessor defines.

diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index e0549b8..dc56331 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -256,6 +256,8 @@ 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_Fortran_MODDIR_DEFAULT
    /variable/CMAKE_Fortran_MODDIR_FLAG
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_KNOWN_FEATURES.rst b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
new file mode 100644
index 0000000..2e87bfb
--- /dev/null
+++ b/Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
@@ -0,0 +1,15 @@
+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 known to this version of CMake are:
+
+``cxx_delegating_constructors``
+  Delegating constructors, as defined in N1986_.
+
+.. _N1986: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index 35aa6c4..f64cb66 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 at 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/Clang-CXX-FeatureTests.cmake b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
new file mode 100644
index 0000000..940a182
--- /dev/null
+++ b/Modules/Compiler/Clang-CXX-FeatureTests.cmake
@@ -0,0 +1,9 @@
+
+set(testable_features
+  cxx_delegating_constructors
+)
+foreach(feature ${testable_features})
+  set(_cmake_feature_test_${feature} "__has_extension(${feature})")
+endforeach()
+
+unset(testable_features)
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index a1b3a10..4a72a99 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -22,3 +22,15 @@ 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()
+
+macro(cmake_record_cxx_compile_features)
+  macro(_get_clang_features std_version list)
+    record_compiler_features(CXX "-std=${std_version}" ${list})
+  endmacro()
+
+  if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.1)
+    _get_clang_features(c++11 CMAKE_CXX11_COMPILE_FEATURES)
+  elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1)
+    _get_clang_features(c++0x CMAKE_CXX11_COMPILE_FEATURES)
+  endif()
+endmacro()
diff --git a/Modules/Compiler/GNU-CXX-FeatureTests.cmake b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
new file mode 100644
index 0000000..7da0563
--- /dev/null
+++ b/Modules/Compiler/GNU-CXX-FeatureTests.cmake
@@ -0,0 +1,2 @@
+
+set(_cmake_feature_test_cxx_delegating_constructors "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407")
diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake
index 3ee8639..7884eea 100644
--- a/Modules/Compiler/GNU-CXX.cmake
+++ b/Modules/Compiler/GNU-CXX.cmake
@@ -23,3 +23,15 @@ 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 (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
+    _get_gcc_features(c++11 CMAKE_CXX11_COMPILE_FEATURES)
+  elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.3)
+    _get_gcc_features(c++0x CMAKE_CXX11_COMPILE_FEATURES)
+  endif()
+endmacro()
diff --git a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
new file mode 100644
index 0000000..8cd2051
--- /dev/null
+++ b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
@@ -0,0 +1,2 @@
+
+set(_cmake_feature_test_cxx_delegating_constructors "_MSC_VER >= 1800")
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/Modules/Platform/Windows-MSVC-CXX.cmake b/Modules/Platform/Windows-MSVC-CXX.cmake
index 0e85005..89885b8 100644
--- a/Modules/Platform/Windows-MSVC-CXX.cmake
+++ b/Modules/Platform/Windows-MSVC-CXX.cmake
@@ -4,3 +4,7 @@ if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0)
   set(_FS_CXX " /FS")
 endif()
 __windows_compiler_msvc(CXX)
+
+macro(cmake_record_cxx_compile_features)
+  record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES)
+endmacro()
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index f82acc8..9376d9f 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_delegating_constructors)
+
 class cmMakefile::Internals
 {
 public:
@@ -2451,6 +2454,20 @@ 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
+    }
+#define PP_FEATURE_NAME(F) \
+  if (name == "CMAKE_PP_NAME_" #F) \
+    { \
+    static std::string val = ("COMPILER_" + cmSystemTools::UpperCase(#F)); \
+    return val.c_str(); \
+    }
+  FOR_EACH_CXX_FEATURE(PP_FEATURE_NAME)
+#undef PP_FEATURE_NAME
   const char* def = this->Internal->VarStack.top().Get(name);
   if(!def)
     {
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 92b24e2..954a2fe 100644
--- a/Tests/SystemInformation/SystemInformation.in
+++ b/Tests/SystemInformation/SystemInformation.in
@@ -25,6 +25,8 @@ 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}"

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=91329bec297cb3e5480e16d9b68896ff25ffb2b4
commit 91329bec297cb3e5480e16d9b68896ff25ffb2b4
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Sun Oct 13 02:00:24 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:44 2014 +0100

    cmTarget: Add CXX_STANDARD and CXX_EXTENSION target properties.
    
    These are used to determine whether to add -std=c++11, -std=gnu++11
    etc flags on the compile line.

diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 6ea5839..d0a5a77 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -106,6 +106,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
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 8b4ce26..e0549b8 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -256,6 +256,7 @@ Variables for Languages
    :maxdepth: 1
 
    /variable/CMAKE_COMPILER_IS_GNULANG
+   /variable/CMAKE_CXX_STANDARD
    /variable/CMAKE_Fortran_MODDIR_DEFAULT
    /variable/CMAKE_Fortran_MODDIR_FLAG
    /variable/CMAKE_Fortran_MODOUT_FLAG
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/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/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index c47147c..2958e9e 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1461,6 +1461,7 @@ void cmLocalGenerator::AddCompileOptions(
       this->AppendFlagEscape(flags, *i);
       }
     }
+  this->AddCompilerRequirementFlag(flags, target, lang);
 }
 
 //----------------------------------------------------------------------------
@@ -2130,6 +2131,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 61488fe..d876958 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/cmTarget.cxx b/Source/cmTarget.cxx
index 17c8a4d..c027503 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -297,6 +297,7 @@ 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);
     }
 
   // Collect the set of configuration types.
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 726e790..9ad2281 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -278,6 +278,19 @@ if(BUILD_TESTING)
   ADD_TEST_MACRO(AliasTarget AliasTarget)
   ADD_TEST_MACRO(StagingPrefix StagingPrefix)
   ADD_TEST_MACRO(InterfaceLibrary InterfaceLibrary)
+  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/CxxDialect/CMakeLists.txt b/Tests/CxxDialect/CMakeLists.txt
new file mode 100644
index 0000000..f0b2d10
--- /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 TRUE)
+
+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 TRUE)
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;
+}

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7713cce6e6765d4c5963d77c30e3ca6ec32e9f7e
commit 7713cce6e6765d4c5963d77c30e3ca6ec32e9f7e
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Sun Oct 13 01:26:16 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:44 2014 +0100

    Add some COMPILE_OPTIONS for specifying C++ dialect.
    
    These are compiler-specific, compiler version specific, extension specific
    and standard version specific.

diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index ab1b766..a1b3a10 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -9,3 +9,16 @@ 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.cmake b/Modules/Compiler/GNU-CXX.cmake
index 33d6093..3ee8639 100644
--- a/Modules/Compiler/GNU-CXX.cmake
+++ b/Modules/Compiler/GNU-CXX.cmake
@@ -10,3 +10,16 @@ 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()
diff --git a/Tests/SystemInformation/SystemInformation.in b/Tests/SystemInformation/SystemInformation.in
index df3bf49..92b24e2 100644
--- a/Tests/SystemInformation/SystemInformation.in
+++ b/Tests/SystemInformation/SystemInformation.in
@@ -21,6 +21,10 @@ 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}"
 
 // C shared library flag
 CMAKE_SHARED_LIBRARY_C_FLAGS == "${CMAKE_SHARED_LIBRARY_C_FLAGS}"

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ce63e5cd29aa409a2334964f8925d99c06ab6869
commit ce63e5cd29aa409a2334964f8925d99c06ab6869
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Nov 11 20:35:52 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Mar 20 21:52:44 2014 +0100

    Don't load Clang-CXX from AppleClang-CXX.
    
    The Clang-CXX module is going to get version-specific checks, and
    the version system for AppleClang is not the same as Clang.

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..ab1b766 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -4,3 +4,8 @@ __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()

-----------------------------------------------------------------------

Summary of changes:
 Help/command/target_compile_features.rst           |   31 ++
 Help/index.rst                                     |    1 +
 Help/manual/cmake-commands.7.rst                   |    1 +
 Help/manual/cmake-compile-features.7.rst           |  344 ++++++++++++++++++++
 Help/manual/cmake-developer.7.rst                  |   27 ++
 Help/manual/cmake-generator-expressions.7.rst      |    3 +
 Help/manual/cmake-modules.7.rst                    |    1 +
 Help/manual/cmake-properties.7.rst                 |    4 +
 Help/manual/cmake-variables.7.rst                  |    3 +
 Help/module/WriteCompilerDetectionHeader.rst       |    1 +
 Help/prop_tgt/COMPILE_FEATURES.rst                 |   11 +
 Help/prop_tgt/CXX_EXTENSIONS.rst                   |   11 +
 Help/prop_tgt/CXX_STANDARD.rst                     |   17 +
 Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst       |   16 +
 Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst       |   14 +
 Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst         |   54 +++
 Help/variable/CMAKE_CXX_STANDARD.rst               |   11 +
 Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst    |    3 +-
 Modules/CMakeCXXCompiler.cmake.in                  |    7 +
 Modules/CMakeDetermineCompileFeatures.cmake        |   60 ++++
 Modules/CMakeTestCXXCompiler.cmake                 |    3 +
 Modules/Compiler/AppleClang-CXX.cmake              |    7 +-
 Modules/Compiler/Clang-CXX-FeatureTests.cmake      |   19 ++
 Modules/Compiler/Clang-CXX.cmake                   |   42 +++
 Modules/Compiler/GNU-CXX-FeatureTests.cmake        |   20 ++
 Modules/Compiler/GNU-CXX.cmake                     |   37 +++
 Modules/Compiler/MSVC-CXX-FeatureTests.cmake       |   15 +
 Modules/Compiler/QCC-CXX-FeatureTests.cmake        |    4 +
 Modules/Internal/FeatureTesting.cmake              |   57 ++++
 Modules/Platform/Windows-MSVC-CXX.cmake            |    8 +
 Modules/WriteCompilerDetectionHeader.cmake         |  270 +++++++++++++++
 Source/CMakeLists.txt                              |    1 +
 Source/cmExportBuildFileGenerator.cxx              |    3 +
 Source/cmExportInstallFileGenerator.cxx            |    4 +
 Source/cmGeneratorExpression.cxx                   |    6 +
 Source/cmGeneratorExpression.h                     |    4 +
 Source/cmGeneratorExpressionDAGChecker.h           |    3 +-
 Source/cmGeneratorExpressionEvaluator.cxx          |   40 +++
 Source/cmGeneratorExpressionEvaluator.h            |    1 +
 Source/cmLocalGenerator.cxx                        |   36 ++
 Source/cmLocalGenerator.h                          |    2 +
 Source/cmMakefile.cxx                              |  274 ++++++++++++++++
 Source/cmMakefile.h                                |    6 +
 Source/cmTarget.cxx                                |  180 ++++++++++
 Source/cmTarget.h                                  |    4 +
 Source/cmTargetCompileDefinitionsCommand.cxx       |    3 +-
 Source/cmTargetCompileDefinitionsCommand.h         |    2 +-
 ...mand.cxx => cmTargetCompileFeaturesCommand.cxx} |   43 +--
 ...sCommand.h => cmTargetCompileFeaturesCommand.h} |   26 +-
 Source/cmTargetCompileOptionsCommand.cxx           |    3 +-
 Source/cmTargetCompileOptionsCommand.h             |    2 +-
 Source/cmTargetIncludeDirectoriesCommand.cxx       |    3 +-
 Source/cmTargetIncludeDirectoriesCommand.h         |    2 +-
 Source/cmTargetPropCommandBase.cxx                 |   14 +-
 Source/cmTargetPropCommandBase.h                   |    4 +-
 .../target_compile_features/CMakeLists.txt         |   42 +++
 .../target_compile_features/binary_literals.cpp    |    6 +
 .../target_compile_features}/dummy.cpp             |    0
 .../feature_conditional_link/CMakeLists.txt        |   26 ++
 .../have_variadics/interface.h                     |   20 ++
 .../no_variadics/interface.h                       |    6 +
 .../feature_conditional_link/template_user.cpp     |    8 +
 .../target_compile_features/gnuxx_typeof_test.cpp  |    6 +
 .../lib_delegating_constructors.cpp                |    8 +
 .../lib_delegating_constructors.h                  |   17 +
 .../target_compile_features/lib_user.cpp           |   27 ++
 .../CMakeCommands/target_compile_features/main.cpp |   25 ++
 .../target_compile_features/msvcxx_sealed_test.cpp |    8 +
 Tests/CMakeLists.txt                               |   30 ++
 Tests/CxxDialect/CMakeLists.txt                    |   14 +
 Tests/CxxDialect/use_constexpr.cxx                 |   10 +
 Tests/CxxDialect/use_constexpr_and_typeof.cxx      |   11 +
 Tests/CxxDialect/use_typeof.cxx                    |    6 +
 Tests/ExportImport/Export/Interface/CMakeLists.txt |    5 +-
 Tests/ExportImport/Import/Interface/CMakeLists.txt |   24 ++
 .../WriteCompilerDetectionHeader/CMakeLists.txt    |  100 ++++++
 Tests/Module/WriteCompilerDetectionHeader/main.cpp |   31 ++
 Tests/RunCMake/CMakeLists.txt                      |   10 +
 .../{TargetObjects => have_feature}/CMakeLists.txt |    0
 Tests/RunCMake/have_feature/RunCMakeTest.cmake     |    3 +
 Tests/RunCMake/{CMP0022 => have_feature}/empty.cpp |    0
 .../inconsistent-result.txt}                       |    0
 .../RunCMake/have_feature/inconsistent-stderr.txt  |    4 +
 Tests/RunCMake/have_feature/inconsistent.cmake     |    8 +
 .../target_compile_features/CMakeLists.txt         |    4 +
 .../target_compile_features/RunCMakeTest.cmake     |   15 +
 .../alias_target-result.txt}                       |    0
 .../alias_target-stderr.txt                        |    4 +
 .../target_compile_features/alias_target.cmake     |    4 +
 .../{CMP0022 => target_compile_features}/empty.cpp |    0
 .../imported_target-result.txt}                    |    0
 .../imported_target-stderr.txt                     |    4 +
 .../target_compile_features/imported_target.cmake  |    3 +
 .../invalid_args-result.txt}                       |    0
 .../invalid_args-stderr.txt                        |    4 +
 .../target_compile_features/invalid_args.cmake     |    3 +
 .../invalid_args_on_interface-result.txt}          |    0
 .../invalid_args_on_interface-stderr.txt           |    5 +
 .../invalid_args_on_interface.cmake                |    3 +
 .../no_matching_cxx_feature-result.txt}            |    0
 .../no_matching_cxx_feature-stderr.txt             |    8 +
 .../no_matching_cxx_feature.cmake                  |   26 ++
 .../no_target-result.txt}                          |    0
 .../target_compile_features/no_target-stderr.txt   |    5 +
 .../target_compile_features/no_target.cmake        |    2 +
 .../not_a_cxx_feature-result.txt}                  |    0
 .../not_a_cxx_feature-stderr.txt                   |    4 +
 .../not_a_cxx_feature.cmake                        |    6 +
 .../not_enough_args-result.txt}                    |    0
 .../not_enough_args-stderr.txt                     |    4 +
 .../target_compile_features/not_enough_args.cmake  |    3 +
 .../unknown_compiler-result.txt}                   |    0
 .../unknown_compiler-stderr.txt}                   |    0
 .../target_compile_features/unknown_compiler.cmake |    4 +
 .../utility_target-result.txt}                     |    0
 .../utility_target-stderr.txt                      |    4 +
 .../target_compile_features/utility_target.cmake   |    4 +
 Tests/SystemInformation/CMakeLists.txt             |    2 +-
 Tests/SystemInformation/SystemInformation.in       |    9 +
 119 files changed, 2296 insertions(+), 57 deletions(-)
 create mode 100644 Help/command/target_compile_features.rst
 create mode 100644 Help/manual/cmake-compile-features.7.rst
 create mode 100644 Help/module/WriteCompilerDetectionHeader.rst
 create mode 100644 Help/prop_tgt/COMPILE_FEATURES.rst
 create mode 100644 Help/prop_tgt/CXX_EXTENSIONS.rst
 create mode 100644 Help/prop_tgt/CXX_STANDARD.rst
 create mode 100644 Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
 create mode 100644 Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
 create mode 100644 Help/variable/CMAKE_CXX_KNOWN_FEATURES.rst
 create mode 100644 Help/variable/CMAKE_CXX_STANDARD.rst
 create mode 100644 Modules/CMakeDetermineCompileFeatures.cmake
 create mode 100644 Modules/Compiler/Clang-CXX-FeatureTests.cmake
 create mode 100644 Modules/Compiler/GNU-CXX-FeatureTests.cmake
 create mode 100644 Modules/Compiler/MSVC-CXX-FeatureTests.cmake
 create mode 100644 Modules/Compiler/QCC-CXX-FeatureTests.cmake
 create mode 100644 Modules/Internal/FeatureTesting.cmake
 create mode 100644 Modules/WriteCompilerDetectionHeader.cmake
 copy Source/{cmTargetCompileDefinitionsCommand.cxx => cmTargetCompileFeaturesCommand.cxx} (64%)
 copy Source/{cmTargetCompileOptionsCommand.h => cmTargetCompileFeaturesCommand.h} (63%)
 create mode 100644 Tests/CMakeCommands/target_compile_features/CMakeLists.txt
 create mode 100644 Tests/CMakeCommands/target_compile_features/binary_literals.cpp
 copy Tests/{InterfaceLibrary => CMakeCommands/target_compile_features}/dummy.cpp (100%)
 create mode 100644 Tests/CMakeCommands/target_compile_features/feature_conditional_link/CMakeLists.txt
 create mode 100644 Tests/CMakeCommands/target_compile_features/feature_conditional_link/have_variadics/interface.h
 create mode 100644 Tests/CMakeCommands/target_compile_features/feature_conditional_link/no_variadics/interface.h
 create mode 100644 Tests/CMakeCommands/target_compile_features/feature_conditional_link/template_user.cpp
 create mode 100644 Tests/CMakeCommands/target_compile_features/gnuxx_typeof_test.cpp
 create mode 100644 Tests/CMakeCommands/target_compile_features/lib_delegating_constructors.cpp
 create mode 100644 Tests/CMakeCommands/target_compile_features/lib_delegating_constructors.h
 create mode 100644 Tests/CMakeCommands/target_compile_features/lib_user.cpp
 create mode 100644 Tests/CMakeCommands/target_compile_features/main.cpp
 create mode 100644 Tests/CMakeCommands/target_compile_features/msvcxx_sealed_test.cpp
 create mode 100644 Tests/CxxDialect/CMakeLists.txt
 create mode 100644 Tests/CxxDialect/use_constexpr.cxx
 create mode 100644 Tests/CxxDialect/use_constexpr_and_typeof.cxx
 create mode 100644 Tests/CxxDialect/use_typeof.cxx
 create mode 100644 Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt
 create mode 100644 Tests/Module/WriteCompilerDetectionHeader/main.cpp
 copy Tests/RunCMake/{TargetObjects => have_feature}/CMakeLists.txt (100%)
 create mode 100644 Tests/RunCMake/have_feature/RunCMakeTest.cmake
 copy Tests/RunCMake/{CMP0022 => have_feature}/empty.cpp (100%)
 copy Tests/RunCMake/{CMP0004/CMP0004-NEW-result.txt => have_feature/inconsistent-result.txt} (100%)
 create mode 100644 Tests/RunCMake/have_feature/inconsistent-stderr.txt
 create mode 100644 Tests/RunCMake/have_feature/inconsistent.cmake
 create mode 100644 Tests/RunCMake/target_compile_features/CMakeLists.txt
 create mode 100644 Tests/RunCMake/target_compile_features/RunCMakeTest.cmake
 copy Tests/RunCMake/{CMP0004/CMP0004-NEW-result.txt => target_compile_features/alias_target-result.txt} (100%)
 create mode 100644 Tests/RunCMake/target_compile_features/alias_target-stderr.txt
 create mode 100644 Tests/RunCMake/target_compile_features/alias_target.cmake
 copy Tests/RunCMake/{CMP0022 => target_compile_features}/empty.cpp (100%)
 copy Tests/RunCMake/{CMP0004/CMP0004-NEW-result.txt => target_compile_features/imported_target-result.txt} (100%)
 create mode 100644 Tests/RunCMake/target_compile_features/imported_target-stderr.txt
 create mode 100644 Tests/RunCMake/target_compile_features/imported_target.cmake
 copy Tests/RunCMake/{CMP0004/CMP0004-NEW-result.txt => target_compile_features/invalid_args-result.txt} (100%)
 create mode 100644 Tests/RunCMake/target_compile_features/invalid_args-stderr.txt
 create mode 100644 Tests/RunCMake/target_compile_features/invalid_args.cmake
 copy Tests/RunCMake/{CMP0004/CMP0004-NEW-result.txt => target_compile_features/invalid_args_on_interface-result.txt} (100%)
 create mode 100644 Tests/RunCMake/target_compile_features/invalid_args_on_interface-stderr.txt
 create mode 100644 Tests/RunCMake/target_compile_features/invalid_args_on_interface.cmake
 copy Tests/RunCMake/{CMP0004/CMP0004-NEW-result.txt => target_compile_features/no_matching_cxx_feature-result.txt} (100%)
 create mode 100644 Tests/RunCMake/target_compile_features/no_matching_cxx_feature-stderr.txt
 create mode 100644 Tests/RunCMake/target_compile_features/no_matching_cxx_feature.cmake
 copy Tests/RunCMake/{CMP0004/CMP0004-NEW-result.txt => target_compile_features/no_target-result.txt} (100%)
 create mode 100644 Tests/RunCMake/target_compile_features/no_target-stderr.txt
 create mode 100644 Tests/RunCMake/target_compile_features/no_target.cmake
 copy Tests/RunCMake/{CMP0004/CMP0004-NEW-result.txt => target_compile_features/not_a_cxx_feature-result.txt} (100%)
 create mode 100644 Tests/RunCMake/target_compile_features/not_a_cxx_feature-stderr.txt
 create mode 100644 Tests/RunCMake/target_compile_features/not_a_cxx_feature.cmake
 copy Tests/RunCMake/{CMP0004/CMP0004-NEW-result.txt => target_compile_features/not_enough_args-result.txt} (100%)
 create mode 100644 Tests/RunCMake/target_compile_features/not_enough_args-stderr.txt
 create mode 100644 Tests/RunCMake/target_compile_features/not_enough_args.cmake
 copy Tests/RunCMake/{CMP0022/CMP0022-WARN-empty-old-result.txt => target_compile_features/unknown_compiler-result.txt} (100%)
 copy Tests/RunCMake/{CMP0022/CMP0022-NOWARN-exe-stderr.txt => target_compile_features/unknown_compiler-stderr.txt} (100%)
 create mode 100644 Tests/RunCMake/target_compile_features/unknown_compiler.cmake
 copy Tests/RunCMake/{CMP0004/CMP0004-NEW-result.txt => target_compile_features/utility_target-result.txt} (100%)
 create mode 100644 Tests/RunCMake/target_compile_features/utility_target-stderr.txt
 create mode 100644 Tests/RunCMake/target_compile_features/utility_target.cmake


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list