1 //===--- Solaris.cpp - Solaris ToolChain Implementations --------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "Solaris.h" 11 #include "CommonArgs.h" 12 #include "clang/Config/config.h" 13 #include "clang/Driver/Compilation.h" 14 #include "clang/Driver/Driver.h" 15 #include "clang/Driver/DriverDiagnostic.h" 16 #include "clang/Driver/Options.h" 17 #include "llvm/Option/ArgList.h" 18 #include "llvm/Support/FileSystem.h" 19 #include "llvm/Support/Path.h" 20 21 using namespace clang::driver; 22 using namespace clang::driver::tools; 23 using namespace clang::driver::toolchains; 24 using namespace clang; 25 using namespace llvm::opt; 26 27 void solaris::Assembler::ConstructJob(Compilation &C, const JobAction &JA, 28 const InputInfo &Output, 29 const InputInfoList &Inputs, 30 const ArgList &Args, 31 const char *LinkingOutput) const { 32 claimNoWarnArgs(Args); 33 ArgStringList CmdArgs; 34 35 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); 36 37 CmdArgs.push_back("-o"); 38 CmdArgs.push_back(Output.getFilename()); 39 40 for (const auto &II : Inputs) 41 CmdArgs.push_back(II.getFilename()); 42 43 const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); 44 C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 45 } 46 47 void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA, 48 const InputInfo &Output, 49 const InputInfoList &Inputs, 50 const ArgList &Args, 51 const char *LinkingOutput) const { 52 ArgStringList CmdArgs; 53 54 // Demangle C++ names in errors 55 CmdArgs.push_back("-C"); 56 57 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) { 58 CmdArgs.push_back("-e"); 59 CmdArgs.push_back("_start"); 60 } 61 62 if (Args.hasArg(options::OPT_static)) { 63 CmdArgs.push_back("-Bstatic"); 64 CmdArgs.push_back("-dn"); 65 } else { 66 CmdArgs.push_back("-Bdynamic"); 67 if (Args.hasArg(options::OPT_shared)) { 68 CmdArgs.push_back("-shared"); 69 } else { 70 CmdArgs.push_back("--dynamic-linker"); 71 CmdArgs.push_back( 72 Args.MakeArgString(getToolChain().GetFilePath("ld.so.1"))); 73 } 74 } 75 76 if (Output.isFilename()) { 77 CmdArgs.push_back("-o"); 78 CmdArgs.push_back(Output.getFilename()); 79 } else { 80 assert(Output.isNothing() && "Invalid output."); 81 } 82 83 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { 84 if (!Args.hasArg(options::OPT_shared)) 85 CmdArgs.push_back( 86 Args.MakeArgString(getToolChain().GetFilePath("crt1.o"))); 87 88 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o"))); 89 CmdArgs.push_back( 90 Args.MakeArgString(getToolChain().GetFilePath("values-Xa.o"))); 91 CmdArgs.push_back( 92 Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); 93 } 94 95 getToolChain().AddFilePathLibArgs(Args, CmdArgs); 96 97 Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group, 98 options::OPT_e, options::OPT_r}); 99 100 AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); 101 102 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { 103 if (getToolChain().getDriver().CCCIsCXX()) 104 getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); 105 CmdArgs.push_back("-lgcc_s"); 106 CmdArgs.push_back("-lc"); 107 if (!Args.hasArg(options::OPT_shared)) { 108 CmdArgs.push_back("-lgcc"); 109 CmdArgs.push_back("-lm"); 110 } 111 } 112 113 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { 114 CmdArgs.push_back( 115 Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); 116 } 117 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); 118 119 getToolChain().addProfileRTLibs(Args, CmdArgs); 120 121 const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); 122 C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 123 } 124 125 /// Solaris - Solaris tool chain which can call as(1) and ld(1) directly. 126 127 Solaris::Solaris(const Driver &D, const llvm::Triple &Triple, 128 const ArgList &Args) 129 : Generic_GCC(D, Triple, Args) { 130 131 GCCInstallation.init(Triple, Args); 132 133 path_list &Paths = getFilePaths(); 134 if (GCCInstallation.isValid()) 135 addPathIfExists(D, GCCInstallation.getInstallPath(), Paths); 136 137 addPathIfExists(D, getDriver().getInstalledDir(), Paths); 138 if (getDriver().getInstalledDir() != getDriver().Dir) 139 addPathIfExists(D, getDriver().Dir, Paths); 140 141 addPathIfExists(D, getDriver().SysRoot + getDriver().Dir + "/../lib", Paths); 142 143 std::string LibPath = "/usr/lib/"; 144 switch (Triple.getArch()) { 145 case llvm::Triple::x86: 146 case llvm::Triple::sparc: 147 break; 148 case llvm::Triple::x86_64: 149 LibPath += "amd64/"; 150 break; 151 case llvm::Triple::sparcv9: 152 LibPath += "sparcv9/"; 153 break; 154 default: 155 llvm_unreachable("Unsupported architecture"); 156 } 157 158 addPathIfExists(D, getDriver().SysRoot + LibPath, Paths); 159 } 160 161 Tool *Solaris::buildAssembler() const { 162 return new tools::solaris::Assembler(*this); 163 } 164 165 Tool *Solaris::buildLinker() const { return new tools::solaris::Linker(*this); } 166 167 void Solaris::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, 168 ArgStringList &CC1Args) const { 169 if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 170 DriverArgs.hasArg(options::OPT_nostdincxx)) 171 return; 172 173 // Include the support directory for things like xlocale and fudged system 174 // headers. 175 // FIXME: This is a weird mix of libc++ and libstdc++. We should also be 176 // checking the value of -stdlib= here and adding the includes for libc++ 177 // rather than libstdc++ if it's requested. 178 addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/v1/support/solaris"); 179 180 if (GCCInstallation.isValid()) { 181 GCCVersion Version = GCCInstallation.getVersion(); 182 addSystemInclude(DriverArgs, CC1Args, 183 getDriver().SysRoot + "/usr/gcc/" + 184 Version.MajorStr + "." + 185 Version.MinorStr + 186 "/include/c++/" + Version.Text); 187 addSystemInclude(DriverArgs, CC1Args, 188 getDriver().SysRoot + "/usr/gcc/" + Version.MajorStr + 189 "." + Version.MinorStr + "/include/c++/" + 190 Version.Text + "/" + 191 GCCInstallation.getTriple().str()); 192 } 193 } 194