فهرست منبع

Features: Enable compiler extensions by default.

Compilers enable their extensions by default, and disabling them
implicitly can lead to results which are surprising or non-obvious
to debug.

 http://public.kitware.com/pipermail/cmake-developers/2014-May/010575.html
 http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/10214
 https://www.mail-archive.com/[email protected]/msg10116.html
 (Compiler feature extensions by default, 29 May 2014)
Stephen Kelly 11 سال پیش
والد
کامیت
60a981ea8e

+ 1 - 1
Help/command/target_compile_features.rst

@@ -11,7 +11,7 @@ Specify compiler features required when compiling a given target.  If the
 feature is not listed in the :variable:`CMAKE_C_COMPILE_FEATURES` variable
 or :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
+an additional compiler flag, such as ``-std=gnu++11``, the flag will be added
 automatically.
 
 The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to

+ 11 - 14
Help/manual/cmake-compile-features.7.rst

@@ -47,7 +47,7 @@ be compiled with compiler support for the
 
 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``
+of the feature, and will add any necessary flags such as ``-std=gnu++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.
@@ -59,8 +59,8 @@ for each target.
 
 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``
+supports variadic templates (with a warning) even if ``-std=gnu++98`` is
+used.  CMake adds the ``-std=gnu++11`` flag if ``cxx_variadic_templates``
 is specified as a requirement.
 
 In the above example, ``mylib`` requires ``cxx_constexpr`` when it
@@ -76,7 +76,7 @@ known feature), that may be specified with the ``PUBLIC`` or
   # cxx_constexpr is a usage-requirement
   target_compile_features(mylib PUBLIC cxx_constexpr)
 
-  # main.cpp will be compiled with -std=c++11 on GNU for cxx_constexpr.
+  # main.cpp will be compiled with -std=gnu++11 on GNU for cxx_constexpr.
   add_executable(myexe main.cpp)
   target_link_libraries(myexe mylib)
 
@@ -84,16 +84,13 @@ Feature requirements are evaluated transitively by consuming the link
 implementation.  See :manual:`cmake-buildsystem(7)` for more on
 transitive behavior of build properties and usage requirements.
 
-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 by expecting the ``typeof`` GNU 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 that compiler extensions are relied upon by setting
-the :prop_tgt:`CXX_EXTENSIONS` target property to ``ON`` when starting to
-use the :command:`target_compile_features` command.
+Because the :prop_tgt:`CXX_EXTENSIONS` target property is ``ON`` by default,
+CMake uses extended variants of language dialects by default, such as
+``-std=gnu++11`` instead of ``-std=c++11``.  That target property may be
+set to ``OFF`` to use the non-extended variant of the dialect flag.  Note
+that because most compilers enable extensions by default, this could
+expose cross-platform bugs in user code or in the headers of third-party
+dependencies.
 
 Optional Compile Features
 =========================

+ 2 - 1
Help/prop_tgt/CXX_EXTENSIONS.rst

@@ -5,7 +5,8 @@ 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.
+as ``-std=gnu++11`` instead of ``-std=c++11`` to the compile line.  This
+property is ``ON`` by default.
 
 See the :manual:`cmake-compile-features(7)` manual for information on
 compile features.

+ 3 - 3
Help/prop_tgt/CXX_STANDARD.rst

@@ -5,7 +5,7 @@ The C++ standard whose features are requested to build this target.
 
 This property specifies the C++ standard whose features are requested
 to build this target.  For some compilers, this results in adding a
-flag such as ``-std=c++11`` to the compile line.
+flag such as ``-std=gnu++11`` to the compile line.
 
 Supported values are ``98`` and ``11``.
 
@@ -17,9 +17,9 @@ means that using:
 
   set_property(TARGET tgt PROPERTY CXX_STANDARD 11)
 
-with a compiler which does not support ``-std=c++11`` or an equivalent
+with a compiler which does not support ``-std=gnu++11`` or an equivalent
 flag will not result in an error or warning, but will instead add the
-``-std=c++98`` flag if supported.  This "decay" behavior may be controlled
+``-std=gnu++98`` flag if supported.  This "decay" behavior may be controlled
 with the :prop_tgt:`CXX_STANDARD_REQUIRED` target property.
 
 See the :manual:`cmake-compile-features(7)` manual for information on

+ 2 - 1
Help/prop_tgt/C_EXTENSIONS.rst

@@ -5,7 +5,8 @@ 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=gnu11`` instead of ``-std=c11`` to the compile line.
+as ``-std=gnu11`` instead of ``-std=c11`` to the compile line.  This
+property is ``ON`` by default.
 
 See the :manual:`cmake-compile-features(7)` manual for information on
 compile features.

+ 3 - 3
Help/prop_tgt/C_STANDARD.rst

@@ -5,7 +5,7 @@ The C standard whose features are requested to build this target.
 
 This property specifies the C standard whose features are requested
 to build this target.  For some compilers, this results in adding a
-flag such as ``-std=c11`` to the compile line.
+flag such as ``-std=gnu11`` to the compile line.
 
 Supported values are ``90``, ``99`` and ``11``.
 
@@ -17,9 +17,9 @@ means that using:
 
   set_property(TARGET tgt PROPERTY C_STANDARD 11)
 
-with a compiler which does not support ``-std=c11`` or an equivalent
+with a compiler which does not support ``-std=gnu11`` or an equivalent
 flag will not result in an error or warning, but will instead add the
