Browse Source

VS: Add support for SYSTEM include directories

Fixes: #17904
Josiah Bills 3 years ago
parent
commit
7a2496daad

+ 4 - 0
Help/release/dev/vs-system-include.rst

@@ -0,0 +1,4 @@
+vs-system-include
+-----------------
+
+* :ref:`Visual Studio Generators` now support ``SYSTEM`` headers.

+ 37 - 6
Source/cmVisualStudio10TargetGenerator.cxx

@@ -3356,6 +3356,43 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
     }
   }
 
+  // Get includes for this target
+  if (!this->LangForClCompile.empty()) {
+    auto includeList = this->GetIncludes(configName, this->LangForClCompile);
+
+    auto sysIncludeFlag = this->Makefile->GetDefinition(
+      cmStrCat("CMAKE_INCLUDE_SYSTEM_FLAG_", this->LangForClCompile));
+
+    if (sysIncludeFlag) {
+      bool gotOneSys = false;
+      for (auto i : includeList) {
+        cmSystemTools::ConvertToUnixSlashes(i);
+        if (this->GeneratorTarget->IsSystemIncludeDirectory(
+              i, configName, this->LangForClCompile)) {
+          auto flag = cmTrimWhitespace(*sysIncludeFlag);
+          if (this->MSTools) {
+            cmSystemTools::ReplaceString(flag, "-external:I", "/external:I");
+          }
+          clOptions.AppendFlagString("AdditionalOptions",
+                                     cmStrCat(flag, " \"", i, '"'));
+          gotOneSys = true;
+        } else {
+          clOptions.AddInclude(i);
+        }
+      }
+
+      if (gotOneSys) {
+        if (auto sysIncludeFlagWarning = this->Makefile->GetDefinition(
+              cmStrCat("_CMAKE_INCLUDE_SYSTEM_FLAG_", this->LangForClCompile,
+                       "_WARNING"))) {
+          flags = cmStrCat(flags, ' ', *sysIncludeFlagWarning);
+        }
+      }
+    } else {
+      clOptions.AddIncludes(includeList);
+    }
+  }
+
   clOptions.Parse(flags);
   clOptions.Parse(defineFlags);
   std::vector<std::string> targetDefines;
@@ -3382,12 +3419,6 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
     clOptions.AppendFlag("DefineConstants", targetDefines);
   }
 
-  // Get includes for this target
-  if (!this->LangForClCompile.empty()) {
-    clOptions.AddIncludes(
-      this->GetIncludes(configName, this->LangForClCompile));
-  }
-
   if (this->MSTools) {
     clOptions.SetVerboseMakefile(
       this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));

+ 3 - 3
Tests/IncludeDirectories/CMakeLists.txt

@@ -11,11 +11,11 @@ if (((CMAKE_C_COMPILER_ID STREQUAL GNU AND CMAKE_C_COMPILER_VERSION VERSION_GREA
     OR CMAKE_C_COMPILER_ID STREQUAL AppleClang
     OR CMAKE_C_COMPILER_ID STREQUAL LCC
     OR ("x${CMAKE_C_COMPILER_ID}" STREQUAL "xMSVC" AND
-       CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "19.29.30036.3" AND
-       NOT CMAKE_GENERATOR MATCHES "Visual Studio")) # No support for VS generators yet.
+       CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "19.29.30036.3"))
     AND (CMAKE_GENERATOR STREQUAL "Unix Makefiles"
       OR CMAKE_GENERATOR STREQUAL "Ninja"
-      OR (CMAKE_GENERATOR STREQUAL "Xcode" AND NOT XCODE_VERSION VERSION_LESS 6.0)))
+      OR (CMAKE_GENERATOR STREQUAL "Xcode" AND NOT XCODE_VERSION VERSION_LESS 6.0)
+      OR CMAKE_GENERATOR MATCHES "Visual Studio"))
   if ("x${CMAKE_C_COMPILER_ID}" STREQUAL "xMSVC")
     set(run_sys_includes_test 1)
   else ()

+ 2 - 1
Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt

@@ -23,7 +23,8 @@ target_include_directories(upstream SYSTEM PUBLIC
 )
 
 add_library(config_specific INTERFACE)
-if(CMAKE_GENERATOR STREQUAL "Xcode")
+get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(isMultiConfig)
   # CMAKE_BUILD_TYPE does not work here for multi-config generators
   target_include_directories(config_specific SYSTEM INTERFACE
     "${CMAKE_CURRENT_SOURCE_DIR}/config_specific"