Browse Source

Android: Always add standard include directories last

The logic added in commit v3.6.0-rc1~30^2 (Add a variable to specify
language-wide system include directories, 2016-05-24) to use
`CMAKE_<LANG>_STANDARD_INCLUDE_DIRECTORIES` incorrectly filters them by
`CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES`.  Rather than recognizing
this, commit v3.8.0-rc1~60^2 (Android: Pass sysroot include directory
explicitly, 2017-01-20) worked around the problem by incorrectly
removing `/usr/include` from `CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES`
so it worked in `CMAKE_<LANG>_STANDARD_INCLUDE_DIRECTORIES`.

By not filtering out `/usr/include` from user-specified include
directories, we allow the code

    include_directories(${CMAKE_SYSROOT}/usr/include)

to place the include directory too early on the command line.

Fix support for standard include directories to not be filtered by
implicit include directories, and do not remove `/usr/include` from the
list of implicit include directories for Android builds.  Add a test
case to verify that an explicit `/usr/include` is ignored in favor
of the standard directory at the end.

Fixes: #17059
Brad King 8 years ago
parent
commit
4bafa3922e

+ 0 - 1
Modules/Platform/Android-Common.cmake

@@ -168,6 +168,5 @@ macro(__android_compiler_common lang)
     else()
       list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES "${CMAKE_SYSROOT}/usr/include")
     endif()
-    list(REMOVE_ITEM CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES "/usr/include")
   endif()
 endmacro()

+ 0 - 12
Source/cmGeneratorTarget.cxx

@@ -2633,18 +2633,6 @@ std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(
 
   cmDeleteAll(linkInterfaceIncludeDirectoriesEntries);
 
-  // Add standard include directories for this language.
-  std::string const standardIncludesVar =
-    "CMAKE_" + lang + "_STANDARD_INCLUDE_DIRECTORIES";
-  std::string const standardIncludes =
-    this->Makefile->GetSafeDefinition(standardIncludesVar);
-  std::vector<std::string>::size_type const before = includes.size();
-  cmSystemTools::ExpandListArgument(standardIncludes, includes);
-  for (std::vector<std::string>::iterator i = includes.begin() + before;
-       i != includes.end(); ++i) {
-    cmSystemTools::ConvertToUnixSlashes(*i);
-  }
-
   return includes;
 }
 

+ 14 - 0
Source/cmLocalGenerator.cxx

@@ -916,6 +916,20 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
     }
   }
 
+  // Add standard include directories for this language.
+  // We do not filter out implicit directories here.
+  std::string const standardIncludesVar =
+    "CMAKE_" + lang + "_STANDARD_INCLUDE_DIRECTORIES";
+  std::string const standardIncludes =
+    this->Makefile->GetSafeDefinition(standardIncludesVar);
+  std::vector<std::string>::size_type const before = includes.size();
+  cmSystemTools::ExpandListArgument(standardIncludes, includes);
+  for (std::vector<std::string>::iterator i = includes.begin() + before;
+       i != includes.end(); ++i) {
+    cmSystemTools::ConvertToUnixSlashes(*i);
+    dirs.push_back(*i);
+  }
+
   for (std::vector<std::string>::const_iterator i = implicitDirs.begin();
        i != implicitDirs.end(); ++i) {
     if (std::find(includes.begin(), includes.end(), *i) != includes.end()) {

+ 7 - 0
Tests/RunCMake/Android/android_sysinc.c

@@ -0,0 +1,7 @@
+#include <dlfcn.h>
+
+#ifndef NOT_SYSTEM_DLFCN_HEADER
+#error "sysroot /usr/include appears too early"
+#endif
+
+#include "android.c"

+ 7 - 0
Tests/RunCMake/Android/android_sysinc.cxx

@@ -0,0 +1,7 @@
+#include <dlfcn.h>
+
+#ifndef NOT_SYSTEM_DLFCN_HEADER
+#error "sysroot /usr/include appears too early"
+#endif
+
+#include "android.cxx"

+ 16 - 0
Tests/RunCMake/Android/common.cmake

@@ -92,3 +92,19 @@ if(CMAKE_ANDROID_ARCH_ABI STREQUAL "armeabi-v7a")
 endif()
 add_executable(android_c android.c)
 add_executable(android_cxx android.cxx)
+
+# Test that an explicit /usr/include is ignored in favor of
+# appearing as a standard include directory at the end.
+set(sysinc_dirs)
+if(CMAKE_ANDROID_NDK)
+  if(NOT CMAKE_ANDROID_NDK_DEPRECATED_HEADERS)
+    list(APPEND sysinc_dirs ${CMAKE_SYSROOT_COMPILE}/usr/include)
+  else()
+    list(APPEND sysinc_dirs ${CMAKE_SYSROOT}/usr/include)
+  endif()
+endif()
+list(APPEND sysinc_dirs ${CMAKE_CURRENT_SOURCE_DIR}/sysinc)
+add_executable(android_sysinc_c android_sysinc.c)
+target_include_directories(android_sysinc_c SYSTEM PRIVATE ${sysinc_dirs})
+add_executable(android_sysinc_cxx android_sysinc.cxx)
+target_include_directories(android_sysinc_cxx SYSTEM PRIVATE ${sysinc_dirs})

+ 1 - 0
Tests/RunCMake/Android/sysinc/dlfcn.h

@@ -0,0 +1 @@
+#define NOT_SYSTEM_DLFCN_HEADER