From 017598a4443c19185dc245f3f0fcfceff9b98463 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 13 Feb 2019 09:45:36 -0500 Subject: macOS: Fix addition of /usr/include to default implicit include dirs In commit 1293ed8507 (ParseImplicitIncludeInfo: keep implicit incl. consistent when rerunning cmake, 2019-01-30, v3.14.0-rc1~26^2) the `Platform/UnixPaths` module was updated to add `/usr/include` to `CMAKE_{C,CXX,CUDA}_IMPLICIT_INCLUDE_DIRECTORIES` through an initialization variable used by `CMakeDetermineCompilerABI` instead of directly. This approach makes it only a default that can be overridden by detection of the implicit include directories really used by the compiler. The addition of `/usr/include` to default implicit include directories by the `Platform/Darwin` module needs the same update but was accidentally left out of the original commit. --- Modules/Platform/Darwin.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake index a73ffba..5590433 100644 --- a/Modules/Platform/Darwin.cmake +++ b/Modules/Platform/Darwin.cmake @@ -214,7 +214,7 @@ include(Platform/UnixPaths) if(_CMAKE_OSX_SYSROOT_PATH AND EXISTS ${_CMAKE_OSX_SYSROOT_PATH}/usr/include) list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${_CMAKE_OSX_SYSROOT_PATH}/usr) foreach(lang C CXX) - list(APPEND CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES ${_CMAKE_OSX_SYSROOT_PATH}/usr/include) + list(APPEND _CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES_INIT ${_CMAKE_OSX_SYSROOT_PATH}/usr/include) endforeach() endif() list(APPEND CMAKE_SYSTEM_PREFIX_PATH -- cgit v0.12 From 557b2d6e65038640d5016413e612e48691cff0d8 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 13 Feb 2019 09:23:31 -0500 Subject: Fix regression in -I/usr/include exclusion logic The change in commit 15ad830062 (Refactor exclusion of -I/usr/include to avoid per-language values, 2019-01-21, v3.14.0-rc1~108^2~4) caused the exclusion to apply to Fortran, but it was only meant for C, CXX, and CUDA. The purpose of the change was to prepare for the value of `CMAKE__IMPLICIT_INCLUDE_DIRECTORIES` to be computed from the actual compiler instead of hard-coded. We need to preserve exclusion of `-I/usr/include` if the compiler has any implicit include directory that looks intended to replace it, e.g. `/usr/include` on macOS. Fixes: #18914 --- Modules/Platform/UnixPaths.cmake | 5 ----- Source/cmLocalGenerator.cxx | 22 ++++++++++++++++------ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Modules/Platform/UnixPaths.cmake b/Modules/Platform/UnixPaths.cmake index 4ae4514..46c24bb 100644 --- a/Modules/Platform/UnixPaths.cmake +++ b/Modules/Platform/UnixPaths.cmake @@ -63,11 +63,6 @@ list(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES /lib /lib32 /lib64 /usr/lib /usr/lib32 /usr/lib64 ) -# Platform-wide directories to avoid adding via -I. -list(APPEND CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES - /usr/include - ) - # Default per-language values. These may be later replaced after # parsing the implicit directory information from compiler output. set(_CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES_INIT diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 252aa4c..b1115ea 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -939,12 +939,6 @@ std::vector> cmLocalGenerator::GetIncludeDirectoriesImplicit( // Raw list of implicit include directories std::vector impDirVec; - // Get platform-wide implicit directories. - if (const char* implicitIncludes = (this->Makefile->GetDefinition( - "CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES"))) { - cmSystemTools::ExpandListArgument(implicitIncludes, impDirVec); - } - // Load implicit include directories for this language. std::string key = "CMAKE_"; key += lang; @@ -953,6 +947,22 @@ std::vector> cmLocalGenerator::GetIncludeDirectoriesImplicit( cmSystemTools::ExpandListArgument(value, impDirVec); } + // The Platform/UnixPaths module used to hard-code /usr/include for C, CXX, + // and CUDA in CMAKE__IMPLICIT_INCLUDE_DIRECTORIES, but those + // variables are now computed. On macOS the /usr/include directory is + // inside the platform SDK so the computed value does not contain it + // directly. In this case adding -I/usr/include can hide SDK headers so we + // must still exclude it. + if ((lang == "C" || lang == "CXX" || lang == "CUDA") && + std::find(impDirVec.begin(), impDirVec.end(), "/usr/include") == + impDirVec.end() && + std::find_if(impDirVec.begin(), impDirVec.end(), + [](std::string const& d) { + return cmHasLiteralSuffix(d, "/usr/include"); + }) != impDirVec.end()) { + impDirVec.emplace_back("/usr/include"); + } + for (std::string const& i : impDirVec) { std::string imd = rootPath + i; cmSystemTools::ConvertToUnixSlashes(imd); -- cgit v0.12 From 2ad14ef4ea57c19f6cb4ed365e99a30be81eefe7 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 13 Feb 2019 09:22:41 -0500 Subject: cmAlgorithms: Add cmHasPrefix to match existing cmHasSuffix --- Source/cmAlgorithms.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h index 9e3efd3..d38b0d1 100644 --- a/Source/cmAlgorithms.h +++ b/Source/cmAlgorithms.h @@ -336,6 +336,14 @@ std::reverse_iterator cmMakeReverseIterator(Iter it) return std::reverse_iterator(it); } +inline bool cmHasPrefix(std::string const& str, std::string const& prefix) +{ + if (str.size() < prefix.size()) { + return false; + } + return str.compare(0, prefix.size(), prefix) == 0; +} + inline bool cmHasSuffix(const std::string& str, const std::string& suffix) { if (str.size() < suffix.size()) { -- cgit v0.12 From 6fc33829443ea3ef2dc8cc71c0a98b635bec6179 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 13 Feb 2019 09:27:24 -0500 Subject: Update logic for sysroot in detected implicit include directories Since commit 5990ecb741 (Compute implicit include directories from compiler output, 2018-12-07, v3.14.0-rc1~108^2) the values of the `CMAKE__IMPLICIT_INCLUDE_DIRECTORIES` variables are computed from a real compiler invocation. In this case the paths under the sysroot should already have the sysroot prefix so we should no longer have to add the sysroot prefix. However, it is also possible for project code to add its own paths to `CMAKE__IMPLICIT_INCLUDE_DIRECTORIES` without the sysroot prefix and expect the historical addition of the sysroot prefix to be preserved. Try to account for both cases by conditionally adding the sysroot prefix on implicit include directories that do not already have it. --- Source/cmLocalGenerator.cxx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index b1115ea..8090e00 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -935,6 +935,7 @@ std::vector> cmLocalGenerator::GetIncludeDirectoriesImplicit( } else { rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"); } + cmSystemTools::ConvertToUnixSlashes(rootPath); // Raw list of implicit include directories std::vector impDirVec; @@ -964,8 +965,11 @@ std::vector> cmLocalGenerator::GetIncludeDirectoriesImplicit( } for (std::string const& i : impDirVec) { - std::string imd = rootPath + i; + std::string imd = i; cmSystemTools::ConvertToUnixSlashes(imd); + if (!rootPath.empty() && !cmHasPrefix(imd, rootPath)) { + imd = rootPath + imd; + } if (implicitSet.insert(imd).second) { implicitDirs.emplace_back(std::move(imd)); } -- cgit v0.12