1 //===-- MipsLinux.cpp - Mips ToolChain Implementations ----------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "MipsLinux.h" 10 #include "Arch/Mips.h" 11 #include "CommonArgs.h" 12 #include "clang/Driver/Driver.h" 13 #include "clang/Driver/DriverDiagnostic.h" 14 #include "clang/Driver/Options.h" 15 #include "llvm/Option/ArgList.h" 16 #include "llvm/Support/FileSystem.h" 17 #include "llvm/Support/Path.h" 18 19 using namespace clang::driver; 20 using namespace clang::driver::toolchains; 21 using namespace clang; 22 using namespace llvm::opt; 23 24 /// Mips Toolchain 25 MipsLLVMToolChain::MipsLLVMToolChain(const Driver &D, 26 const llvm::Triple &Triple, 27 const ArgList &Args) 28 : Linux(D, Triple, Args) { 29 // Select the correct multilib according to the given arguments. 30 DetectedMultilibs Result; 31 findMIPSMultilibs(D, Triple, "", Args, Result); 32 Multilibs = Result.Multilibs; 33 SelectedMultilib = Result.SelectedMultilib; 34 35 // Find out the library suffix based on the ABI. 36 LibSuffix = tools::mips::getMipsABILibSuffix(Args, Triple); 37 getFilePaths().clear(); 38 getFilePaths().push_back(computeSysRoot() + "/usr/lib" + LibSuffix); 39 } 40 41 void MipsLLVMToolChain::AddClangSystemIncludeArgs( 42 const ArgList &DriverArgs, ArgStringList &CC1Args) const { 43 if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) 44 return; 45 46 const Driver &D = getDriver(); 47 48 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 49 SmallString<128> P(D.ResourceDir); 50 llvm::sys::path::append(P, "include"); 51 addSystemInclude(DriverArgs, CC1Args, P); 52 } 53 54 if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 55 return; 56 57 const auto &Callback = Multilibs.includeDirsCallback(); 58 if (Callback) { 59 for (const auto &Path : Callback(SelectedMultilib)) 60 addExternCSystemIncludeIfExists(DriverArgs, CC1Args, 61 D.getInstalledDir() + Path); 62 } 63 } 64 65 Tool *MipsLLVMToolChain::buildLinker() const { 66 return new tools::gnutools::Linker(*this); 67 } 68 69 std::string MipsLLVMToolChain::computeSysRoot() const { 70 if (!getDriver().SysRoot.empty()) 71 return getDriver().SysRoot + SelectedMultilib.osSuffix(); 72 73 const std::string InstalledDir(getDriver().getInstalledDir()); 74 std::string SysRootPath = 75 InstalledDir + "/../sysroot" + SelectedMultilib.osSuffix(); 76 if (llvm::sys::fs::exists(SysRootPath)) 77 return SysRootPath; 78 79 return std::string(); 80 } 81 82 ToolChain::CXXStdlibType 83 MipsLLVMToolChain::GetCXXStdlibType(const ArgList &Args) const { 84 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); 85 if (A) { 86 StringRef Value = A->getValue(); 87 if (Value != "libc++") 88 getDriver().Diag(clang::diag::err_drv_invalid_stdlib_name) 89 << A->getAsString(Args); 90 } 91 92 return ToolChain::CST_Libcxx; 93 } 94 95 void MipsLLVMToolChain::addLibCxxIncludePaths( 96 const llvm::opt::ArgList &DriverArgs, 97 llvm::opt::ArgStringList &CC1Args) const { 98 if (const auto &Callback = Multilibs.includeDirsCallback()) { 99 for (std::string Path : Callback(SelectedMultilib)) { 100 Path = getDriver().getInstalledDir() + Path + "/c++/v1"; 101 if (llvm::sys::fs::exists(Path)) { 102 addSystemInclude(DriverArgs, CC1Args, Path); 103 return; 104 } 105 } 106 } 107 } 108 109 void MipsLLVMToolChain::AddCXXStdlibLibArgs(const ArgList &Args, 110 ArgStringList &CmdArgs) const { 111 assert((GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) && 112 "Only -lc++ (aka libxx) is supported in this toolchain."); 113 114 CmdArgs.push_back("-lc++"); 115 CmdArgs.push_back("-lc++abi"); 116 CmdArgs.push_back("-lunwind"); 117 } 118 119 std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args, 120 StringRef Component, 121 FileType Type) const { 122 SmallString<128> Path(getDriver().ResourceDir); 123 llvm::sys::path::append(Path, SelectedMultilib.osSuffix(), "lib" + LibSuffix, 124 getOS()); 125 const char *Suffix; 126 switch (Type) { 127 case ToolChain::FT_Object: 128 Suffix = ".o"; 129 break; 130 case ToolChain::FT_Static: 131 Suffix = ".a"; 132 break; 133 case ToolChain::FT_Shared: 134 Suffix = ".so"; 135 break; 136 } 137 llvm::sys::path::append( 138 Path, Twine("libclang_rt." + Component + "-" + "mips" + Suffix)); 139 return Path.str(); 140 } 141