1 //===--- Ananas.cpp - Ananas 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 "Ananas.h" 10 #include "InputInfo.h" 11 #include "CommonArgs.h" 12 #include "clang/Driver/Compilation.h" 13 #include "clang/Driver/Driver.h" 14 #include "clang/Driver/Options.h" 15 #include "llvm/ADT/SmallString.h" 16 #include "llvm/Option/ArgList.h" 17 #include "llvm/Support/Path.h" 18 19 using namespace clang::driver; 20 using namespace clang::driver::tools; 21 using namespace clang::driver::toolchains; 22 using namespace clang; 23 using namespace llvm::opt; 24 25 void ananas::Assembler::ConstructJob(Compilation &C, const JobAction &JA, 26 const InputInfo &Output, 27 const InputInfoList &Inputs, 28 const ArgList &Args, 29 const char *LinkingOutput) const { 30 claimNoWarnArgs(Args); 31 ArgStringList CmdArgs; 32 33 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); 34 35 CmdArgs.push_back("-o"); 36 CmdArgs.push_back(Output.getFilename()); 37 38 for (const auto &II : Inputs) 39 CmdArgs.push_back(II.getFilename()); 40 41 const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); 42 C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 43 } 44 45 void ananas::Linker::ConstructJob(Compilation &C, const JobAction &JA, 46 const InputInfo &Output, 47 const InputInfoList &Inputs, 48 const ArgList &Args, 49 const char *LinkingOutput) const { 50 const ToolChain &ToolChain = getToolChain(); 51 const Driver &D = ToolChain.getDriver(); 52 ArgStringList CmdArgs; 53 54 // Silence warning for "clang -g foo.o -o foo" 55 Args.ClaimAllArgs(options::OPT_g_Group); 56 // and "clang -emit-llvm foo.o -o foo" 57 Args.ClaimAllArgs(options::OPT_emit_llvm); 58 // and for "clang -w foo.o -o foo". Other warning options are already 59 // handled somewhere else. 60 Args.ClaimAllArgs(options::OPT_w); 61 62 if (!D.SysRoot.empty()) 63 CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 64 65 if (Args.hasArg(options::OPT_static)) { 66 CmdArgs.push_back("-Bstatic"); 67 } else { 68 if (Args.hasArg(options::OPT_rdynamic)) 69 CmdArgs.push_back("-export-dynamic"); 70 if (Args.hasArg(options::OPT_shared)) { 71 CmdArgs.push_back("-Bshareable"); 72 } else { 73 Args.AddAllArgs(CmdArgs, options::OPT_pie); 74 CmdArgs.push_back("-dynamic-linker"); 75 CmdArgs.push_back("/lib/ld-ananas.so"); 76 } 77 } 78 79 if (Output.isFilename()) { 80 CmdArgs.push_back("-o"); 81 CmdArgs.push_back(Output.getFilename()); 82 } else { 83 assert(Output.isNothing() && "Invalid output."); 84 } 85 86 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { 87 if (!Args.hasArg(options::OPT_shared)) { 88 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); 89 } 90 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); 91 if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) { 92 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbeginS.o"))); 93 } else { 94 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o"))); 95 } 96 } 97 98 Args.AddAllArgs(CmdArgs, options::OPT_L); 99 ToolChain.AddFilePathLibArgs(Args, CmdArgs); 100 Args.AddAllArgs(CmdArgs, 101 {options::OPT_T_Group, options::OPT_e, options::OPT_s, 102 options::OPT_t, options::OPT_Z_Flag, options::OPT_r}); 103 104 if (D.isUsingLTO()) { 105 assert(!Inputs.empty() && "Must have at least one input."); 106 AddGoldPlugin(ToolChain, Args, CmdArgs, Output, Inputs[0], 107 D.getLTOMode() == LTOK_Thin); 108 } 109 110 AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); 111 112 if (ToolChain.ShouldLinkCXXStdlib(Args)) 113 ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); 114 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) 115 CmdArgs.push_back("-lc"); 116 117 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { 118 if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) 119 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o"))); 120 else 121 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o"))); 122 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); 123 } 124 125 const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); 126 C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 127 } 128 129 // Ananas - Ananas tool chain which can call as(1) and ld(1) directly. 130 131 Ananas::Ananas(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) 132 : Generic_ELF(D, Triple, Args) { 133 getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); 134 } 135 136 Tool *Ananas::buildAssembler() const { 137 return new tools::ananas::Assembler(*this); 138 } 139 140 Tool *Ananas::buildLinker() const { return new tools::ananas::Linker(*this); } 141