Procházet zdrojové kódy

Compiler/MSVC: use the `-external:I` flag for system includes

See: #17904
Ben Boeckel před 5 roky
rodič
revize
f29e1874ad

+ 7 - 0
Help/release/dev/msvc-isystem.rst

@@ -0,0 +1,7 @@
+msvc-isystem
+------------
+
+* The MSVC compilers learned to pass the ``-external:I`` flag for system
+  includes when using the :generator:`Ninja` and :generator:`NMake Makefiles`
+  generators. This became available as of Visual Studio 16.10 (toolchain
+  version 14.29.30037).

+ 6 - 0
Modules/Compiler/MSVC-C.cmake

@@ -63,3 +63,9 @@ endmacro()
 if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05)
   set(CMAKE_C_COMPILE_OPTIONS_JMC "-JMC")
 endif()
+
+# The `/external:I` flag was made non-experimental in 19.29.30036.3.
+if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29.30036.3)
+  set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-external:I ")
+  set(_CMAKE_INCLUDE_SYSTEM_FLAG_C_WARNING "-external:W0 ")
+endif ()

+ 6 - 0
Modules/Compiler/MSVC-CXX.cmake

@@ -79,3 +79,9 @@ endif()
 if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05)
   set(CMAKE_CXX_COMPILE_OPTIONS_JMC "-JMC")
 endif()
+
+# The `/external:I` flag was made non-experimental in 19.29.30036.3.
+if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29.30036.3)
+  set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-external:I ")
+  set(_CMAKE_INCLUDE_SYSTEM_FLAG_CXX_WARNING "-external:W0 ")
+endif ()

+ 8 - 0
Source/cmLocalGenerator.cxx

@@ -878,9 +878,12 @@ std::string cmLocalGenerator::GetIncludeFlags(
   // Support special system include flag if it is available and the
   // normal flag is repeated for each directory.
   cmProp sysIncludeFlag = nullptr;
+  cmProp sysIncludeFlagWarning = nullptr;
   if (repeatFlag) {
     sysIncludeFlag = this->Makefile->GetDefinition(
       cmStrCat("CMAKE_INCLUDE_SYSTEM_FLAG_", lang));
+    sysIncludeFlagWarning = this->Makefile->GetDefinition(
+      cmStrCat("_CMAKE_INCLUDE_SYSTEM_FLAG_", lang, "_WARNING"));
   }
 
   cmProp fwSearchFlag = this->Makefile->GetDefinition(
@@ -889,6 +892,7 @@ std::string cmLocalGenerator::GetIncludeFlags(
     cmStrCat("CMAKE_", lang, "_SYSTEM_FRAMEWORK_SEARCH_FLAG"));
 
   bool flagUsed = false;
+  bool sysIncludeFlagUsed = false;
   std::set<std::string> emitted;
 #ifdef __APPLE__
   emitted.insert("/System/Library/Frameworks");
@@ -915,6 +919,7 @@ std::string cmLocalGenerator::GetIncludeFlags(
       if (sysIncludeFlag && target &&
           target->IsSystemIncludeDirectory(i, config, lang)) {
         includeFlags << *sysIncludeFlag;
+        sysIncludeFlagUsed = true;
       } else {
         includeFlags << includeFlag;
       }
@@ -931,6 +936,9 @@ std::string cmLocalGenerator::GetIncludeFlags(
     }
     includeFlags << sep;
   }
+  if (sysIncludeFlagUsed && sysIncludeFlagWarning) {
+    includeFlags << *sysIncludeFlagWarning;
+  }
   std::string flags = includeFlags.str();
   // remove trailing separators
   if ((sep[0] != ' ') && !flags.empty() && flags.back() == sep[0]) {