From 4bafa3922e3773e5bcc6741994379455c7d1c0fc Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 12 Jul 2017 11:37:00 -0400 Subject: 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__STANDARD_INCLUDE_DIRECTORIES` incorrectly filters them by `CMAKE__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__IMPLICIT_INCLUDE_DIRECTORIES` so it worked in `CMAKE__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 --- Modules/Platform/Android-Common.cmake | 1 - Source/cmGeneratorTarget.cxx | 12 ------------ Source/cmLocalGenerator.cxx | 14 ++++++++++++++ Tests/RunCMake/Android/android_sysinc.c | 7 +++++++ Tests/RunCMake/Android/android_sysinc.cxx | 7 +++++++ Tests/RunCMake/Android/common.cmake | 16 ++++++++++++++++ Tests/RunCMake/Android/sysinc/dlfcn.h | 1 + 7 files changed, 45 insertions(+), 13 deletions(-) create mode 100644 Tests/RunCMake/Android/android_sysinc.c create mode 100644 Tests/RunCMake/Android/android_sysinc.cxx create mode 100644 Tests/RunCMake/Android/sysinc/dlfcn.h diff --git a/Modules/Platform/Android-Common.cmake b/Modules/Platform/Android-Common.cmake index 6360376..5faada3 100644 --- a/Modules/Platform/Android-Common.cmake +++ b/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() diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index b93442d..1802da4 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -2633,18 +2633,6 @@ std::vector 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::size_type const before = includes.size(); - cmSystemTools::ExpandListArgument(standardIncludes, includes); - for (std::vector::iterator i = includes.begin() + before; - i != includes.end(); ++i) { - cmSystemTools::ConvertToUnixSlashes(*i); - } - return includes; } diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 8e00303..5a062bc 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -916,6 +916,20 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector& 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::size_type const before = includes.size(); + cmSystemTools::ExpandListArgument(standardIncludes, includes); + for (std::vector::iterator i = includes.begin() + before; + i != includes.end(); ++i) { + cmSystemTools::ConvertToUnixSlashes(*i); + dirs.push_back(*i); + } + for (std::vector::const_iterator i = implicitDirs.begin(); i != implicitDirs.end(); ++i) { if (std::find(includes.begin(), includes.end(), *i) != includes.end()) { diff --git a/Tests/RunCMake/Android/android_sysinc.c b/Tests/RunCMake/Android/android_sysinc.c new file mode 100644 index 0000000..18d73db --- /dev/null +++ b/Tests/RunCMake/Android/android_sysinc.c @@ -0,0 +1,7 @@ +#include + +#ifndef NOT_SYSTEM_DLFCN_HEADER +#error "sysroot /usr/include appears too early" +#endif + +#include "android.c" diff --git a/Tests/RunCMake/Android/android_sysinc.cxx b/Tests/RunCMake/Android/android_sysinc.cxx new file mode 100644 index 0000000..5c5694b --- /dev/null +++ b/Tests/RunCMake/Android/android_sysinc.cxx @@ -0,0 +1,7 @@ +#include + +#ifndef NOT_SYSTEM_DLFCN_HEADER +#error "sysroot /usr/include appears too early" +#endif + +#include "android.cxx" diff --git a/Tests/RunCMake/Android/common.cmake b/Tests/RunCMake/Android/common.cmake index bef2428..015f202 100644 --- a/Tests/RunCMake/Android/common.cmake +++ b/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}) diff --git a/Tests/RunCMake/Android/sysinc/dlfcn.h b/Tests/RunCMake/Android/sysinc/dlfcn.h new file mode 100644 index 0000000..273306c --- /dev/null +++ b/Tests/RunCMake/Android/sysinc/dlfcn.h @@ -0,0 +1 @@ +#define NOT_SYSTEM_DLFCN_HEADER -- cgit v0.12