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,17 +358,36 @@ void Fuchsia::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { + const Driver &D = getDriver(); + if (DriverArgs.hasArg(options::OPT_nostdlibinc) || DriverArgs.hasArg(options::OPT_nostdincxx)) return; + auto AddIncludePath = [&](StringRef Path) { + std::string Version = detectLibcxxVersion(Path); + if (Version.empty()) + return; + + SmallString<128> P; + + // First add the per-target include path. + P.assign(Path); + llvm::sys::path::append(P, getTriple().str(), "c++", Version); + if (getVFS().exists(P)) + addSystemInclude(DriverArgs, CC1Args, P); + + // Second add the generic one. + P.assign(Path); + llvm::sys::path::append(P, "c++", Version); + addSystemInclude(DriverArgs, CC1Args, P); + }; + 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 @@ -2895,14 +2895,26 @@ void Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { + const Driver &D = getDriver(); + std::string SysRoot = computeSysRoot(); + std::string MultiarchTriple = getMultiarchTriple(D, getTriple(), SysRoot); + 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 multiarch include path if it exists. + std::string MultiarchDir = Path + "/" + MultiarchTriple + "/c++/" + Version; + llvm::outs() << MultiarchDir << "\n"; + if (!MultiarchTriple.empty() && D.getVFS().exists(MultiarchDir)) + addSystemInclude(DriverArgs, CC1Args, MultiarchDir); + + // 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()) @@ -2911,7 +2923,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-linux-gnu/c++/v1/.keep b/clang/test/Driver/Inputs/basic_linux_libcxx_tree/usr/include/x86_64-linux-gnu/c++/v1/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/basic_linux_libcxxv2_tree/usr/include/x86_64-linux-gnu/c++/v2/.keep b/clang/test/Driver/Inputs/basic_linux_libcxxv2_tree/usr/include/x86_64-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-linux-gnu/c++/v2/.keep b/clang/test/Driver/Inputs/basic_linux_libstdcxx_libcxxv2_tree/usr/include/x86_64-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-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-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-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-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-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}/c++) 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}/c++) + 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 @@ -191,9 +191,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}") @@ -210,24 +210,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 ${LIBCXX_INSTALL_HEADER_PREFIX}include/c++/v1/${dir} + DESTINATION ${LIBCXX_INSTALL_HEADER_PREFIX}${LIBCXX_INSTALL_HEADER_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 ${LIBCXX_INSTALL_HEADER_PREFIX}include/c++/v1 + install(FILES ${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}/__config_site + DESTINATION ${LIBCXX_INSTALL_HEADER_PREFIX}${LIBCXX_INSTALL_INCLUDE_TARGET_DIR} PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT cxx-headers)