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 @@ -2941,31 +2941,27 @@ if (!getVFS().exists(IncludeDir)) return false; + // Debian native gcc uses g++-multiarch-incdir.diff which uses + // include/x86_64-linux-gnu/c++/10$IncludeSuffix instead of + // include/c++/10/x86_64-linux-gnu$IncludeSuffix. + std::string Dir = IncludeDir.str(); + StringRef Include = + llvm::sys::path::parent_path(llvm::sys::path::parent_path(Dir)); + std::string Path = + (Include + "/" + Triple + Dir.substr(Include.size()) + IncludeSuffix) + .str(); + if (DetectDebian && !getVFS().exists(Path)) + return false; + // GPLUSPLUS_INCLUDE_DIR addSystemInclude(DriverArgs, CC1Args, IncludeDir); // GPLUSPLUS_TOOL_INCLUDE_DIR. If Triple is not empty, add a target-dependent // include directory. - if (!Triple.empty()) { - if (DetectDebian) { - // Debian native gcc has an awful patch g++-multiarch-incdir.diff which - // uses include/x86_64-linux-gnu/c++/10$IncludeSuffix instead of - // include/c++/10/x86_64-linux-gnu$IncludeSuffix. - std::string Dir = IncludeDir.str(); - StringRef Include = - llvm::sys::path::parent_path(llvm::sys::path::parent_path(Dir)); - std::string Path = - (Include + "/" + Triple + Dir.substr(Include.size()) + IncludeSuffix) - .str(); - if (getVFS().exists(Path)) - addSystemInclude(DriverArgs, CC1Args, Path); - else - addSystemInclude(DriverArgs, CC1Args, - IncludeDir + "/" + Triple + IncludeSuffix); - } else { - addSystemInclude(DriverArgs, CC1Args, - IncludeDir + "/" + Triple + IncludeSuffix); - } - } + if (DetectDebian) + addSystemInclude(DriverArgs, CC1Args, Path); + else if (!Triple.empty()) + addSystemInclude(DriverArgs, CC1Args, + IncludeDir + "/" + Triple + IncludeSuffix); // GPLUSPLUS_BACKWARD_INCLUDE_DIR addSystemInclude(DriverArgs, CC1Args, IncludeDir + "/backward"); return true; @@ -2985,7 +2981,7 @@ const Multilib &Multilib = GCCInstallation.getMultilib(); const GCCVersion &Version = GCCInstallation.getVersion(); - // Try /../$triple/include/c++/$version then /../include/c++/$version. + // Try /../$triple/include/c++/$version (gcc --print-multiarch is not empty). if (addLibStdCXXIncludePaths( LibDir.str() + "/../" + TripleStr + "/include/c++/" + Version.Text, TripleStr, Multilib.includeSuffix(), DriverArgs, CC1Args)) @@ -2997,6 +2993,12 @@ DriverArgs, CC1Args, /*Debian=*/true)) return true; + // Try /../include/c++/$version (gcc --print-multiarch is empty). + if (addLibStdCXXIncludePaths(LibDir.str() + "/../include/c++/" + Version.Text, + TripleStr, Multilib.includeSuffix(), DriverArgs, + CC1Args)) + return true; + // Otherwise, fall back on a bunch of options which don't use multiarch // layouts for simplicity. const std::string LibStdCXXIncludePathCandidates[] = { diff --git a/clang/test/Driver/Inputs/archlinux_i686_tree/lib/.keep b/clang/test/Driver/Inputs/archlinux_i686_tree/lib/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/archlinux_i686_tree/usr/include/c++/11.1.0/backward/.keep b/clang/test/Driver/Inputs/archlinux_i686_tree/usr/include/c++/11.1.0/backward/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/archlinux_i686_tree/usr/include/c++/11.1.0/i686-pc-linux-gnu/.keep b/clang/test/Driver/Inputs/archlinux_i686_tree/usr/include/c++/11.1.0/i686-pc-linux-gnu/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/archlinux_i686_tree/usr/lib/crt1.o b/clang/test/Driver/Inputs/archlinux_i686_tree/usr/lib/crt1.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/archlinux_i686_tree/usr/lib/crti.o b/clang/test/Driver/Inputs/archlinux_i686_tree/usr/lib/crti.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/archlinux_i686_tree/usr/lib/crtn.o b/clang/test/Driver/Inputs/archlinux_i686_tree/usr/lib/crtn.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/archlinux_i686_tree/usr/lib/gcc/i686-pc-linux-gnu/11.1.0/crtbegin.o b/clang/test/Driver/Inputs/archlinux_i686_tree/usr/lib/gcc/i686-pc-linux-gnu/11.1.0/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/archlinux_i686_tree/usr/lib/gcc/i686-pc-linux-gnu/11.1.0/crtend.o b/clang/test/Driver/Inputs/archlinux_i686_tree/usr/lib/gcc/i686-pc-linux-gnu/11.1.0/crtend.o new file mode 100644 diff --git a/clang/test/Driver/linux-cross.cpp b/clang/test/Driver/linux-cross.cpp --- a/clang/test/Driver/linux-cross.cpp +++ b/clang/test/Driver/linux-cross.cpp @@ -1,5 +1,27 @@ // UNSUPPORTED: system-windows +/// Test native GCC installation on Arch Linux i686. +// RUN: %clang -### %s --target=i686-linux-gnu --sysroot=%S/Inputs/archlinux_i686_tree \ +// RUN: -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin -resource-dir=%S/Inputs/resource_dir \ +// RUN: --stdlib=platform --rtlib=platform 2>&1 | FileCheck %s --check-prefix=ARCH_I686 +// ARCH_I686: "-resource-dir" "[[RESOURCE:[^"]+]]" +// ARCH_I686: "-internal-isystem" +// ARCH_I686-SAME: {{^}} "[[SYSROOT:[^"]+]]/usr/lib/gcc/i686-pc-linux-gnu/11.1.0/../../../../include/c++/11.1.0" +// ARCH_I686-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/lib/gcc/i686-pc-linux-gnu/11.1.0/../../../../include/c++/11.1.0/i686-pc-linux-gnu" +// ARCH_I686-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/lib/gcc/i686-pc-linux-gnu/11.1.0/../../../../include/c++/11.1.0/backward" +// ARCH_I686-SAME: {{^}} "-internal-isystem" "[[RESOURCE]]/include" +// ARCH_I686-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/local/include" +/// This resolves to /usr/i686-linux-gnu/include. Because it does not exist, +/// having it does no harm albeit not ideal. +// ARCH_I686-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/lib/gcc/i686-pc-linux-gnu/11.1.0/../../../../i686-pc-linux-gnu/include" +// ARCH_I686: "-internal-externc-isystem" +// ARCH_I686-SAME: {{^}} "[[SYSROOT]]/include" +// ARCH_I686-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/usr/include" +// ARCH_I686: "-L +// ARCH_I686-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/i686-pc-linux-gnu/11.1.0" +// ARCH_I686-SAME: {{^}} "-L[[SYSROOT]]/lib" +// ARCH_I686-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + /// Test native x86-64 in the tree. // RUN: %clang -### %s --target=x86_64-linux-gnu --sysroot=%S/Inputs/debian_multiarch_tree \ // RUN: -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin -resource-dir=%S/Inputs/resource_dir \