Forráskód Böngészése

cmTarget: Add CXX_STANDARD_REQUIRED to control decay.

Stephen Kelly 11 éve
szülő
commit
205215fb8a
34 módosított fájl, 152 hozzáadás és 1 törlés
  1. 1 0
      Help/manual/cmake-properties.7.rst
  2. 1 0
      Help/manual/cmake-variables.7.rst
  3. 2 1
      Help/prop_tgt/CXX_STANDARD.rst
  4. 14 0
      Help/prop_tgt/CXX_STANDARD_REQUIRED.rst
  5. 8 0
      Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst
  6. 20 0
      Source/cmLocalGenerator.cxx
  7. 1 0
      Source/cmTarget.cxx
  8. 3 0
      Tests/CompileFeatures/CMakeLists.txt
  9. 1 0
      Tests/RunCMake/CompileFeatures/RequireCXX11-result.txt
  10. 3 0
      Tests/RunCMake/CompileFeatures/RequireCXX11-stderr.txt
  11. 4 0
      Tests/RunCMake/CompileFeatures/RequireCXX11.cmake
  12. 1 0
      Tests/RunCMake/CompileFeatures/RequireCXX11Ext-result.txt
  13. 3 0
      Tests/RunCMake/CompileFeatures/RequireCXX11Ext-stderr.txt
  14. 5 0
      Tests/RunCMake/CompileFeatures/RequireCXX11Ext.cmake
  15. 1 0
      Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable-result.txt
  16. 3 0
      Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable-stderr.txt
  17. 5 0
      Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable.cmake
  18. 1 0
      Tests/RunCMake/CompileFeatures/RequireCXX11Variable-result.txt
  19. 3 0
      Tests/RunCMake/CompileFeatures/RequireCXX11Variable-stderr.txt
  20. 4 0
      Tests/RunCMake/CompileFeatures/RequireCXX11Variable.cmake
  21. 1 0
      Tests/RunCMake/CompileFeatures/RequireCXX98-result.txt
  22. 3 0
      Tests/RunCMake/CompileFeatures/RequireCXX98-stderr.txt
  23. 4 0
      Tests/RunCMake/CompileFeatures/RequireCXX98.cmake
  24. 1 0
      Tests/RunCMake/CompileFeatures/RequireCXX98Ext-result.txt
  25. 3 0
      Tests/RunCMake/CompileFeatures/RequireCXX98Ext-stderr.txt
  26. 5 0
      Tests/RunCMake/CompileFeatures/RequireCXX98Ext.cmake
  27. 1 0
      Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable-result.txt
  28. 3 0
      Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable-stderr.txt
  29. 5 0
      Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable.cmake
  30. 1 0
      Tests/RunCMake/CompileFeatures/RequireCXX98Variable-result.txt
  31. 3 0
      Tests/RunCMake/CompileFeatures/RequireCXX98Variable-stderr.txt
  32. 4 0
      Tests/RunCMake/CompileFeatures/RequireCXX98Variable.cmake
  33. 15 0
      Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake
  34. 19 0
      Tests/RunCMake/CompileFeatures/generate_feature_list.cmake

+ 1 - 0
Help/manual/cmake-properties.7.rst

@@ -110,6 +110,7 @@ Properties on Targets
    /prop_tgt/CONFIG_POSTFIX
    /prop_tgt/CXX_EXTENSIONS
    /prop_tgt/CXX_STANDARD
+   /prop_tgt/CXX_STANDARD_REQUIRED
    /prop_tgt/DEBUG_POSTFIX
    /prop_tgt/DEFINE_SYMBOL
    /prop_tgt/EchoString

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

@@ -260,6 +260,7 @@ Variables for Languages
    /variable/CMAKE_CXX_COMPILE_FEATURES
    /variable/CMAKE_CXX_EXTENSIONS
    /variable/CMAKE_CXX_STANDARD
