mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-23 18:08:31 +08:00
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
This commit is contained in:
@@ -412,3 +412,11 @@ Changes made since CMake 3.14.0 include the following.
|
|||||||
incorrectly propagate usage requirements of those dependencies to
|
incorrectly propagate usage requirements of those dependencies to
|
||||||
dependents that link the static library. This has been fixed.
|
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.
|
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();
|
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 =
|
std::vector<std::string> enabledLanguages =
|
||||||
this->GetState()->GetEnabledLanguages();
|
this->GetState()->GetEnabledLanguages();
|
||||||
|
|
||||||
@@ -988,9 +1001,18 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Checks if this is not an excluded (implicit) include directory.
|
// Checks if this is not an excluded (implicit) include directory.
|
||||||
auto notExcluded = [&implicitSet, &implicitExclude](std::string const& dir) {
|
auto notExcluded = [this, &implicitSet, &implicitExclude,
|
||||||
return ((implicitSet.find(dir) == implicitSet.end()) &&
|
&lang](std::string const& dir) {
|
||||||
(implicitExclude.find(dir) == implicitExclude.end()));
|
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.
|
// Get the target-specific include directories.
|
||||||
|
@@ -429,6 +429,8 @@ protected:
|
|||||||
std::string::size_type ObjectPathMax;
|
std::string::size_type ObjectPathMax;
|
||||||
std::set<std::string> ObjectMaxPathViolations;
|
std::set<std::string> ObjectMaxPathViolations;
|
||||||
|
|
||||||
|
std::set<std::string> EnvCPATH;
|
||||||
|
|
||||||
typedef std::unordered_map<std::string, cmGeneratorTarget*>
|
typedef std::unordered_map<std::string, cmGeneratorTarget*>
|
||||||
GeneratorTargetMap;
|
GeneratorTargetMap;
|
||||||
GeneratorTargetMap GeneratorTargetSearchIndex;
|
GeneratorTargetMap GeneratorTargetSearchIndex;
|
||||||
|
@@ -3620,6 +3620,24 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
|
|||||||
--test-command IncludeDirectories)
|
--test-command IncludeDirectories)
|
||||||
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/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}
|
add_test(InterfaceLinkLibraries ${CMAKE_CTEST_COMMAND}
|
||||||
--build-and-test
|
--build-and-test
|
||||||
"${CMake_SOURCE_DIR}/Tests/InterfaceLinkLibraries"
|
"${CMake_SOURCE_DIR}/Tests/InterfaceLinkLibraries"
|
||||||
|
22
Tests/IncludeDirectoriesCPATH/CMakeLists.txt
Normal file
22
Tests/IncludeDirectoriesCPATH/CMakeLists.txt
Normal file
@@ -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")
|
6
Tests/IncludeDirectoriesCPATH/consumer.cpp
Normal file
6
Tests/IncludeDirectoriesCPATH/consumer.cpp
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include "systemlib.h"
|
||||||
|
|
||||||
|
int consumer()
|
||||||
|
{
|
||||||
|
return systemlib();
|
||||||
|
}
|
15
Tests/IncludeDirectoriesCPATH/viacpath/systemlib.h
Normal file
15
Tests/IncludeDirectoriesCPATH/viacpath/systemlib.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#ifndef SYSTEMLIB_H
|
||||||
|
#define SYSTEMLIB_H
|
||||||
|
|
||||||
|
int systemlib()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int unusedFunc()
|
||||||
|
{
|
||||||
|
int unused;
|
||||||
|
return systemlib();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user