xref: /llvm-project/clang/lib/Driver/ToolChains/CSKYToolChain.cpp (revision 10886a8f0a054d8d97708fcfbe03313d81fae35e)
197e49605SZi Xuan Wu //===--- CSKYToolchain.cpp - CSKY ToolChain Implementations ---*- C++ -*-===//
297e49605SZi Xuan Wu //
397e49605SZi Xuan Wu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
497e49605SZi Xuan Wu // See https://llvm.org/LICENSE.txt for license information.
597e49605SZi Xuan Wu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
697e49605SZi Xuan Wu //
797e49605SZi Xuan Wu //===----------------------------------------------------------------------===//
897e49605SZi Xuan Wu 
997e49605SZi Xuan Wu #include "CSKYToolChain.h"
1097e49605SZi Xuan Wu #include "CommonArgs.h"
1197e49605SZi Xuan Wu #include "clang/Driver/Compilation.h"
1297e49605SZi Xuan Wu #include "clang/Driver/InputInfo.h"
1397e49605SZi Xuan Wu #include "clang/Driver/Options.h"
1497e49605SZi Xuan Wu #include "llvm/Option/ArgList.h"
1597e49605SZi Xuan Wu #include "llvm/Support/FileSystem.h"
1697e49605SZi Xuan Wu #include "llvm/Support/Path.h"
1797e49605SZi Xuan Wu #include "llvm/Support/raw_ostream.h"
1897e49605SZi Xuan Wu 
1997e49605SZi Xuan Wu using namespace clang::driver;
2097e49605SZi Xuan Wu using namespace clang::driver::toolchains;
2197e49605SZi Xuan Wu using namespace clang::driver::tools;
2297e49605SZi Xuan Wu using namespace clang;
2397e49605SZi Xuan Wu using namespace llvm::opt;
2497e49605SZi Xuan Wu 
addMultilibsFilePaths(const Driver & D,const MultilibSet & Multilibs,const Multilib & Multilib,StringRef InstallPath,ToolChain::path_list & Paths)2597e49605SZi Xuan Wu static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs,
2697e49605SZi Xuan Wu                                   const Multilib &Multilib,
2797e49605SZi Xuan Wu                                   StringRef InstallPath,
2897e49605SZi Xuan Wu                                   ToolChain::path_list &Paths) {
2997e49605SZi Xuan Wu   if (const auto &PathsCallback = Multilibs.filePathsCallback())
3097e49605SZi Xuan Wu     for (const auto &Path : PathsCallback(Multilib))
3197e49605SZi Xuan Wu       addPathIfExists(D, InstallPath + Path, Paths);
3297e49605SZi Xuan Wu }
3397e49605SZi Xuan Wu 
3497e49605SZi Xuan Wu /// CSKY Toolchain
CSKYToolChain(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)3597e49605SZi Xuan Wu CSKYToolChain::CSKYToolChain(const Driver &D, const llvm::Triple &Triple,
3697e49605SZi Xuan Wu                              const ArgList &Args)
3797e49605SZi Xuan Wu     : Generic_ELF(D, Triple, Args) {
3897e49605SZi Xuan Wu   GCCInstallation.init(Triple, Args);
3997e49605SZi Xuan Wu   if (GCCInstallation.isValid()) {
4097e49605SZi Xuan Wu     Multilibs = GCCInstallation.getMultilibs();
41edc1130cSMichael Platings     SelectedMultilibs.assign({GCCInstallation.getMultilib()});
4297e49605SZi Xuan Wu     path_list &Paths = getFilePaths();
4397e49605SZi Xuan Wu     // Add toolchain/multilib specific file paths.
44edc1130cSMichael Platings     addMultilibsFilePaths(D, Multilibs, SelectedMultilibs.back(),
4597e49605SZi Xuan Wu                           GCCInstallation.getInstallPath(), Paths);
4697e49605SZi Xuan Wu     getFilePaths().push_back(GCCInstallation.getInstallPath().str() +
47edc1130cSMichael Platings                              SelectedMultilibs.back().osSuffix());
4897e49605SZi Xuan Wu     ToolChain::path_list &PPaths = getProgramPaths();
4997e49605SZi Xuan Wu     // Multilib cross-compiler GCC installations put ld in a triple-prefixed
5097e49605SZi Xuan Wu     // directory off of the parent of the GCC installation.
5197e49605SZi Xuan Wu     PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
5297e49605SZi Xuan Wu                            GCCInstallation.getTriple().str() + "/bin")
5397e49605SZi Xuan Wu                          .str());
5497e49605SZi Xuan Wu     PPaths.push_back((GCCInstallation.getParentLibPath() + "/../bin").str());
55edc1130cSMichael Platings     getFilePaths().push_back(computeSysRoot() + "/lib" +
56edc1130cSMichael Platings                              SelectedMultilibs.back().osSuffix());
5797e49605SZi Xuan Wu   } else {
5897e49605SZi Xuan Wu     getProgramPaths().push_back(D.Dir);
59edc1130cSMichael Platings     getFilePaths().push_back(computeSysRoot() + "/lib");
6097e49605SZi Xuan Wu   }
6197e49605SZi Xuan Wu }
6297e49605SZi Xuan Wu 
buildLinker() const6397e49605SZi Xuan Wu Tool *CSKYToolChain::buildLinker() const {
6497e49605SZi Xuan Wu   return new tools::CSKY::Linker(*this);
6597e49605SZi Xuan Wu }
6697e49605SZi Xuan Wu 
GetDefaultRuntimeLibType() const6797e49605SZi Xuan Wu ToolChain::RuntimeLibType CSKYToolChain::GetDefaultRuntimeLibType() const {
6897e49605SZi Xuan Wu   return GCCInstallation.isValid() ? ToolChain::RLT_Libgcc
6997e49605SZi Xuan Wu                                    : ToolChain::RLT_CompilerRT;
7097e49605SZi Xuan Wu }
7197e49605SZi Xuan Wu 
7297e49605SZi Xuan Wu ToolChain::UnwindLibType
GetUnwindLibType(const llvm::opt::ArgList & Args) const7397e49605SZi Xuan Wu CSKYToolChain::GetUnwindLibType(const llvm::opt::ArgList &Args) const {
7497e49605SZi Xuan Wu   return ToolChain::UNW_None;
7597e49605SZi Xuan Wu }
7697e49605SZi Xuan Wu 
addClangTargetOptions(const llvm::opt::ArgList & DriverArgs,llvm::opt::ArgStringList & CC1Args,Action::OffloadKind) const7797e49605SZi Xuan Wu void CSKYToolChain::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
7897e49605SZi Xuan Wu                                           llvm::opt::ArgStringList &CC1Args,
7997e49605SZi Xuan Wu                                           Action::OffloadKind) const {
8097e49605SZi Xuan Wu   CC1Args.push_back("-nostdsysteminc");
8197e49605SZi Xuan Wu }
8297e49605SZi Xuan Wu 
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const8397e49605SZi Xuan Wu void CSKYToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
8497e49605SZi Xuan Wu                                               ArgStringList &CC1Args) const {
8597e49605SZi Xuan Wu   if (DriverArgs.hasArg(options::OPT_nostdinc))
8697e49605SZi Xuan Wu     return;
8797e49605SZi Xuan Wu 
8897e49605SZi Xuan Wu   if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) {
8997e49605SZi Xuan Wu     SmallString<128> Dir(computeSysRoot());
9097e49605SZi Xuan Wu     llvm::sys::path::append(Dir, "include");
9197e49605SZi Xuan Wu     addSystemInclude(DriverArgs, CC1Args, Dir.str());
9297e49605SZi Xuan Wu     SmallString<128> Dir2(computeSysRoot());
9397e49605SZi Xuan Wu     llvm::sys::path::append(Dir2, "sys-include");
9497e49605SZi Xuan Wu     addSystemInclude(DriverArgs, CC1Args, Dir2.str());
9597e49605SZi Xuan Wu   }
9697e49605SZi Xuan Wu }
9797e49605SZi Xuan Wu 
addLibStdCxxIncludePaths(const llvm::opt::ArgList & DriverArgs,llvm::opt::ArgStringList & CC1Args) const9897e49605SZi Xuan Wu void CSKYToolChain::addLibStdCxxIncludePaths(
9997e49605SZi Xuan Wu     const llvm::opt::ArgList &DriverArgs,
10097e49605SZi Xuan Wu     llvm::opt::ArgStringList &CC1Args) const {
10197e49605SZi Xuan Wu   const GCCVersion &Version = GCCInstallation.getVersion();
10297e49605SZi Xuan Wu   StringRef TripleStr = GCCInstallation.getTriple().str();
10397e49605SZi Xuan Wu   const Multilib &Multilib = GCCInstallation.getMultilib();
10497e49605SZi Xuan Wu   addLibStdCXXIncludePaths(computeSysRoot() + "/include/c++/" + Version.Text,
10597e49605SZi Xuan Wu                            TripleStr, Multilib.includeSuffix(), DriverArgs,
10697e49605SZi Xuan Wu                            CC1Args);
10797e49605SZi Xuan Wu }
10897e49605SZi Xuan Wu 
computeSysRoot() const10997e49605SZi Xuan Wu std::string CSKYToolChain::computeSysRoot() const {
11097e49605SZi Xuan Wu   if (!getDriver().SysRoot.empty())
11197e49605SZi Xuan Wu     return getDriver().SysRoot;
11297e49605SZi Xuan Wu 
11397e49605SZi Xuan Wu   SmallString<128> SysRootDir;
11497e49605SZi Xuan Wu   if (GCCInstallation.isValid()) {
11597e49605SZi Xuan Wu     StringRef LibDir = GCCInstallation.getParentLibPath();
11697e49605SZi Xuan Wu     StringRef TripleStr = GCCInstallation.getTriple().str();
11797e49605SZi Xuan Wu     llvm::sys::path::append(SysRootDir, LibDir, "..", TripleStr);
11897e49605SZi Xuan Wu   } else {
11997e49605SZi Xuan Wu     // Use the triple as provided to the driver. Unlike the parsed triple
12097e49605SZi Xuan Wu     // this has not been normalized to always contain every field.
12197e49605SZi Xuan Wu     llvm::sys::path::append(SysRootDir, getDriver().Dir, "..",
12297e49605SZi Xuan Wu                             getDriver().getTargetTriple());
12397e49605SZi Xuan Wu   }
12497e49605SZi Xuan Wu 
12597e49605SZi Xuan Wu   if (!llvm::sys::fs::exists(SysRootDir))
12697e49605SZi Xuan Wu     return std::string();
12797e49605SZi Xuan Wu 
128*10886a8fSKazu Hirata   return std::string(SysRootDir);
12997e49605SZi Xuan Wu }
13097e49605SZi Xuan Wu 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const13197e49605SZi Xuan Wu void CSKY::Linker::ConstructJob(Compilation &C, const JobAction &JA,
13297e49605SZi Xuan Wu                                 const InputInfo &Output,
13397e49605SZi Xuan Wu                                 const InputInfoList &Inputs,
13497e49605SZi Xuan Wu                                 const ArgList &Args,
13597e49605SZi Xuan Wu                                 const char *LinkingOutput) const {
13697e49605SZi Xuan Wu   const ToolChain &ToolChain = getToolChain();
13797e49605SZi Xuan Wu   const Driver &D = ToolChain.getDriver();
13897e49605SZi Xuan Wu   ArgStringList CmdArgs;
13997e49605SZi Xuan Wu 
14097e49605SZi Xuan Wu   if (!D.SysRoot.empty())
14197e49605SZi Xuan Wu     CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
14297e49605SZi Xuan Wu 
14397e49605SZi Xuan Wu   CmdArgs.push_back("-m");
14497e49605SZi Xuan Wu   CmdArgs.push_back("cskyelf");
14597e49605SZi Xuan Wu 
14697e49605SZi Xuan Wu   std::string Linker = getToolChain().GetLinkerPath();
14797e49605SZi Xuan Wu 
14897e49605SZi Xuan Wu   bool WantCRTs =
14997e49605SZi Xuan Wu       !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles);
15097e49605SZi Xuan Wu 
15197e49605SZi Xuan Wu   const char *crtbegin, *crtend;
15297e49605SZi Xuan Wu   auto RuntimeLib = ToolChain.GetRuntimeLibType(Args);
15397e49605SZi Xuan Wu   if (RuntimeLib == ToolChain::RLT_Libgcc) {
15497e49605SZi Xuan Wu     crtbegin = "crtbegin.o";
15597e49605SZi Xuan Wu     crtend = "crtend.o";
15697e49605SZi Xuan Wu   } else {
15797e49605SZi Xuan Wu     assert(RuntimeLib == ToolChain::RLT_CompilerRT);
15897e49605SZi Xuan Wu     crtbegin = ToolChain.getCompilerRTArgString(Args, "crtbegin",
15997e49605SZi Xuan Wu                                                 ToolChain::FT_Object);
16097e49605SZi Xuan Wu     crtend =
16197e49605SZi Xuan Wu         ToolChain.getCompilerRTArgString(Args, "crtend", ToolChain::FT_Object);
16297e49605SZi Xuan Wu   }
16397e49605SZi Xuan Wu 
16497e49605SZi Xuan Wu   if (WantCRTs) {
16597e49605SZi Xuan Wu     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
16697e49605SZi Xuan Wu     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
16797e49605SZi Xuan Wu     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
16897e49605SZi Xuan Wu   }
16997e49605SZi Xuan Wu 
17097e49605SZi Xuan Wu   Args.AddAllArgs(CmdArgs, options::OPT_L);
17197e49605SZi Xuan Wu   ToolChain.AddFilePathLibArgs(Args, CmdArgs);
172993e8394SFangrui Song   Args.addAllArgs(CmdArgs, {options::OPT_T_Group, options::OPT_s,
173993e8394SFangrui Song                             options::OPT_t, options::OPT_r});
17497e49605SZi Xuan Wu 
17597e49605SZi Xuan Wu   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
17697e49605SZi Xuan Wu 
17797e49605SZi Xuan Wu   // TODO: add C++ includes and libs if compiling C++.
17897e49605SZi Xuan Wu 
17997e49605SZi Xuan Wu   if (!Args.hasArg(options::OPT_nostdlib) &&
18097e49605SZi Xuan Wu       !Args.hasArg(options::OPT_nodefaultlibs)) {
18197e49605SZi Xuan Wu     if (ToolChain.ShouldLinkCXXStdlib(Args))
18297e49605SZi Xuan Wu       ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
18397e49605SZi Xuan Wu     CmdArgs.push_back("--start-group");
18497e49605SZi Xuan Wu     CmdArgs.push_back("-lc");
18597e49605SZi Xuan Wu     if (Args.hasArg(options::OPT_msim))
18697e49605SZi Xuan Wu       CmdArgs.push_back("-lsemi");
18797e49605SZi Xuan Wu     else
18897e49605SZi Xuan Wu       CmdArgs.push_back("-lnosys");
18997e49605SZi Xuan Wu     CmdArgs.push_back("--end-group");
19097e49605SZi Xuan Wu     AddRunTimeLibs(ToolChain, ToolChain.getDriver(), CmdArgs, Args);
19197e49605SZi Xuan Wu   }
19297e49605SZi Xuan Wu 
19397e49605SZi Xuan Wu   if (WantCRTs) {
19497e49605SZi Xuan Wu     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
19597e49605SZi Xuan Wu     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
19697e49605SZi Xuan Wu   }
19797e49605SZi Xuan Wu 
19897e49605SZi Xuan Wu   CmdArgs.push_back("-o");
19997e49605SZi Xuan Wu   CmdArgs.push_back(Output.getFilename());
20097e49605SZi Xuan Wu   C.addCommand(std::make_unique<Command>(
20197e49605SZi Xuan Wu       JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker),
20297e49605SZi Xuan Wu       CmdArgs, Inputs, Output));
20397e49605SZi Xuan Wu }
20497e49605SZi Xuan Wu // CSKY tools end.
205