+   /variable/CMAKE_CXX_STANDARD_REQUIRED
    /variable/CMAKE_Fortran_MODDIR_DEFAULT
    /variable/CMAKE_Fortran_MODDIR_FLAG
    /variable/CMAKE_Fortran_MODOUT_FLAG

+ 2 - 1
Help/prop_tgt/CXX_STANDARD.rst

@@ -19,7 +19,8 @@ means that using:
 
 with a compiler which does not support ``-std=c++11`` or an equivalent
 flag will not result in an error or warning, but will instead add the
-``-std=c++98`` flag if supported.
+``-std=c++98`` flag if supported.  This "decay" behavior may be controlled
+with the :prop_tgt:`CXX_STANDARD_REQUIRED` target property.
 
 This property is initialized by the value of
 the :variable:`CMAKE_CXX_STANDARD` variable if it is set when a target

+ 14 - 0
Help/prop_tgt/CXX_STANDARD_REQUIRED.rst

@@ -0,0 +1,14 @@
+CXX_STANDARD_REQUIRED
+---------------------
+
+Boolean describing whether the value of :prop_tgt:`CXX_STANDARD` is a requirement.
+
+If this property is set to ``ON``, then the value of the
+:prop_tgt:`CXX_STANDARD` target property is treated as a requirement.  If this
+property is ``OFF`` or unset, the :prop_tgt:`CXX_STANDARD` target property is
+treated as optional and may "decay" to a previous standard if the requested is
+not available.
+
+This property is initialized by the value of
+the :variable:`CMAKE_CXX_STANDARD_REQUIRED` variable if it is set when a
+target is created.

+ 8 - 0
Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst

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

+ 20 - 0
Source/cmLocalGenerator.cxx

@@ -2161,6 +2161,26 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget* target,
   bool ext = target->GetPropertyAsBool(extProp);
   std::string type = ext ? "EXTENSION" : "STANDARD";
 
+  if (target->GetPropertyAsBool(lang + "_STANDARD_REQUIRED"))
+    {
+    std::string option_flag =
+              "CMAKE_" + lang + standardProp
+                      + "_" + type + "_COMPILE_OPTION";
+
+    const char *opt = target->GetMakefile()->GetDefinition(option_flag);
+    if (!opt)
+      {
+      cmOStringStream e;
+      e << "Target \"" << target->GetName() << "\" requires the language "
+           "dialect \"" << lang << standardProp << "\" "
+        << (ext ? "(with compiler extensions)" : "") << ", but CMake "
+           "does not know the compile flags to use to enable it.";
+      this->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
+      }
+    this->AppendFlags(flags, opt);
+    return;
+    }
+
   static std::map<std::string, std::vector<std::string> > langStdMap;
   if (langStdMap.empty())
     {

+ 1 - 0
Source/cmTarget.cxx

@@ -315,6 +315,7 @@ void cmTarget::SetMakefile(cmMakefile* mf)
     this->SetPropertyDefault("MACOSX_RPATH", 0);
     this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0);
     this->SetPropertyDefault("CXX_STANDARD", 0);
+    this->SetPropertyDefault("CXX_STANDARD_REQUIRED", 0);
     this->SetPropertyDefault("CXX_EXTENSIONS", 0);
     }
 

+ 3 - 0
Tests/CompileFeatures/CMakeLists.txt

@@ -31,6 +31,9 @@ add_executable(CompileFeatures main.cpp)
 set_property(TARGET CompileFeatures
   PROPERTY COMPILE_FEATURES "cxx_auto_type"
 )
