clang  15.0.0git
DragonFly.cpp
Go to the documentation of this file.
1 //===--- DragonFly.cpp - DragonFly 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 "DragonFly.h"
10 #include "CommonArgs.h"
12 #include "clang/Driver/Driver.h"
13 #include "clang/Driver/Options.h"
14 #include "llvm/Option/ArgList.h"
15 
16 using namespace clang::driver;
17 using namespace clang::driver::tools;
18 using namespace clang::driver::toolchains;
19 using namespace clang;
20 using namespace llvm::opt;
21 
22 /// DragonFly Tools
23 
24 // For now, DragonFly Assemble does just about the same as for
25 // FreeBSD, but this may change soon.
27  const InputInfo &Output,
28  const InputInfoList &Inputs,
29  const ArgList &Args,
30  const char *LinkingOutput) const {
31  claimNoWarnArgs(Args);
32  ArgStringList CmdArgs;
33 
34  // When building 32-bit code on DragonFly/pc64, we have to explicitly
35  // instruct as in the base system to assemble 32-bit code.
36  if (getToolChain().getArch() == llvm::Triple::x86)
37  CmdArgs.push_back("--32");
38 
39  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
40 
41  CmdArgs.push_back("-o");
42  CmdArgs.push_back(Output.getFilename());
43 
44  for (const auto &II : Inputs)
45  CmdArgs.push_back(II.getFilename());
46 
47  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
48  C.addCommand(std::make_unique<Command>(JA, *this,
50  Exec, CmdArgs, Inputs, Output));
51 }
52 
54  const InputInfo &Output,
55  const InputInfoList &Inputs,
56  const ArgList &Args,
57  const char *LinkingOutput) const {
58  const Driver &D = getToolChain().getDriver();
59  ArgStringList CmdArgs;
60 
61  if (!D.SysRoot.empty())
62  CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
63 
64  CmdArgs.push_back("--eh-frame-hdr");
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  CmdArgs.push_back("-dynamic-linker");
74  CmdArgs.push_back("/usr/libexec/ld-elf.so.2");
75  }
76  CmdArgs.push_back("--hash-style=gnu");
77  CmdArgs.push_back("--enable-new-dtags");
78  }
79 
80  // When building 32-bit code on DragonFly/pc64, we have to explicitly
81  // instruct ld in the base system to link 32-bit code.
82  if (getToolChain().getArch() == llvm::Triple::x86) {
83  CmdArgs.push_back("-m");
84  CmdArgs.push_back("elf_i386");
85  }
86 
87  if (Output.isFilename()) {
88  CmdArgs.push_back("-o");
89  CmdArgs.push_back(Output.getFilename());
90  } else {
91  assert(Output.isNothing() && "Invalid output.");
92  }
93 
94  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
95  options::OPT_r)) {
96  if (!Args.hasArg(options::OPT_shared)) {
97  if (Args.hasArg(options::OPT_pg))
98  CmdArgs.push_back(
99  Args.MakeArgString(getToolChain().GetFilePath("gcrt1.o")));
100  else {
101  if (Args.hasArg(options::OPT_pie))
102  CmdArgs.push_back(
103  Args.MakeArgString(getToolChain().GetFilePath("Scrt1.o")));
104  else
105  CmdArgs.push_back(
106  Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
107  }
108  }
109  CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
110  if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
111  CmdArgs.push_back(
112  Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
113  else
114  CmdArgs.push_back(
115  Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
116  }
117 
118  Args.AddAllArgs(CmdArgs,
119  {options::OPT_L, options::OPT_T_Group, options::OPT_e});
120 
121  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
122 
123  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
124  options::OPT_r)) {
125  CmdArgs.push_back("-L/usr/lib/gcc80");
126 
127  if (!Args.hasArg(options::OPT_static)) {
128  CmdArgs.push_back("-rpath");
129  CmdArgs.push_back("/usr/lib/gcc80");
130  }
131 
132  if (D.CCCIsCXX()) {
133  if (getToolChain().ShouldLinkCXXStdlib(Args))
134  getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
135  CmdArgs.push_back("-lm");
136  }
137 
138  if (Args.hasArg(options::OPT_pthread))
139  CmdArgs.push_back("-lpthread");
140 
141  if (!Args.hasArg(options::OPT_nolibc)) {
142  CmdArgs.push_back("-lc");
143  }
144 
145  if (Args.hasArg(options::OPT_static) ||
146  Args.hasArg(options::OPT_static_libgcc)) {
147  CmdArgs.push_back("-lgcc");
148  CmdArgs.push_back("-lgcc_eh");
149  } else {
150  if (Args.hasArg(options::OPT_shared_libgcc)) {
151  CmdArgs.push_back("-lgcc_pic");
152  if (!Args.hasArg(options::OPT_shared))
153  CmdArgs.push_back("-lgcc");
154  } else {
155  CmdArgs.push_back("-lgcc");
156  CmdArgs.push_back("--as-needed");
157  CmdArgs.push_back("-lgcc_pic");
158  CmdArgs.push_back("--no-as-needed");
159  }
160  }
161  }
162 
163  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
164  options::OPT_r)) {
165  if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
166  CmdArgs.push_back(
167  Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
168  else
169  CmdArgs.push_back(
170  Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
171  CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
172  }
173 
174  getToolChain().addProfileRTLibs(Args, CmdArgs);
175 
176  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
177  C.addCommand(std::make_unique<Command>(JA, *this,
179  Exec, CmdArgs, Inputs, Output));
180 }
181 
182 /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
183 
184 DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple,
185  const ArgList &Args)
186  : Generic_ELF(D, Triple, Args) {
187 
188  // Path mangling to find libexec
189  getProgramPaths().push_back(getDriver().getInstalledDir());
190  if (getDriver().getInstalledDir() != getDriver().Dir)
191  getProgramPaths().push_back(getDriver().Dir);
192 
193  getFilePaths().push_back(getDriver().Dir + "/../lib");
194  getFilePaths().push_back("/usr/lib");
195  getFilePaths().push_back("/usr/lib/gcc80");
196 }
197 
199  return new tools::dragonfly::Assembler(*this);
200 }
201 
203  return new tools::dragonfly::Linker(*this);
204 }
clang::driver::toolchains
Definition: AIX.h:55
clang::driver::ToolChain::getProgramPaths
path_list & getProgramPaths()
Definition: ToolChain.h:269
Driver.h
llvm::SmallVector
Definition: LLVM.h:38
clang::driver::tools
Definition: AIX.h:17
clang::driver::ToolChain::getDriver
const Driver & getDriver() const
Definition: ToolChain.h:228
clang::driver::InputInfo
InputInfo - Wrapper for information about an input source.
Definition: InputInfo.h:22
clang::driver::tools::AddLinkerInputs
void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const JobAction &JA)
clang::driver::ToolChain::getFilePaths
path_list & getFilePaths()
Definition: ToolChain.h:266
clang::driver::toolchains::DragonFly::buildAssembler
Tool * buildAssembler() const override
Definition: DragonFly.cpp:198
clang::driver::Tool
Tool - Information on a specific compilation tool.
Definition: Tool.h:32
clang::driver::toolchains::Generic_ELF
Definition: Gnu.h:362
clang::driver::tools::claimNoWarnArgs
void claimNoWarnArgs(const llvm::opt::ArgList &Args)
Options.h
clang::driver::InputInfo::isFilename
bool isFilename() const
Definition: InputInfo.h:75
llvm::opt
Definition: DiagnosticOptions.h:19
clang::driver::tools::dragonfly::Linker::ConstructJob
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition: DragonFly.cpp:53
clang::driver::ResponseFileSupport::AtFileCurCP
static constexpr ResponseFileSupport AtFileCurCP()
Definition: Job.h:92
clang::driver::InputInfo::isNothing
bool isNothing() const
Definition: InputInfo.h:74
clang::driver::tools::dragonfly::Assembler::ConstructJob
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
DragonFly Tools.
Definition: DragonFly.cpp:26
clang::driver::Driver::SysRoot
std::string SysRoot
sysroot, if present
Definition: Driver.h:178
clang::driver::Driver::CCCIsCXX
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
Definition: Driver.h:208
clang::driver::tools::dragonfly::Linker
Definition: DragonFly.h:34
Compilation.h
clang::driver::Compilation
Compilation - A set of tasks to perform for a single driver invocation.
Definition: Compilation.h:45
clang::driver::tools::dragonfly::Assembler
Definition: DragonFly.h:21
clang::driver::InputInfo::getFilename
const char * getFilename() const
Definition: InputInfo.h:83
CommonArgs.h
clang
Definition: CalledOnceCheck.h:17
clang::driver::Driver
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:72
clang::driver
Definition: Action.h:31
clang::driver::toolchains::DragonFly::buildLinker
Tool * buildLinker() const override
Definition: DragonFly.cpp:202
clang::driver::JobAction
Definition: Action.h:395
DragonFly.h