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,9 @@ void Generic_GCC::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { - addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args); + StringRef TripleStr = + GCCInstallation.isValid() ? 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.c b/clang/test/Driver/hurd.c deleted file mode 100644 --- a/clang/test/Driver/hurd.c +++ /dev/null @@ -1,73 +0,0 @@ -// 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:[^"]+]]" -// 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" - -// RUN: %clang -no-canonical-prefixes %s -### 2>&1 \ -// RUN: --target=i386-pc-gnu -static \ -// RUN: --sysroot=%S/Inputs/basic_hurd_tree \ -// RUN: | FileCheck --check-prefix=CHECK-STATIC %s -// CHECK-STATIC-NOT: warning: -// CHECK-STATIC: "-cc1" -// CHECK-STATIC: "-static-define" -// CHECK-STATIC: "-isysroot" "[[SYSROOT:[^"]+]]" -// CHECK-STATIC: "-internal-isystem" "[[SYSROOT]]/usr/local/include" -// CHECK-STATIC: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/i386-gnu" -// CHECK-STATIC: "-internal-externc-isystem" "[[SYSROOT]]/include" -// CHECK-STATIC: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" -// CHECK-STATIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-STATIC: "-static" -// CHECK-STATIC: "{{.*}}/usr/lib/gcc/i686-gnu/4.6.0{{/|\\\\}}crtbeginT.o" -// CHECK-STATIC: "-L[[SYSROOT]]/lib/i386-gnu" -// CHECK-STATIC: "-L[[SYSROOT]]/lib/../lib32" -// CHECK-STATIC: "-L[[SYSROOT]]/usr/lib/i386-gnu" -// CHECK-STATIC: "-L[[SYSROOT]]/usr/lib/../lib32" -// CHECK-STATIC: "-L[[SYSROOT]]/lib" -// CHECK-STATIC: "-L[[SYSROOT]]/usr/lib" - -// RUN: %clang -no-canonical-prefixes %s -### 2>&1 \ -// RUN: --target=i386-pc-gnu -shared \ -// RUN: --sysroot=%S/Inputs/basic_hurd_tree \ -// RUN: | FileCheck --check-prefix=CHECK-SHARED %s -// CHECK-SHARED-NOT: warning: -// CHECK-SHARED: "-cc1" -// CHECK-SHARED: "-isysroot" "[[SYSROOT:[^"]+]]" -// CHECK-SHARED: "-internal-isystem" "[[SYSROOT]]/usr/local/include" -// CHECK-SHARED: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/i386-gnu" -// CHECK-SHARED: "-internal-externc-isystem" "[[SYSROOT]]/include" -// CHECK-SHARED: "-internal-externc-isystem" "[[SYSROOT]]/usr/include" -// CHECK-SHARED: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" -// CHECK-SHARED: "{{.*}}/usr/lib/gcc/i686-gnu/4.6.0{{/|\\\\}}crtbeginS.o" -// CHECK-SHARED: "-L[[SYSROOT]]/lib/i386-gnu" -// CHECK-SHARED: "-L[[SYSROOT]]/lib/../lib32" -// CHECK-SHARED: "-L[[SYSROOT]]/usr/lib/i386-gnu" -// CHECK-SHARED: "-L[[SYSROOT]]/usr/lib/../lib32" -// CHECK-SHARED: "-L[[SYSROOT]]/lib" -// CHECK-SHARED: "-L[[SYSROOT]]/usr/lib" - -// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as -fuse-ld=ld \ -// RUN: --gcc-toolchain=%S/Inputs/basic_cross_hurd_tree/usr \ -// RUN: --target=i386-pc-gnu \ -// RUN: | FileCheck --check-prefix=CHECK-CROSS %s -// CHECK-CROSS-NOT: warning: -// CHECK-CROSS: "-cc1" "-triple" "i386-pc-hurd-gnu" -// CHECK-CROSS: "{{.*}}/Inputs/basic_cross_hurd_tree/usr/lib/gcc/i686-gnu/4.6.0/../../../../i686-gnu/bin{{/|\\\\}}as" "--32" -// CHECK-CROSS: "{{.*}}/Inputs/basic_cross_hurd_tree/usr/lib/gcc/i686-gnu/4.6.0/../../../../i686-gnu/bin{{/|\\\\}}ld" {{.*}} "-m" "elf_i386" -// CHECK-CROSS: "{{.*}}/Inputs/basic_cross_hurd_tree/usr/lib/gcc/i686-gnu/4.6.0{{/|\\\\}}crtbegin.o" -// CHECK-CROSS: "-L{{.*}}/Inputs/basic_cross_hurd_tree/usr/lib/gcc/i686-gnu/4.6.0/../../../../i686-gnu/lib" 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,98 @@ +// UNSUPPORTED: system-windows + +// RUN: %clang -no-canonical-prefixes %s -### 2>&1 \ +// RUN: --target=i386-pc-hurd-gnu \ +// RUN: --sysroot=%S/Inputs/basic_hurd_tree \ +// RUN: | FileCheck --check-prefix=CHECK %s +// CHECK: "-cc1" +// CHECK: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0/../../../../include/c++/4.6.0" +/// Debian specific - the path component after 'include' is i386-gnu even +/// though the installation is i686-gnu. +// CHECK-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0/../../../../include/i386-gnu/c++/4.6.0" +// CHECK-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0/../../../../include/c++/4.6.0/backward" +// CHECK-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// CHECK: "-internal-externc-isystem" +// CHECK-SAME: {{^}} "[[SYSROOT]]/usr/include/i386-gnu" +// CHECK-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/include" +// CHECK-SAME: {{^}} "-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 +// CHECK-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0" +// CHECK-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0/../../../../lib32" +// CHECK-SAME: {{^}} "-L[[SYSROOT]]/lib/i386-gnu" +// CHECK-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib32" +// CHECK-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/i386-gnu" +// CHECK-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/../lib32" +// CHECK-SAME: {{^}} "-L[[SYSROOT]]/lib" +// CHECK-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +// RUN: %clang -no-canonical-prefixes %s -### 2>&1 \ +// RUN: --target=i386-pc-hurd-gnu -static \ +// RUN: --sysroot=%S/Inputs/basic_hurd_tree \ +// RUN: | FileCheck --check-prefix=CHECK-STATIC %s +// CHECK-STATIC: "-cc1" +// CHECK-STATIC: "-static-define" +// CHECK-STATIC: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-STATIC-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0/../../../../include/c++/4.6.0" +/// Debian specific - the path component after 'include' is i386-gnu even +/// though the installation is i686-gnu. +// CHECK-STATIC-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0/../../../../include/i386-gnu/c++/4.6.0" +// CHECK-STATIC-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0/../../../../include/c++/4.6.0/backward" +// CHECK-STATIC-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// CHECK-STATIC: "-internal-externc-isystem" +// CHECK-STATIC-SAME: {{^}} "[[SYSROOT]]/usr/include/i386-gnu" +// CHECK-STATIC-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/include" +// CHECK-STATIC-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/usr/include" +// CHECK-STATIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-STATIC: "-static" +// CHECK-STATIC: "{{.*}}/usr/lib/gcc/i686-gnu/4.6.0{{/|\\\\}}crtbeginT.o" +// CHECK-STATIC: "-L +// CHECK-STATIC-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0" +// CHECK-STATIC-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0/../../../../lib32" +// CHECK-STATIC-SAME: {{^}} "-L[[SYSROOT]]/lib/i386-gnu" +// CHECK-STATIC-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib32" +// CHECK-STATIC-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/i386-gnu" +// CHECK-STATIC-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/../lib32" +// CHECK-STATIC-SAME: {{^}} "-L[[SYSROOT]]/lib" +// CHECK-STATIC-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +// RUN: %clang -no-canonical-prefixes %s -### 2>&1 \ +// RUN: --target=i386-pc-hurd-gnu -shared \ +// RUN: --sysroot=%S/Inputs/basic_hurd_tree \ +// RUN: | FileCheck --check-prefix=CHECK-SHARED %s +// CHECK-SHARED: "-cc1" +// CHECK-SHARED: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-SHARED-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0/../../../../include/c++/4.6.0" +/// Debian specific - the path component after 'include' is i386-gnu even +/// though the installation is i686-gnu. +// CHECK-SHARED-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0/../../../../include/i386-gnu/c++/4.6.0" +// CHECK-SHARED-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0/../../../../include/c++/4.6.0/backward" +// CHECK-SHARED-SAME: {{^}} "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// CHECK-SHARED: "-internal-externc-isystem" +// CHECK-SHARED-SAME: {{^}} "[[SYSROOT]]/usr/include/i386-gnu" +// CHECK-SHARED-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/include" +// CHECK-SHARED-SAME: {{^}} "-internal-externc-isystem" "[[SYSROOT]]/usr/include" +// CHECK-SHARED: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" +// CHECK-SHARED: "{{.*}}/usr/lib/gcc/i686-gnu/4.6.0{{/|\\\\}}crtbeginS.o" +// CHECK-SHARED: "-L +// CHECK-SHARED-SAME: {{^}}[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0" +// CHECK-SHARED-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/gcc/i686-gnu/4.6.0/../../../../lib32" +// CHECK-SHARED-SAME: {{^}} "-L[[SYSROOT]]/lib/i386-gnu" +// CHECK-SHARED-SAME: {{^}} "-L[[SYSROOT]]/lib/../lib32" +// CHECK-SHARED-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/i386-gnu" +// CHECK-SHARED-SAME: {{^}} "-L[[SYSROOT]]/usr/lib/../lib32" +// CHECK-SHARED-SAME: {{^}} "-L[[SYSROOT]]/lib" +// CHECK-SHARED-SAME: {{^}} "-L[[SYSROOT]]/usr/lib" + +// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as -fuse-ld=ld \ +// RUN: --gcc-toolchain=%S/Inputs/basic_cross_hurd_tree/usr \ +// RUN: --target=i386-pc-gnu \ +// RUN: | FileCheck --check-prefix=CHECK-CROSS %s +// CHECK-CROSS: "-cc1" "-triple" "i386-pc-hurd-gnu" +// CHECK-CROSS: "{{.*}}/Inputs/basic_cross_hurd_tree/usr/lib/gcc/i686-gnu/4.6.0/../../../../i686-gnu/bin{{/|\\\\}}as" "--32" +// CHECK-CROSS: "{{.*}}/Inputs/basic_cross_hurd_tree/usr/lib/gcc/i686-gnu/4.6.0/../../../../i686-gnu/bin{{/|\\\\}}ld" {{.*}} "-m" "elf_i386" +// CHECK-CROSS: "{{.*}}/Inputs/basic_cross_hurd_tree/usr/lib/gcc/i686-gnu/4.6.0{{/|\\\\}}crtbegin.o" +// CHECK-CROSS: "-L{{.*}}/Inputs/basic_cross_hurd_tree/usr/lib/gcc/i686-gnu/4.6.0/../../../../i686-gnu/lib"