소스 검색

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.
Stephen Kelly 12 년 전
부모
커밋
913394af24

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

+ 2 - 0
Help/manual/cmake-variables.7.rst

@@ -257,6 +257,8 @@ Variables for Languages
    :maxdepth: 1
 
    /variable/CMAKE_COMPILER_IS_GNULANG
+   /variable/CMAKE_CXX_STANDARD
+   /variable/CMAKE_CXX_EXTENSIONS
    /variable/CMAKE_Fortran_MODDIR_DEFAULT
    /variable/CMAKE_Fortran_MODDIR_FLAG
    /variable/CMAKE_Fortran_MODOUT_FLAG

+ 8 - 0
Help/prop_tgt/CXX_EXTENSIONS.rst

@@ -0,0 +1,8 @@
+CXX_EXTENSIONS
+--------------
+
+Boolean specifying whether compiler specific extensions are requested.
+
+This property specifies whether compiler specific extensions should be
+used.  For some compilers, this results in adding a flag such
+as ``-std=gnu++11`` instead of ``-std=c++11`` to the compile line.

+ 14 - 0
Help/prop_tgt/CXX_STANDARD.rst

@@ -0,0 +1,14 @@
+CXX_STANDARD
+------------
+
+The C++ standard whose features are required to build this target.
+
+This property specifies the C++ standard whose features are required
+to build this target.  For some compilers, this results in adding a
+flag such as ``-std=c++11`` to the compile line.
+
+Supported values are ``98`` and ``11``.
+
+This property is initialized by the value of
+the :variable:`CMAKE_CXX_STANDARD` variable if it is set when a target
+is created.

+ 8 - 0
Help/release/dev/compile-language-features.rst

@@ -0,0 +1,8 @@
+target-language-features
+------------------------
+
+* New :prop_tgt:`CXX_STANDARD` and :prop_tgt:`CXX_EXTENSIONS` target
+  properties may specify values which CMake uses to compute required
+  compile options such as ``-std=c++11`` or ``-std=gnu++11``. The
+  :variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_EXTENSIONS`
+  variables may be set to initialize the target properties.

+ 8 - 0
Help/variable/CMAKE_CXX_EXTENSIONS.rst

@@ -0,0 +1,8 @@
+CMAKE_CXX_EXTENSIONS
+--------------------
+
+Default value for ``CXX_EXTENSIONS`` property of targets.
+
+This variable is used to initialize the :prop_tgt:`CXX_EXTENSIONS`
+property on all targets.  See that target property for additional
+information.

+ 8 - 0
Help/variable/CMAKE_CXX_STANDARD.rst

@@ -0,0 +1,8 @@
+CMAKE_CXX_STANDARD
+------------------
+
+Default value for ``CXX_STANDARD`` property of targets.
+
+This variable is used to initialize the :prop_tgt:`CXX_STANDARD`
+property on all targets.  See that target property for additional
+information.

+ 29 - 0
Source/cmLocalGenerator.cxx

@@ -1459,6 +1459,7 @@ void cmLocalGenerator::AddCompileOptions(
       this->AppendFlagEscape(flags, *i);
       }
     }
+  this->AddCompilerRequirementFlag(flags, target, lang);
 }
 
 //----------------------------------------------------------------------------
@@ -2128,6 +2129,34 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags,
     }
 }
 
+//----------------------------------------------------------------------------
+void cmLocalGenerator::
+AddCompilerRequirementFlag(std::string &flags, cmTarget* target,
+                           const std::string& lang)
+{
+  if (lang.empty())
+    {
+    return;
+    }
+  std::string stdProp = lang + "_STANDARD";
+  const char *standard = target->GetProperty(stdProp);
+  if (!standard)
+    {
+    return;
+    }
+  std::string extProp = lang + "_EXTENSIONS";
+  bool ext = target->GetPropertyAsBool(extProp);
+  std::string type = ext ? "EXTENSION" : "STANDARD";
+
+  std::string compile_option =
+            "CMAKE_" + lang + std::string(standard)
+                     + "_" + type + "_COMPILE_OPTION";
+  if (const char *opt = target->GetMakefile()->GetDefinition(compile_option))
+    {
+    this->AppendFlags(flags, opt);
+    }
+}
+
 static void AddVisibilityCompileOption(std::string &flags, cmTarget* target,
                                        cmLocalGenerator *lg,
                                        const std::string& lang)

+ 2 - 0
Source/cmLocalGenerator.h

@@ -149,6 +149,8 @@ public:
                                 const std::string& lang);
   void AddConfigVariableFlags(std::string& flags, const std::string& var,
                               const std::string& config);
+  void AddCompilerRequirementFlag(std::string &flags, cmTarget* target,
+                                  const std::string& lang);
   ///! Append flags to a string.
   virtual void AppendFlags(std::string& flags, const char* newFlags);
   virtual void AppendFlagEscape(std::string& flags,

+ 2 - 0
Source/cmTarget.cxx

@@ -307,6 +307,8 @@ void cmTarget::SetMakefile(cmMakefile* mf)
     this->SetPropertyDefault("MACOSX_BUNDLE", 0);
     this->SetPropertyDefault("MACOSX_RPATH", 0);
     this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0);
+    this->SetPropertyDefault("CXX_STANDARD", 0);
+    this->SetPropertyDefault("CXX_EXTENSIONS", 0);
     }
 
   // Collect the set of configuration types.

+ 13 - 0
Tests/CMakeLists.txt

@@ -283,6 +283,19 @@ if(BUILD_TESTING)
     ADD_TEST_MACRO(ConfigSources ConfigSources)
   endif()
   ADD_TEST_MACRO(SourcesProperty SourcesProperty)
+  if(CMAKE_CXX_COMPILER_ID STREQUAL GNU
+      AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
+    set(runCxxDialectTest 1)
+  endif()
+  if(CMAKE_CXX_COMPILER_ID STREQUAL Clang
+        AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.9)
+    if(NOT APPLE OR POLICY CMP0025)
+      set(runCxxDialectTest 1)
+    endif()
+  endif()
+  if(runCxxDialectTest)
+    ADD_TEST_MACRO(CxxDialect CxxDialect)
+  endif()
   set_tests_properties(EmptyLibrary PROPERTIES
     PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target: test")
   ADD_TEST_MACRO(CrossCompile CrossCompile)

+ 14 - 0
Tests/CxxDialect/CMakeLists.txt

@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 2.8.12)
+cmake_policy(SET CMP0025 NEW)
+project(CxxDialect)
+
+add_executable(use_typeof use_typeof.cxx)
+set_property(TARGET use_typeof PROPERTY CXX_STANDARD 98)
+set_property(TARGET use_typeof PROPERTY CXX_EXTENSIONS ON)
+
+add_executable(use_constexpr use_constexpr.cxx)
+set_property(TARGET use_constexpr PROPERTY CXX_STANDARD 11)
+
+add_executable(CxxDialect use_constexpr_and_typeof.cxx)
+set_property(TARGET CxxDialect PROPERTY CXX_STANDARD 11)
+set_property(TARGET CxxDialect PROPERTY CXX_EXTENSIONS ON)

+ 10 - 0
Tests/CxxDialect/use_constexpr.cxx

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

+ 11 - 0
Tests/CxxDialect/use_constexpr_and_typeof.cxx

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

+ 6 - 0
Tests/CxxDialect/use_typeof.cxx

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