From 5b0cc0d803f6f7052b03d4aef51becd7a75a1093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= Date: Thu, 27 Jun 2019 12:19:11 +0200 Subject: [PATCH] Only include extra headers if they are not already in the search path This commit adds additional logic to only add the headers of LLVM, clang and rapidjson if they are not already in the compiler's default search path. The issue was, that adding the same folder via: target_include_directories(tgt SYSTEM ${foo}) results in the following invocation of gcc: gcc -isystem $foo ... which causes issues with libstdc++ shipped by gcc9. libstdc++ makes use of #include_next for some internal trickery, but that changes the way headers are resolved and causes compilation failures because standard headers are now suddenly missing. With this commit we now check each of the extra include directories if they are already in the compiler's search path. If they are, we don't add them and circumvent this issue. --- CMakeLists.txt | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index efca2ba9..47848e8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,8 +144,7 @@ set_property(SOURCE src/utils.cc APPEND PROPERTY COMPILE_DEFINITIONS ### Includes target_include_directories(ccls PRIVATE src) -target_include_directories(ccls SYSTEM PRIVATE - third_party ${LLVM_INCLUDE_DIRS} ${CLANG_INCLUDE_DIRS}) +target_include_directories(ccls SYSTEM PRIVATE third_party) if(USE_SYSTEM_RAPIDJSON) find_package(RapidJSON QUIET) @@ -153,7 +152,33 @@ endif() if(NOT RapidJSON_FOUND) set(RapidJSON_INCLUDE_DIRS third_party/rapidjson/include) endif() -target_include_directories(ccls SYSTEM PRIVATE ${RapidJSON_INCLUDE_DIRS}) + +# only add the include directories for LLVM, clang & rapidjson if they aren't in +# the default list of include directories (these are stored by cmake in +# CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES) +# +# Adding the same include directory twice with SYSTEM results these being +# included as -isystem, which causes issues with libstdc++ from gcc9 with their +# usage of #include_next<> +# see also: https://github.com/MaskRay/ccls/pull/417 +foreach(include_dir + ${LLVM_INCLUDE_DIRS} ${CLANG_INCLUDE_DIRS} ${RapidJSON_INCLUDE_DIRS}) + + # rapidjson's include dir is a relative path => normalize it + get_filename_component(include_dir_realpath ${include_dir} REALPATH) + set(dir_already_included FALSE) + + foreach(cxx_include_dir ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) + if("${cxx_include_dir}" STREQUAL "${include_dir_realpath}") + set(dir_already_included TRUE) + endif() + endforeach() + + if(NOT "${dir_already_included}") + target_include_directories(ccls SYSTEM PRIVATE ${include_dir}) + endif() +endforeach() + ### Install