diff options
Diffstat (limited to 'clang/lib/Driver/ToolChains/Solaris.cpp')
-rw-r--r-- | clang/lib/Driver/ToolChains/Solaris.cpp | 137 |
1 files changed, 93 insertions, 44 deletions
diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp index 9fe6e9d520d..bdf40668f11 100644 --- a/clang/lib/Driver/ToolChains/Solaris.cpp +++ b/clang/lib/Driver/ToolChains/Solaris.cpp @@ -122,6 +122,21 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); } +static StringRef getSolarisLibSuffix(const llvm::Triple &Triple) { + switch (Triple.getArch()) { + case llvm::Triple::x86: + case llvm::Triple::sparc: + break; + case llvm::Triple::x86_64: + return "/amd64"; + case llvm::Triple::sparcv9: + return "/sparcv9"; + default: + llvm_unreachable("Unsupported architecture"); + } + return ""; +} + /// Solaris - Solaris tool chain which can call as(1) and ld(1) directly. Solaris::Solaris(const Driver &D, const llvm::Triple &Triple, @@ -130,32 +145,24 @@ Solaris::Solaris(const Driver &D, const llvm::Triple &Triple, GCCInstallation.init(Triple, Args); + StringRef LibSuffix = getSolarisLibSuffix(Triple); path_list &Paths = getFilePaths(); - if (GCCInstallation.isValid()) - addPathIfExists(D, GCCInstallation.getInstallPath(), Paths); - - addPathIfExists(D, getDriver().getInstalledDir(), Paths); - if (getDriver().getInstalledDir() != getDriver().Dir) - addPathIfExists(D, getDriver().Dir, Paths); - - addPathIfExists(D, getDriver().SysRoot + getDriver().Dir + "/../lib", Paths); - - std::string LibPath = "/usr/lib/"; - switch (Triple.getArch()) { - case llvm::Triple::x86: - case llvm::Triple::sparc: - break; - case llvm::Triple::x86_64: - LibPath += "amd64/"; - break; - case llvm::Triple::sparcv9: - LibPath += "sparcv9/"; - break; - default: - llvm_unreachable("Unsupported architecture"); + if (GCCInstallation.isValid()) { + // On Solaris gcc uses both an architecture-specific path with triple in it + // as well as a more generic lib path (+arch suffix). + addPathIfExists(D, + GCCInstallation.getInstallPath() + + GCCInstallation.getMultilib().gccSuffix(), + Paths); + addPathIfExists(D, GCCInstallation.getParentLibPath() + LibSuffix, Paths); } - addPathIfExists(D, getDriver().SysRoot + LibPath, Paths); + // If we are currently running Clang inside of the requested system root, + // add its parent library path to those searched. + if (StringRef(D.Dir).startswith(D.SysRoot)) + addPathIfExists(D, D.Dir + "/../lib", Paths); + + addPathIfExists(D, D.SysRoot + "/usr/lib" + LibSuffix, Paths); } Tool *Solaris::buildAssembler() const { @@ -164,30 +171,72 @@ Tool *Solaris::buildAssembler() const { Tool *Solaris::buildLinker() const { return new tools::solaris::Linker(*this); } -void Solaris::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, - ArgStringList &CC1Args) const { - if (DriverArgs.hasArg(options::OPT_nostdlibinc) || - DriverArgs.hasArg(options::OPT_nostdincxx)) +void Solaris::AddClangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + const Driver &D = getDriver(); + + if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) + return; + + if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) + addSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/local/include"); + + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "include"); + addSystemInclude(DriverArgs, CC1Args, P); + } + + if (DriverArgs.hasArg(options::OPT_nostdlibinc)) return; - // Include the support directory for things like xlocale and fudged system - // headers. - // FIXME: This is a weird mix of libc++ and libstdc++. We should also be - // checking the value of -stdlib= here and adding the includes for libc++ - // rather than libstdc++ if it's requested. - addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/v1/support/solaris"); + // Check for configure-time C include directories. + StringRef CIncludeDirs(C_INCLUDE_DIRS); + if (CIncludeDirs != "") { + SmallVector<StringRef, 5> dirs; + CIncludeDirs.split(dirs, ":"); + for (StringRef dir : dirs) { + StringRef Prefix = + llvm::sys::path::is_absolute(dir) ? StringRef(D.SysRoot) : ""; + addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); + } + return; + } + // Add include directories specific to the selected multilib set and multilib. if (GCCInstallation.isValid()) { - GCCVersion Version = GCCInstallation.getVersion(); - addSystemInclude(DriverArgs, CC1Args, - getDriver().SysRoot + "/usr/gcc/" + - Version.MajorStr + "." + - Version.MinorStr + - "/include/c++/" + Version.Text); - addSystemInclude(DriverArgs, CC1Args, - getDriver().SysRoot + "/usr/gcc/" + Version.MajorStr + - "." + Version.MinorStr + "/include/c++/" + - Version.Text + "/" + - GCCInstallation.getTriple().str()); + const MultilibSet::IncludeDirsFunc &Callback = + Multilibs.includeDirsCallback(); + if (Callback) { + for (const auto &Path : Callback(GCCInstallation.getMultilib())) + addExternCSystemIncludeIfExists( + DriverArgs, CC1Args, GCCInstallation.getInstallPath() + Path); + } } + + addExternCSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/include"); +} + +void Solaris::addLibStdCxxIncludePaths( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { + // We need a detected GCC installation on Solaris (similar to Linux) + // to provide libstdc++'s headers. + if (!GCCInstallation.isValid()) + return; + + // By default, look for the C++ headers in an include directory adjacent to + // the lib directory of the GCC installation. + // On Solaris this usually looks like /usr/gcc/X.Y/include/c++/X.Y.Z + StringRef LibDir = GCCInstallation.getParentLibPath(); + StringRef TripleStr = GCCInstallation.getTriple().str(); + const Multilib &Multilib = GCCInstallation.getMultilib(); + const GCCVersion &Version = GCCInstallation.getVersion(); + + // The primary search for libstdc++ supports multiarch variants. + addLibStdCXXIncludePaths(LibDir.str() + "/../include", "/c++/" + Version.Text, + TripleStr, + /*GCCMultiarchTriple*/ "", + /*TargetMultiarchTriple*/ "", + Multilib.includeSuffix(), DriverArgs, CC1Args); } |