+set_property(TARGET CompileFeatures
+  PROPERTY CXX_STANDARD_REQUIRED TRUE
+)
 
 add_executable(GenexCompileFeatures main.cpp)
 set_property(TARGET GenexCompileFeatures

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

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

+ 3 - 0
Tests/RunCMake/CompileFeatures/RequireCXX11-stderr.txt

@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+  Target "foo" requires the language dialect "CXX11" , but CMake does not
+  know the compile flags to use to enable it.

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

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

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

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

+ 3 - 0
Tests/RunCMake/CompileFeatures/RequireCXX11Ext-stderr.txt

@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+  Target "foo" requires the language dialect "CXX11" \(with compiler
+  extensions\), but CMake does not know the compile flags to use to enable it.

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

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

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

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

+ 3 - 0
Tests/RunCMake/CompileFeatures/RequireCXX11ExtVariable-stderr.txt

@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+  Target "foo" requires the language dialect "CXX11" \(with compiler
+  extensions\), but CMake does not know the compile flags to use to enable it.

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

@@ -0,0 +1,5 @@
+
+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-result.txt

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

+ 3 - 0
Tests/RunCMake/CompileFeatures/RequireCXX11Variable-stderr.txt

@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+  Target "foo" requires the language dialect "CXX11" , but CMake does not
+  know the compile flags to use to enable it.

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

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

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

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

+ 3 - 0
Tests/RunCMake/CompileFeatures/RequireCXX98-stderr.txt

@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+  Target "foo" requires the language dialect "CXX98" , but CMake does not
+  know the compile flags to use to enable it.

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

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

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

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

+ 3 - 0
Tests/RunCMake/CompileFeatures/RequireCXX98Ext-stderr.txt

@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+  Target "foo" requires the language dialect "CXX98" \(with compiler
+  extensions\), but CMake does not know the compile flags to use to enable it.

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

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

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

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

+ 3 - 0
Tests/RunCMake/CompileFeatures/RequireCXX98ExtVariable-stderr.txt

@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+  Target "foo" requires the language dialect "CXX98" \(with compiler
+  extensions\), but CMake does not know the compile flags to use to enable it.

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

@@ -0,0 +1,5 @@
+
+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-result.txt

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

+ 3 - 0
Tests/RunCMake/CompileFeatures/RequireCXX98Variable-stderr.txt

@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+  Target "foo" requires the language dialect "CXX98" , but CMake does not
+  know the compile flags to use to enable it.

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

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

+ 15 - 0
Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake

@@ -18,3 +18,18 @@ if (NOT FEATURES)
   run_cmake(NoSupportedCxxFeatures)
   run_cmake(NoSupportedCxxFeaturesGenex)
 endif()
+
+foreach(standard 98 11)
+  file(READ
+    "${RunCMake_BINARY_DIR}/generate_feature_list-build/cxx${standard}_flag.txt"
+    CXX${standard}_FLAG
+  )
+  if (CXX${standard}_FLAG STREQUAL NOTFOUND)
+    run_cmake(RequireCXX${standard})
+    run_cmake(RequireCXX${standard}Variable)
+  endif()
+  if (CXX${standard}EXT_FLAG STREQUAL NOTFOUND)
+    run_cmake(RequireCXX${standard}Ext)
+    run_cmake(RequireCXX${standard}ExtVariable)
+  endif()
+endforeach()

+ 19 - 0
Tests/RunCMake/CompileFeatures/generate_feature_list.cmake

@@ -2,3 +2,22 @@
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/features.txt"
   "${CMAKE_CXX_COMPILE_FEATURES}"
 )
+
+foreach(standard 98 11)
+  set(CXX${standard}_FLAG NOTFOUND)
+  if (DEFINED CMAKE_CXX${standard}_STANDARD_COMPILE_OPTION)
+    set(CXX${standard}_FLAG ${CMAKE_CXX${standard}_STANDARD_COMPILE_OPTION})
+  endif()
+
+  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cxx${standard}_flag.txt"
+    "${CXX${standard}_FLAG}"
+  )
+  set(CXX${standard}EXT_FLAG NOTFOUND)
+  if (DEFINED CMAKE_CXX${standard}_EXTENSION_COMPILE_OPTION)
+    set(CXX${standard}EXT_FLAG ${CMAKE_CXX${standard}_EXTENSION_COMPILE_OPTION})
+  endif()
+
+  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cxx${standard}ext_flag.txt"
+    "${CXX${standard}EXT_FLAG}"
+  )
+endforeach()