Просмотр исходного кода

Xcode: Obey SYSTEM keyword for includes (#15687)

CMake used to put all header search paths into HEADER_SEARCH_PATHS
attribute. Unfortunately this attribute does not support to declare
a search path as a system include.

As a hack one could add a -isystem /path to the cflags but then include
ordering is not deterministic. A better approach was chosen with this
patch by not filling HEADER_SEARCH_PATHS at all and to populate
the C, C++, and Fortran flags directly. The include paths used by
Xcode should be now identical to the ones used by Unix Makefiles and
Ninja generator.
Gregor Jasny 10 лет назад
Родитель
Сommit
93ac2a78d5

+ 1 - 0
Modules/CMakeSwiftInformation.cmake

@@ -13,6 +13,7 @@
 #  License text for the above reference.)
 
 set(CMAKE_Swift_OUTPUT_EXTENSION .o)
+set(CMAKE_INCLUDE_FLAG_Swift "-I")
 
 # Load compiler-specific information.
 if(CMAKE_Swift_COMPILER_ID)

+ 34 - 14
Source/cmGlobalXCodeGenerator.cxx

@@ -1907,23 +1907,40 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
 
   BuildObjectListOrString dirs(this, this->XcodeVersion >= 30);
   BuildObjectListOrString fdirs(this, this->XcodeVersion >= 30);
-  std::vector<std::string> includes;
-  this->CurrentLocalGenerator->GetIncludeDirectories(includes, gtgt, "C",
-                                                     configName);
   std::set<std::string> emitted;
   emitted.insert("/System/Library/Frameworks");
-  for (std::vector<std::string>::iterator i = includes.begin();
-       i != includes.end(); ++i) {
-    if (this->NameResolvesToFramework(i->c_str())) {
-      std::string frameworkDir = *i;
-      frameworkDir += "/../";
-      frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir);
-      if (emitted.insert(frameworkDir).second) {
-        fdirs.Add(this->XCodeEscapePath(frameworkDir));
+
+  if (this->XcodeVersion < 60) {
+    std::vector<std::string> includes;
+    this->CurrentLocalGenerator->GetIncludeDirectories(includes, gtgt, "C",
+                                                       configName);
+    for (std::vector<std::string>::iterator i = includes.begin();
+         i != includes.end(); ++i) {
+      if (this->NameResolvesToFramework(i->c_str())) {
+        std::string frameworkDir = *i;
+        frameworkDir += "/../";
+        frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir);
+        if (emitted.insert(frameworkDir).second) {
+          fdirs.Add(this->XCodeEscapePath(frameworkDir));
+        }
+      } else {
+        std::string incpath = this->XCodeEscapePath(*i);
+        dirs.Add(incpath);
+      }
+    }
+  } else {
+    for (std::set<std::string>::iterator li = languages.begin();
+         li != languages.end(); ++li) {
+      std::vector<std::string> includes;
+      this->CurrentLocalGenerator->GetIncludeDirectories(includes, gtgt, *li,
+                                                         configName);
+      std::string includeFlags = this->CurrentLocalGenerator->GetIncludeFlags(
+        includes, gtgt, *li, true, false, configName);
+
+      std::string& flags = cflags[*li];
+      if (!includeFlags.empty()) {
+        flags += " " + includeFlags;
       }
-    } else {
-      std::string incpath = this->XCodeEscapePath(*i);
-      dirs.Add(incpath);
     }
   }
   // Add framework search paths needed for linking.
@@ -2008,6 +2025,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
                                   this->CreateString(flags));
     } else if (*li == "C") {
       buildSettings->AddAttribute("OTHER_CFLAGS", this->CreateString(flags));
+    } else if (*li == "Swift") {
+      buildSettings->AddAttribute("OTHER_SWIFT_FLAGS",
+                                  this->CreateString(flags));
     }
   }
 

+ 3 - 1
Tests/IncludeDirectories/CMakeLists.txt

@@ -3,7 +3,9 @@ project(IncludeDirectories)
 
 if (((CMAKE_C_COMPILER_ID STREQUAL GNU AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.4)
     OR CMAKE_C_COMPILER_ID STREQUAL Clang OR CMAKE_C_COMPILER_ID STREQUAL AppleClang)
-    AND (CMAKE_GENERATOR STREQUAL "Unix Makefiles" OR CMAKE_GENERATOR STREQUAL "Ninja"))
+    AND (CMAKE_GENERATOR STREQUAL "Unix Makefiles"
+      OR CMAKE_GENERATOR STREQUAL "Ninja"
+      OR (CMAKE_GENERATOR STREQUAL "Xcode" AND NOT XCODE_VERSION VERSION_LESS 6.0)))
   include(CheckCXXCompilerFlag)
   check_cxx_compiler_flag(-Wunused-variable run_sys_includes_test)
   if(run_sys_includes_test)

+ 11 - 4
Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt

@@ -15,10 +15,17 @@ target_include_directories(upstream SYSTEM PUBLIC
 )
 
 add_library(config_specific INTERFACE)
-set(testConfig ${CMAKE_BUILD_TYPE})
-target_include_directories(config_specific SYSTEM INTERFACE
-  "$<$<CONFIG:${testConfig}>:${CMAKE_CURRENT_SOURCE_DIR}/config_specific>"
-)
+if(CMAKE_GENERATOR STREQUAL "Xcode")
+  # CMAKE_BUILD_TYPE does not work here for multi-config generators
+  target_include_directories(config_specific SYSTEM INTERFACE
+    "${CMAKE_CURRENT_SOURCE_DIR}/config_specific"
+  )
+else()
+  set(testConfig ${CMAKE_BUILD_TYPE})
+  target_include_directories(config_specific SYSTEM INTERFACE
+    "$<$<CONFIG:${testConfig}>:${CMAKE_CURRENT_SOURCE_DIR}/config_specific>"
+  )
+endif()
 
 add_library(consumer consumer.cpp)
 target_link_libraries(consumer upstream config_specific)