-``-std=c99`` or ``-std=c90`` flag if supported.  This "decay" behavior may
+``-std=gnu99`` or ``-std=gnu90`` flag if supported.  This "decay" behavior may
 be controlled with the :prop_tgt:`C_STANDARD_REQUIRED` target property.
 
 See the :manual:`cmake-compile-features(7)` manual for information on

+ 10 - 2
Source/cmLocalGenerator.cxx

@@ -2195,8 +2195,16 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget* target,
     return;
     }
   std::string extProp = lang + "_EXTENSIONS";
-  bool ext = target->GetPropertyAsBool(extProp);
-  std::string type = ext ? "EXTENSION" : "STANDARD";
+  std::string type = "EXTENSION";
+  bool ext = true;
+  if (const char* extPropValue = target->GetProperty(extProp))
+    {
+    if (cmSystemTools::IsOff(extPropValue))
+      {
+      ext = false;
+      type = "STANDARD";
+      }
+    }
 
   if (target->GetPropertyAsBool(lang + "_STANDARD_REQUIRED"))
     {

+ 16 - 2
Tests/CxxDialect/CMakeLists.txt

@@ -4,11 +4,25 @@ project(CxxDialect)
 
 add_executable(use_typeof use_typeof.cxx)
 set_property(TARGET use_typeof PROPERTY CXX_STANDARD 98)
-set_property(TARGET use_typeof PROPERTY CXX_EXTENSIONS ON)
 
 add_executable(use_constexpr use_constexpr.cxx)
 set_property(TARGET use_constexpr PROPERTY CXX_STANDARD 11)
 
 add_executable(CxxDialect use_constexpr_and_typeof.cxx)
 set_property(TARGET CxxDialect PROPERTY CXX_STANDARD 11)
-set_property(TARGET CxxDialect PROPERTY CXX_EXTENSIONS ON)
+
+try_compile(typeof_no_extensions_works
+  "${CMAKE_CURRENT_BINARY_DIR}/use_typeof_test"
+  "${CMAKE_CURRENT_SOURCE_DIR}/use_typeof.cxx"
+  COMPILE_DEFINITIONS
+  CMAKE_FLAGS
+    "-DCMAKE_CXX_STANDARD=98"
+    "-DCMAKE_CXX_EXTENSIONS=FALSE"
+  OUTPUT_VARIABLE OUTPUT
+)
+
+if (typeof_no_extensions_works)
+  message("Use of typeof extension with extensions disabled works, but is expected to fail: ${OUTPUT}")
+else()
+  message("Use of typeof extension with extensions disabled fails, as expected")
+endif()

+ 1 - 0
Tests/RunCMake/CompileFeatures/RequireCXX11.cmake

@@ -1,4 +1,5 @@
 
 add_library(foo empty.cpp)
 set_property(TARGET foo PROPERTY CXX_STANDARD 11)
+set_property(TARGET foo PROPERTY CXX_EXTENSIONS FALSE)
 set_property(TARGET foo PROPERTY CXX_STANDARD_REQUIRED TRUE)

+ 0 - 1
Tests/RunCMake/CompileFeatures/RequireCXX11Ext.cmake

@@ -1,5 +1,4 @@
 
 add_library(foo empty.cpp)
 set_property(TARGET foo PROPERTY CXX_STANDARD 11)
-set_property(TARGET foo PROPERTY CXX_EXTENSIONS TRUE)
 set_property(TARGET foo PROPERTY CXX_STANDARD_REQUIRED TRUE)

+ 0 - 1
Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable.cmake

@@ -2,4 +2,3 @@
 set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
 add_library(foo empty.cpp)
 set_property(TARGET foo PROPERTY CXX_STANDARD 11)
-set_property(TARGET foo PROPERTY CXX_EXTENSIONS TRUE)

+ 1 - 0
Tests/RunCMake/CompileFeatures/RequireCXX11Variable.cmake

@@ -2,3 +2,4 @@
 set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
 add_library(foo empty.cpp)
 set_property(TARGET foo PROPERTY CXX_STANDARD 11)
+set_property(TARGET foo PROPERTY CXX_EXTENSIONS FALSE)

+ 1 - 0
Tests/RunCMake/CompileFeatures/RequireCXX98.cmake

@@ -2,3 +2,4 @@
 add_library(foo empty.cpp)
 set_property(TARGET foo PROPERTY CXX_STANDARD 98)
 set_property(TARGET foo PROPERTY CXX_STANDARD_REQUIRED TRUE)
+set_property(TARGET foo PROPERTY CXX_EXTENSIONS FALSE)

+ 0 - 1
Tests/RunCMake/CompileFeatures/RequireCXX98Ext.cmake

@@ -1,5 +1,4 @@
 
 add_library(foo empty.cpp)
 set_property(TARGET foo PROPERTY CXX_STANDARD 98)
-set_property(TARGET foo PROPERTY CXX_EXTENSIONS TRUE)
 set_property(TARGET foo PROPERTY CXX_STANDARD_REQUIRED TRUE)

+ 0 - 1
Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable.cmake

@@ -2,4 +2,3 @@
 set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
 add_library(foo empty.cpp)
 set_property(TARGET foo PROPERTY CXX_STANDARD 98)
-set_property(TARGET foo PROPERTY CXX_EXTENSIONS TRUE)

+ 1 - 0
Tests/RunCMake/CompileFeatures/RequireCXX98Variable.cmake

@@ -2,3 +2,4 @@
 set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
 add_library(foo empty.cpp)
 set_property(TARGET foo PROPERTY CXX_STANDARD 98)
+set_property(TARGET foo PROPERTY CXX_EXTENSIONS FALSE)