Do not exclude include directories made implicit by CPATH
Entries of the `CPATH` environment variable are implicitly searched as
include directories by some C/C++ compilers. Since commit 5990ecb741
(Compute implicit include directories from compiler output, 2018-12-07,
v3.14.0-rc1~108^2) these entries are detected by CMake and included in
the `CMAKE_{C,CXX}_IMPLICIT_INCLUDE_DIRECTORIES` variables.
However, we should not exclude them from explicit specification via `-I`
or particularly `-isystem` because they are meant as user-specified
include directories that can be re-ordered without breaking compiler
builtin headers. In particular, we need explicit requests via
`include_directories` with the `SYSTEM` option to result in `-isystem`
so that third-party headers do not produce warnings.
Co-Author: Ben Boeckel <ben.boeckel@kitware.com>
Fixes: #19291
stage/master/nightly/2019/05/31
parent
f872033d75
commit
2d0b0e2b9d
|
@ -412,3 +412,11 @@ Changes made since CMake 3.14.0 include the following.
|
|||
incorrectly propagate usage requirements of those dependencies to
|
||||
dependents that link the static library. This has been fixed.
|
||||
The bug also existed in 3.13.0 through 3.13.4 and is fixed in 3.13.5.
|
||||
|
||||
3.14.5
|
||||
------
|
||||
|
||||
* Entries of the ``CPATH`` environment variable are no longer excluded
|
||||
from explicit use via :command:`include_directories` and
|
||||
:command:`target_include_directories` as they were in CMake 3.14.0
|
||||
through 3.14.4.
|
||||
|
|
|
@ -88,6 +88,19 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
|
|||
|
||||
this->ComputeObjectMaxPath();
|
||||
|
||||
// Canonicalize entries of the CPATH environment variable the same
|
||||
// way detection of CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES does.
|
||||
{
|
||||
std::vector<std::string> cpath;
|
||||
cmSystemTools::GetPath(cpath, "CPATH");
|
||||
for (std::string& cp : cpath) {
|
||||
if (cmSystemTools::FileIsFullPath(cp)) {
|
||||
cp = cmSystemTools::CollapseFullPath(cp);
|
||||
this->EnvCPATH.emplace(std::move(cp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> enabledLanguages =
|
||||
this->GetState()->GetEnabledLanguages();
|
||||
|
||||
|
@ -988,9 +1001,18 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
|
|||
}
|
||||
|
||||
// Checks if this is not an excluded (implicit) include directory.
|
||||
auto notExcluded = [&implicitSet, &implicitExclude](std::string const& dir) {
|
||||
return ((implicitSet.find(dir) == implicitSet.end()) &&
|
||||
(implicitExclude.find(dir) == implicitExclude.end()));
|
||||
auto notExcluded = [this, &implicitSet, &implicitExclude,
|
||||
&lang](std::string const& dir) {
|
||||
return (
|
||||
// Do not exclude directories that are not in an excluded set.
|
||||
((implicitSet.find(dir) == implicitSet.end()) &&
|
||||
(implicitExclude.find(dir) == implicitExclude.end()))
|
||||
// Do not exclude entries of the CPATH environment variable even though
|
||||
// they are implicitly searched by the compiler. They are meant to be
|
||||
// user-specified directories that can be re-ordered or converted to
|
||||
// -isystem without breaking real compiler builtin headers.
|
||||
|| ((lang == "C" || lang == "CXX") &&
|
||||
(this->EnvCPATH.find(dir) != this->EnvCPATH.end())));
|
||||
};
|
||||
|
||||
// Get the target-specific include directories.
|
||||
|
|
|
@ -429,6 +429,8 @@ protected:
|
|||
std::string::size_type ObjectPathMax;
|
||||
std::set<std::string> ObjectMaxPathViolations;
|
||||
|
||||
std::set<std::string> EnvCPATH;
|
||||
|
||||
typedef std::unordered_map<std::string, cmGeneratorTarget*>
|
||||
GeneratorTargetMap;
|
||||
GeneratorTargetMap GeneratorTargetSearchIndex;
|
||||
|
|
|
@ -3620,6 +3620,24 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
|
|||
--test-command IncludeDirectories)
|
||||
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/IncludeDirectories")
|
||||
|
||||
if(CMAKE_GENERATOR MATCHES "^((Unix|MSYS) Makefiles|Ninja)$" AND
|
||||
((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.4)
|
||||
OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
|
||||
OR (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")))
|
||||
add_test(IncludeDirectoriesCPATH ${CMAKE_CTEST_COMMAND}
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Tests/IncludeDirectoriesCPATH"
|
||||
"${CMake_BINARY_DIR}/Tests/IncludeDirectoriesCPATH"
|
||||
--build-two-config
|
||||
${build_generator_args}
|
||||
--build-project IncludeDirectoriesCPATH
|
||||
--build-options ${build_options})
|
||||
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/IncludeDirectoriesCPATH")
|
||||
set_tests_properties(IncludeDirectoriesCPATH
|
||||
PROPERTIES
|
||||
ENVIRONMENT "CPATH=${CMAKE_CURRENT_SOURCE_DIR}/IncludeDirectoriesCPATH/viacpath")
|
||||
endif()
|
||||
|
||||
add_test(InterfaceLinkLibraries ${CMAKE_CTEST_COMMAND}
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Tests/InterfaceLinkLibraries"
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
cmake_minimum_required (VERSION 3.14)
|
||||
project(IncludeDirectoriesCPATH CXX)
|
||||
message(STATUS "ENV{CPATH}: '$ENV{CPATH}'")
|
||||
message(STATUS "CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES: '${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}'")
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
check_cxx_compiler_flag(-Wunused-variable run_sys_includes_test)
|
||||
if(run_sys_includes_test)
|
||||
# The Bullseye wrapper appears to break the -isystem effect.
|
||||
execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE out ERROR_VARIABLE out)
|
||||
if("x${out}" MATCHES "Bullseye")
|
||||
set(run_sys_includes_test 0)
|
||||
endif()
|
||||
endif()
|
||||
if (NOT run_sys_includes_test)
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_library(consumer consumer.cpp)
|
||||
add_library(consumer_system consumer.cpp)
|
||||
target_compile_options(consumer_system PRIVATE -Werror=unused-variable)
|
||||
target_include_directories(consumer_system SYSTEM PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/viacpath")
|
|
@ -0,0 +1,6 @@
|
|||
#include "systemlib.h"
|
||||
|
||||
int consumer()
|
||||
{
|
||||
return systemlib();
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef SYSTEMLIB_H
|
||||
#define SYSTEMLIB_H
|
||||
|
||||
int systemlib()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unusedFunc()
|
||||
{
|
||||
int unused;
|
||||
return systemlib();
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue