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