diff --git a/clang/lib/Driver/ToolChains/Gnu.h b/clang/lib/Driver/ToolChains/Gnu.h --- a/clang/lib/Driver/ToolChains/Gnu.h +++ b/clang/lib/Driver/ToolChains/Gnu.h @@ -347,9 +347,9 @@ addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const; - bool - addGCCLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const; + bool addGCCLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args, + StringRef Debianmultiarch) const; bool addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple, Twine IncludeSuffix, 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 @@ -2961,9 +2961,9 @@ return true; } -bool -Generic_GCC::addGCCLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const { +bool Generic_GCC::addGCCLibStdCxxIncludePaths( + const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, + StringRef DebianMultiarch) const { // Use GCCInstallation to know where libstdc++ headers are installed. if (!GCCInstallation.isValid()) return false; @@ -2982,11 +2982,8 @@ LibDir.str() + "/../" + TripleStr + "/include/c++/" + Version.Text, TripleStr, Multilib.includeSuffix(), DriverArgs, CC1Args)) return true; + // Detect Debian g++-multiarch-incdir.diff. - StringRef DebianMultiarch = - GCCInstallation.getTriple().getArch() == llvm::Triple::x86 - ? "i386-linux-gnu" - : TripleStr; if (addLibStdCXXIncludePaths(LibDir.str() + "/../include/c++/" + Version.Text, DebianMultiarch, Multilib.includeSuffix(), DriverArgs, CC1Args, /*Debian=*/true)) @@ -3014,7 +3011,12 @@ void Generic_GCC::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { - addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args); + if (!GCCInstallation.isValid()) + return; + + StringRef TripleStr = GCCInstallation.getTriple().str(); + + addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args, TripleStr); } llvm::opt::DerivedArgList * diff --git a/clang/lib/Driver/ToolChains/Hurd.h b/clang/lib/Driver/ToolChains/Hurd.h --- a/clang/lib/Driver/ToolChains/Hurd.h +++ b/clang/lib/Driver/ToolChains/Hurd.h @@ -26,6 +26,9 @@ void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void + addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; std::string getDynamicLinker(const llvm::opt::ArgList &Args) const override; diff --git a/clang/lib/Driver/ToolChains/Hurd.cpp b/clang/lib/Driver/ToolChains/Hurd.cpp --- a/clang/lib/Driver/ToolChains/Hurd.cpp +++ b/clang/lib/Driver/ToolChains/Hurd.cpp @@ -186,6 +186,21 @@ addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); } +void Hurd::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { + // We need a detected GCC installation on Linux to provide libstdc++'s + // headers in odd Linuxish places. + if (!GCCInstallation.isValid()) + return; + + StringRef TripleStr = GCCInstallation.getTriple().str(); + StringRef DebianMultiarch = + GCCInstallation.getTriple().getArch() == llvm::Triple::x86 ? "i386-gnu" + : TripleStr; + + addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args, DebianMultiarch); +} + void Hurd::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { for (const auto &Opt : ExtraOpts) CmdArgs.push_back(Opt.c_str()); diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -595,17 +595,24 @@ void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { - // Try generic GCC detection first. - if (Generic_GCC::addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args)) - return; - // We need a detected GCC installation on Linux to provide libstdc++'s // headers in odd Linuxish places. if (!GCCInstallation.isValid()) return; - StringRef LibDir = GCCInstallation.getParentLibPath(); + // Detect Debian g++-multiarch-incdir.diff. StringRef TripleStr = GCCInstallation.getTriple().str(); + StringRef DebianMultiarch = + GCCInstallation.getTriple().getArch() == llvm::Triple::x86 + ? "i386-linux-gnu" + : TripleStr; + + // Try generic GCC detection first. + if (Generic_GCC::addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args, + DebianMultiarch)) + return; + + StringRef LibDir = GCCInstallation.getParentLibPath(); const Multilib &Multilib = GCCInstallation.getMultilib(); const GCCVersion &Version = GCCInstallation.getVersion(); diff --git a/clang/test/Driver/Inputs/basic_hurd_tree/usr/include/c++/4.6.0/.keep b/clang/test/Driver/Inputs/basic_hurd_tree/usr/include/c++/4.6.0/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/basic_hurd_tree/usr/include/i386-gnu/c++/4.6.0/.keep b/clang/test/Driver/Inputs/basic_hurd_tree/usr/include/i386-gnu/c++/4.6.0/.keep new file mode 100644 diff --git a/clang/test/Driver/hurd.cpp b/clang/test/Driver/hurd.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Driver/hurd.cpp @@ -0,0 +1,25 @@ +// RUN: %clang -no-canonical-prefixes %s -### 2>&1 \ +// RUN: --target=i386-pc-gnu \ +// RUN: --sysroot=%S/Inputs/basic_hurd_tree \ +// RUN: | FileCheck --check-prefix=CHECK %s +// CHECK-NOT: warning: +// CHECK: "-cc1" +// CHECK: "-isysroot" "[[SYSROOT:[^"]+]]" +/// Debian specific - the path component after 'include' is i386-gnu even +/// though the installation is i686-gnu. +// CHECK: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0/../../../../include/c++/4.6.0" +// CHECK: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0/../../../../include/i386-gnu/c++/4.6.0" +// CHECK: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0/../../../../include/c++/4.6.0/backward" +// CHECK: "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// CHECK: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/i386-gnu" +// CHECK: "-internal-externc-isystem" "[[SYSROOT]]/include" +// CHECK: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" +// CHECK: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK: "-dynamic-linker" "/lib/ld.so" +// CHECK: "{{.*}}/usr/lib/gcc/i686-gnu/4.6.0{{/|\\\\}}crtbegin.o" +// CHECK: "-L[[SYSROOT]]/lib/i386-gnu" +// CHECK: "-L[[SYSROOT]]/lib/../lib32" +// CHECK: "-L[[SYSROOT]]/usr/lib/i386-gnu" +// CHECK: "-L[[SYSROOT]]/usr/lib/../lib32" +// CHECK: "-L[[SYSROOT]]/lib" +// CHECK: "-L[[SYSROOT]]/usr/lib"