diff --git a/clang/lib/Driver/ToolChains/Fuchsia.cpp b/clang/lib/Driver/ToolChains/Fuchsia.cpp --- a/clang/lib/Driver/ToolChains/Fuchsia.cpp +++ b/clang/lib/Driver/ToolChains/Fuchsia.cpp @@ -358,13 +358,31 @@ DriverArgs.hasArg(options::OPT_nostdincxx)) return; + const Driver &D = getDriver(); + std::string Target = getTripleString();; + + auto AddIncludePath = [&](StringRef Path) { + std::string Version = detectLibcxxVersion(Path); + if (Version.empty()) + return; + + // First add the per-target include path. + SmallString<128> TargetDir(Path); + llvm::sys::path::append(TargetDir, Target, "c++", Version); + if (getVFS().exists(TargetDir)) + addSystemInclude(DriverArgs, CC1Args, TargetDir); + + // Second add the generic one. + SmallString<128> Dir(Path); + llvm::sys::path::append(Dir, "c++", Version); + addSystemInclude(DriverArgs, CC1Args, Dir); + }; + switch (GetCXXStdlibType(DriverArgs)) { case ToolChain::CST_Libcxx: { - SmallString<128> P(getDriver().Dir); + SmallString<128> P(D.Dir); llvm::sys::path::append(P, "..", "include"); - std::string Version = detectLibcxxVersion(P); - llvm::sys::path::append(P, "c++", Version); - addSystemInclude(DriverArgs, CC1Args, P.str()); + AddIncludePath(P); break; } diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -2900,14 +2900,25 @@ void Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { + const Driver &D = getDriver(); + std::string SysRoot = computeSysRoot(); + std::string Target = getTripleString(); + auto AddIncludePath = [&](std::string Path) { std::string Version = detectLibcxxVersion(Path); - std::string IncludePath = Path + "/c++/" + Version; - if (Version.empty() || !getVFS().exists(IncludePath)) + if (Version.empty()) return false; - addSystemInclude(DriverArgs, CC1Args, IncludePath); + + // First add the per-target include path if it exists. + std::string TargetDir = Path + "/" + Target + "/c++/" + Version; + if (D.getVFS().exists(TargetDir)) + addSystemInclude(DriverArgs, CC1Args, TargetDir); + + // Second add the generic one. + addSystemInclude(DriverArgs, CC1Args, Path + "/c++/" + Version); return true; }; + // Android never uses the libc++ headers installed alongside the toolchain, // which are generally incompatible with the NDK libraries anyway. if (!getTriple().isAndroid()) @@ -2916,7 +2927,6 @@ // If this is a development, non-installed, clang, libcxx will // not be found at ../include/c++ but it likely to be found at // one of the following two locations: - std::string SysRoot = computeSysRoot(); if (AddIncludePath(SysRoot + "/usr/local/include")) return; if (AddIncludePath(SysRoot + "/usr/include")) diff --git a/clang/test/Driver/Inputs/basic_fuchsia_tree/include/aarch64-unknown-fuchsia/c++/v1/.keep b/clang/test/Driver/Inputs/basic_fuchsia_tree/include/aarch64-unknown-fuchsia/c++/v1/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/basic_fuchsia_tree/include/riscv64-unknown-fuchsia/c++/v1/.keep b/clang/test/Driver/Inputs/basic_fuchsia_tree/include/riscv64-unknown-fuchsia/c++/v1/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/basic_fuchsia_tree/include/x86_64-unknown-fuchsia/c++/v1/.keep b/clang/test/Driver/Inputs/basic_fuchsia_tree/include/x86_64-unknown-fuchsia/c++/v1/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/basic_linux_libcxx_tree/usr/include/x86_64-unknown-linux-gnu/c++/v1/.keep b/clang/test/Driver/Inputs/basic_linux_libcxx_tree/usr/include/x86_64-unknown-linux-gnu/c++/v1/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/basic_linux_libcxxv2_tree/usr/include/x86_64-unknown-linux-gnu/c++/v2/.keep b/clang/test/Driver/Inputs/basic_linux_libcxxv2_tree/usr/include/x86_64-unknown-linux-gnu/c++/v2/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/basic_linux_libstdcxx_libcxxv2_tree/usr/include/x86_64-unknown-linux-gnu/c++/v2/.keep b/clang/test/Driver/Inputs/basic_linux_libstdcxx_libcxxv2_tree/usr/include/x86_64-unknown-linux-gnu/c++/v2/.keep new file mode 100644 diff --git a/clang/test/Driver/fuchsia.cpp b/clang/test/Driver/fuchsia.cpp --- a/clang/test/Driver/fuchsia.cpp +++ b/clang/test/Driver/fuchsia.cpp @@ -20,6 +20,9 @@ // CHECK-NOT: "-fno-use-init-array" // CHECK: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-X86_64: "-internal-isystem" "{{.*[/\\]}}include{{/|\\\\}}x86_64-unknown-fuchsia{{/|\\\\}}c++{{/|\\\\}}v1" +// CHECK-AARCH64: "-internal-isystem" "{{.*[/\\]}}include{{/|\\\\}}aarch64-unknown-fuchsia{{/|\\\\}}c++{{/|\\\\}}v1" +// CHECK-RISCV64: "-internal-isystem" "{{.*[/\\]}}include{{/|\\\\}}riscv64-unknown-fuchsia{{/|\\\\}}c++{{/|\\\\}}v1" // CHECK: "-internal-isystem" "{{.*[/\\]}}include{{/|\\\\}}c++{{/|\\\\}}v1" // CHECK: "-internal-externc-isystem" "[[SYSROOT]]{{/|\\\\}}include" // CHECK: {{.*}}ld.lld{{.*}}" "-z" "now" "-z" "rodynamic" "-z" "separate-loadable-segments" diff --git a/clang/test/Driver/linux-header-search.cpp b/clang/test/Driver/linux-header-search.cpp --- a/clang/test/Driver/linux-header-search.cpp +++ b/clang/test/Driver/linux-header-search.cpp @@ -13,6 +13,7 @@ // RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-SYSROOT %s // CHECK-BASIC-LIBCXX-SYSROOT: "{{[^"]*}}clang{{[^"]*}}" "-cc1" // CHECK-BASIC-LIBCXX-SYSROOT: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-BASIC-LIBCXX-SYSROOT: "-internal-isystem" "[[SYSROOT]]/usr/include/x86_64-unknown-linux-gnu/c++/v1" // CHECK-BASIC-LIBCXX-SYSROOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" // CHECK-BASIC-LIBCXX-SYSROOT: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ @@ -25,6 +26,7 @@ // RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-INSTALL %s // CHECK-BASIC-LIBCXX-INSTALL: "{{[^"]*}}clang{{[^"]*}}" "-cc1" // CHECK-BASIC-LIBCXX-INSTALL: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-BASIC-LIBCXX-INSTALL: "-internal-isystem" "[[SYSROOT]]/usr/bin/../include/x86_64-unknown-linux-gnu/c++/v1" // CHECK-BASIC-LIBCXX-INSTALL: "-internal-isystem" "[[SYSROOT]]/usr/bin/../include/c++/v1" // CHECK-BASIC-LIBCXX-INSTALL: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // @@ -38,6 +40,7 @@ // RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBCXXV2-SYSROOT %s // CHECK-BASIC-LIBCXXV2-SYSROOT: "{{[^"]*}}clang{{[^"]*}}" "-cc1" // CHECK-BASIC-LIBCXXV2-SYSROOT: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-BASIC-LIBCXXV2-SYSROOT: "-internal-isystem" "[[SYSROOT]]/usr/include/x86_64-unknown-linux-gnu/c++/v2" // CHECK-BASIC-LIBCXXV2-SYSROOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v2" // CHECK-BASIC-LIBCXXV2-SYSROOT: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ @@ -50,6 +53,7 @@ // RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBCXXV2-INSTALL %s // CHECK-BASIC-LIBCXXV2-INSTALL: "{{[^"]*}}clang{{[^"]*}}" "-cc1" // CHECK-BASIC-LIBCXXV2-INSTALL: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-BASIC-LIBCXXV2-INSTALL: "-internal-isystem" "[[SYSROOT]]/usr/bin/../include/x86_64-unknown-linux-gnu/c++/v2" // CHECK-BASIC-LIBCXXV2-INSTALL: "-internal-isystem" "[[SYSROOT]]/usr/bin/../include/c++/v2" // CHECK-BASIC-LIBCXXV2-INSTALL: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // @@ -64,6 +68,7 @@ // RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBSTDCXX-LIBCXXV2-SYSROOT %s // CHECK-BASIC-LIBSTDCXX-LIBCXXV2-SYSROOT: "{{[^"]*}}clang{{[^"]*}}" "-cc1" // CHECK-BASIC-LIBSTDCXX-LIBCXXV2-SYSROOT: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-BASIC-LIBSTDCXX-LIBCXXV2-SYSROOT: "-internal-isystem" "[[SYSROOT]]/usr/include/x86_64-unknown-linux-gnu/c++/v2" // CHECK-BASIC-LIBSTDCXX-LIBCXXV2-SYSROOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v2" // CHECK-BASIC-LIBSTDCXX-LIBCXXV2-SYSROOT: "-internal-isystem" "[[SYSROOT]]/usr/local/include" diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -408,7 +408,10 @@ if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1") + set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LLVM_BINARY_DIR}/include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1") set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}) + set(LIBCXX_INSTALL_INCLUDE_DIR "include/c++/v1") + set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1") if(LIBCXX_LIBDIR_SUBDIR) string(APPEND LIBCXX_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR}) string(APPEND LIBCXX_INSTALL_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR}) @@ -416,11 +419,17 @@ elseif(LLVM_LIBRARY_OUTPUT_INTDIR) set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}) set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1") + set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LIBCXX_GENERATED_INCLUDE_DIR}") set(LIBCXX_INSTALL_LIBRARY_DIR lib${LIBCXX_LIBDIR_SUFFIX}) + set(LIBCXX_INSTALL_INCLUDE_DIR "include/c++/v1") + set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${LIBCXX_INSTALL_INCLUDE_DIR}") else() set(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX}) set(LIBCXX_GENERATED_INCLUDE_DIR "${CMAKE_BINARY_DIR}/include/c++/v1") + set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LIBCXX_GENERATED_INCLUDE_DIR}") set(LIBCXX_INSTALL_LIBRARY_DIR lib${LIBCXX_LIBDIR_SUFFIX}) + set(LIBCXX_INSTALL_INCLUDE_DIR "include/c++/v1") + set(LIBCXX_INSTALL_INCLUDE_TARGET_DIR "${LIBCXX_INSTALL_INCLUDE_DIR}") endif() file(MAKE_DIRECTORY "${LIBCXX_BINARY_INCLUDE_DIR}") diff --git a/libcxx/benchmarks/CMakeLists.txt b/libcxx/benchmarks/CMakeLists.txt --- a/libcxx/benchmarks/CMakeLists.txt +++ b/libcxx/benchmarks/CMakeLists.txt @@ -15,6 +15,10 @@ -Wl,-rpath,${LIBCXX_LIBRARY_DIR} ${SANITIZER_FLAGS} ) +if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) + list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS + -isystem "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}") +endif() if (DEFINED LIBCXX_CXX_ABI_LIBRARY_PATH) list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS -L${LIBCXX_CXX_ABI_LIBRARY_PATH} diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -209,9 +209,9 @@ wctype.h ) -configure_file("__config_site.in" "${LIBCXX_GENERATED_INCLUDE_DIR}/__config_site" @ONLY) +configure_file("__config_site.in" "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site" @ONLY) -set(_all_includes "${LIBCXX_GENERATED_INCLUDE_DIR}/__config_site") +set(_all_includes "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site") foreach(f ${files}) set(src "${CMAKE_CURRENT_SOURCE_DIR}/${f}") set(dst "${LIBCXX_GENERATED_INCLUDE_DIR}/${f}") @@ -228,24 +228,26 @@ add_dependencies(cxx-headers generate-cxx-headers ${LIBCXX_CXX_ABI_HEADER_TARGET}) # TODO: Use target_include_directories once we figure out why that breaks the runtimes build if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" OR "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC") - target_compile_options(cxx-headers INTERFACE /I "${LIBCXX_GENERATED_INCLUDE_DIR}") + target_compile_options(cxx-headers INTERFACE /I "${LIBCXX_GENERATED_INCLUDE_DIR}" + INTERFACE /I "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}") else() - target_compile_options(cxx-headers INTERFACE -I "${LIBCXX_GENERATED_INCLUDE_DIR}") + target_compile_options(cxx-headers INTERFACE -I${LIBCXX_GENERATED_INCLUDE_DIR} + INTERFACE -I${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}) endif() if (LIBCXX_INSTALL_HEADERS) foreach(file ${files}) get_filename_component(dir ${file} DIRECTORY) install(FILES ${file} - DESTINATION include/c++/v1/${dir} + DESTINATION ${LIBCXX_INSTALL_INCLUDE_DIR}/${dir} COMPONENT cxx-headers PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ ) endforeach() # Install the generated __config_site. - install(FILES ${LIBCXX_GENERATED_INCLUDE_DIR}/__config_site - DESTINATION include/c++/v1 + install(FILES ${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site + DESTINATION ${LIBCXX_INSTALL_INCLUDE_TARGET_DIR} PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT cxx-headers) diff --git a/libcxx/utils/libcxx/test/config.py b/libcxx/utils/libcxx/test/config.py --- a/libcxx/utils/libcxx/test/config.py +++ b/libcxx/utils/libcxx/test/config.py @@ -354,6 +354,11 @@ self.cxx.compile_flags += ['-nostdinc++'] if not os.path.isdir(cxx_headers): self.lit_config.fatal("cxx_headers='{}' is not a directory.".format(cxx_headers)) + cxx_target_headers = os.path.join( + os.path.dirname(os.path.dirname(cxx_headers)), + self.get_lit_conf('target_triple', None), 'c++', 'v1') + if os.path.isdir(cxx_target_headers): + self.cxx.compile_flags += ['-I' + cxx_target_headers] self.cxx.compile_flags += ['-I' + cxx_headers] if self.libcxx_obj_root is not None: cxxabi_headers = os.path.join(self.libcxx_obj_root, 'include', diff --git a/libcxxabi/test/libcxxabi/test/config.py b/libcxxabi/test/libcxxabi/test/config.py --- a/libcxxabi/test/libcxxabi/test/config.py +++ b/libcxxabi/test/libcxxabi/test/config.py @@ -69,6 +69,11 @@ if not os.path.isdir(cxx_headers): self.lit_config.fatal("cxx_headers='%s' is not a directory." % cxx_headers) + cxx_target_headers = os.path.join( + os.path.dirname(os.path.dirname(cxx_headers)), + self.get_lit_conf('target_triple', None), 'c++', 'v1') + if os.path.isdir(cxx_target_headers): + self.cxx.compile_flags += ['-I' + cxx_target_headers] self.cxx.compile_flags += ['-I' + cxx_headers] libcxxabi_headers = self.get_lit_conf(