204 lines · cpp
1//===--- CSKYToolchain.cpp - CSKY 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "CSKYToolChain.h"10#include "clang/Driver/CommonArgs.h"11#include "clang/Driver/Compilation.h"12#include "clang/Driver/InputInfo.h"13#include "clang/Options/Options.h"14#include "llvm/Option/ArgList.h"15#include "llvm/Support/FileSystem.h"16#include "llvm/Support/Path.h"17 18using namespace clang::driver;19using namespace clang::driver::toolchains;20using namespace clang::driver::tools;21using namespace clang;22using namespace llvm::opt;23 24static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs,25 const Multilib &Multilib,26 StringRef InstallPath,27 ToolChain::path_list &Paths) {28 if (const auto &PathsCallback = Multilibs.filePathsCallback())29 for (const auto &Path : PathsCallback(Multilib))30 addPathIfExists(D, InstallPath + Path, Paths);31}32 33/// CSKY Toolchain34CSKYToolChain::CSKYToolChain(const Driver &D, const llvm::Triple &Triple,35 const ArgList &Args)36 : Generic_ELF(D, Triple, Args) {37 GCCInstallation.init(Triple, Args);38 if (GCCInstallation.isValid()) {39 Multilibs = GCCInstallation.getMultilibs();40 SelectedMultilibs.assign({GCCInstallation.getMultilib()});41 path_list &Paths = getFilePaths();42 // Add toolchain/multilib specific file paths.43 addMultilibsFilePaths(D, Multilibs, SelectedMultilibs.back(),44 GCCInstallation.getInstallPath(), Paths);45 getFilePaths().push_back(GCCInstallation.getInstallPath().str() +46 SelectedMultilibs.back().osSuffix());47 ToolChain::path_list &PPaths = getProgramPaths();48 // Multilib cross-compiler GCC installations put ld in a triple-prefixed49 // directory off of the parent of the GCC installation.50 PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +51 GCCInstallation.getTriple().str() + "/bin")52 .str());53 PPaths.push_back((GCCInstallation.getParentLibPath() + "/../bin").str());54 getFilePaths().push_back(computeSysRoot() + "/lib" +55 SelectedMultilibs.back().osSuffix());56 } else {57 getProgramPaths().push_back(D.Dir);58 getFilePaths().push_back(computeSysRoot() + "/lib");59 }60}61 62Tool *CSKYToolChain::buildLinker() const {63 return new tools::CSKY::Linker(*this);64}65 66ToolChain::RuntimeLibType CSKYToolChain::GetDefaultRuntimeLibType() const {67 return GCCInstallation.isValid() ? ToolChain::RLT_Libgcc68 : ToolChain::RLT_CompilerRT;69}70 71ToolChain::UnwindLibType72CSKYToolChain::GetUnwindLibType(const llvm::opt::ArgList &Args) const {73 return ToolChain::UNW_None;74}75 76void CSKYToolChain::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,77 llvm::opt::ArgStringList &CC1Args,78 Action::OffloadKind) const {79 CC1Args.push_back("-nostdsysteminc");80}81 82void CSKYToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,83 ArgStringList &CC1Args) const {84 if (DriverArgs.hasArg(options::OPT_nostdinc))85 return;86 87 if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) {88 SmallString<128> Dir(computeSysRoot());89 llvm::sys::path::append(Dir, "include");90 addSystemInclude(DriverArgs, CC1Args, Dir.str());91 SmallString<128> Dir2(computeSysRoot());92 llvm::sys::path::append(Dir2, "sys-include");93 addSystemInclude(DriverArgs, CC1Args, Dir2.str());94 }95}96 97void CSKYToolChain::addLibStdCxxIncludePaths(98 const llvm::opt::ArgList &DriverArgs,99 llvm::opt::ArgStringList &CC1Args) const {100 const GCCVersion &Version = GCCInstallation.getVersion();101 StringRef TripleStr = GCCInstallation.getTriple().str();102 const Multilib &Multilib = GCCInstallation.getMultilib();103 addLibStdCXXIncludePaths(computeSysRoot() + "/include/c++/" + Version.Text,104 TripleStr, Multilib.includeSuffix(), DriverArgs,105 CC1Args);106}107 108std::string CSKYToolChain::computeSysRoot() const {109 if (!getDriver().SysRoot.empty())110 return getDriver().SysRoot;111 112 SmallString<128> SysRootDir;113 if (GCCInstallation.isValid()) {114 StringRef LibDir = GCCInstallation.getParentLibPath();115 StringRef TripleStr = GCCInstallation.getTriple().str();116 llvm::sys::path::append(SysRootDir, LibDir, "..", TripleStr);117 } else {118 // Use the triple as provided to the driver. Unlike the parsed triple119 // this has not been normalized to always contain every field.120 llvm::sys::path::append(SysRootDir, getDriver().Dir, "..",121 getDriver().getTargetTriple());122 }123 124 if (!llvm::sys::fs::exists(SysRootDir))125 return std::string();126 127 return std::string(SysRootDir);128}129 130void CSKY::Linker::ConstructJob(Compilation &C, const JobAction &JA,131 const InputInfo &Output,132 const InputInfoList &Inputs,133 const ArgList &Args,134 const char *LinkingOutput) const {135 const ToolChain &ToolChain = getToolChain();136 const Driver &D = ToolChain.getDriver();137 ArgStringList CmdArgs;138 139 if (!D.SysRoot.empty())140 CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));141 142 CmdArgs.push_back("-m");143 CmdArgs.push_back("cskyelf");144 145 std::string Linker = getToolChain().GetLinkerPath();146 147 bool WantCRTs =148 !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles);149 150 const char *crtbegin, *crtend;151 auto RuntimeLib = ToolChain.GetRuntimeLibType(Args);152 if (RuntimeLib == ToolChain::RLT_Libgcc) {153 crtbegin = "crtbegin.o";154 crtend = "crtend.o";155 } else {156 assert(RuntimeLib == ToolChain::RLT_CompilerRT);157 crtbegin = ToolChain.getCompilerRTArgString(Args, "crtbegin",158 ToolChain::FT_Object);159 crtend =160 ToolChain.getCompilerRTArgString(Args, "crtend", ToolChain::FT_Object);161 }162 163 if (WantCRTs) {164 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));165 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));166 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));167 }168 169 Args.AddAllArgs(CmdArgs, options::OPT_L);170 ToolChain.AddFilePathLibArgs(Args, CmdArgs);171 Args.addAllArgs(CmdArgs, {options::OPT_T_Group, options::OPT_s,172 options::OPT_t, options::OPT_r});173 174 AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);175 176 // TODO: add C++ includes and libs if compiling C++.177 178 if (!Args.hasArg(options::OPT_nostdlib) &&179 !Args.hasArg(options::OPT_nodefaultlibs)) {180 if (ToolChain.ShouldLinkCXXStdlib(Args))181 ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);182 CmdArgs.push_back("--start-group");183 CmdArgs.push_back("-lc");184 if (Args.hasArg(options::OPT_msim))185 CmdArgs.push_back("-lsemi");186 else187 CmdArgs.push_back("-lnosys");188 CmdArgs.push_back("--end-group");189 AddRunTimeLibs(ToolChain, ToolChain.getDriver(), CmdArgs, Args);190 }191 192 if (WantCRTs) {193 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));194 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));195 }196 197 CmdArgs.push_back("-o");198 CmdArgs.push_back(Output.getFilename());199 C.addCommand(std::make_unique<Command>(200 JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker),201 CmdArgs, Inputs, Output));202}203// CSKY tools end.204