]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Driver/ToolChains/DragonFly.cpp
Merge clang trunk r300422 and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / Driver / ToolChains / DragonFly.cpp
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"
12 #include "clang/Driver/Compilation.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.
27 void dragonfly::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
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
52 void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA,
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       getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
131       CmdArgs.push_back("-lm");
132     }
133
134     if (Args.hasArg(options::OPT_pthread))
135       CmdArgs.push_back("-lpthread");
136
137     if (!Args.hasArg(options::OPT_nolibc)) {
138       CmdArgs.push_back("-lc");
139     }
140
141     if (Args.hasArg(options::OPT_static) ||
142         Args.hasArg(options::OPT_static_libgcc)) {
143         CmdArgs.push_back("-lgcc");
144         CmdArgs.push_back("-lgcc_eh");
145     } else {
146       if (Args.hasArg(options::OPT_shared_libgcc)) {
147           CmdArgs.push_back("-lgcc_pic");
148           if (!Args.hasArg(options::OPT_shared))
149             CmdArgs.push_back("-lgcc");
150       } else {
151           CmdArgs.push_back("-lgcc");
152           CmdArgs.push_back("--as-needed");
153           CmdArgs.push_back("-lgcc_pic");
154           CmdArgs.push_back("--no-as-needed");
155       }
156     }
157   }
158
159   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
160     if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
161       CmdArgs.push_back(
162           Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
163     else
164       CmdArgs.push_back(
165           Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
166     CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
167   }
168
169   getToolChain().addProfileRTLibs(Args, CmdArgs);
170
171   const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
172   C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
173 }
174
175 /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
176
177 DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple,
178                      const ArgList &Args)
179     : Generic_ELF(D, Triple, Args) {
180
181   // Path mangling to find libexec
182   getProgramPaths().push_back(getDriver().getInstalledDir());
183   if (getDriver().getInstalledDir() != getDriver().Dir)
184     getProgramPaths().push_back(getDriver().Dir);
185
186   getFilePaths().push_back(getDriver().Dir + "/../lib");
187   getFilePaths().push_back("/usr/lib");
188   getFilePaths().push_back("/usr/lib/gcc50");
189 }
190
191 Tool *DragonFly::buildAssembler() const {
192   return new tools::dragonfly::Assembler(*this);
193 }
194
195 Tool *DragonFly::buildLinker() const {
196   return new tools::dragonfly::Linker(*this);
197 }