17 #include "llvm/Option/ArgList.h"
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/Path.h"
20 #include <system_error>
22 using namespace clang::diag;
23 using namespace clang::driver;
24 using namespace clang;
25 using namespace llvm::opt;
32 const char *LinkingOutput)
const {
34 ArgStringList CmdArgs;
36 if (getToolChain().getArch() == llvm::Triple::x86) {
37 CmdArgs.push_back(
"--32");
38 }
else if (getToolChain().getArch() == llvm::Triple::x86_64) {
39 CmdArgs.push_back(
"--64");
42 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
44 CmdArgs.push_back(
"-o");
47 for (
const auto &II : Inputs)
48 CmdArgs.push_back(II.getFilename());
50 const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(
"as"));
51 C.
addCommand(llvm::make_unique<Command>(JA, *
this, Exec, CmdArgs, Inputs));
53 if (Args.hasArg(options::OPT_gsplit_dwarf))
58 void tools::MinGW::Linker::AddLibGCC(
const ArgList &Args,
59 ArgStringList &CmdArgs)
const {
60 if (Args.hasArg(options::OPT_mthreads))
61 CmdArgs.push_back(
"-lmingwthrd");
62 CmdArgs.push_back(
"-lmingw32");
66 if (RLT == ToolChain::RLT_Libgcc) {
67 bool Static = Args.hasArg(options::OPT_static_libgcc) ||
68 Args.hasArg(options::OPT_static);
69 bool Shared = Args.hasArg(options::OPT_shared);
70 bool CXX = getToolChain().getDriver().CCCIsCXX();
72 if (Static || (!CXX && !Shared)) {
73 CmdArgs.push_back(
"-lgcc");
74 CmdArgs.push_back(
"-lgcc_eh");
76 CmdArgs.push_back(
"-lgcc_s");
77 CmdArgs.push_back(
"-lgcc");
80 AddRunTimeLibs(getToolChain(), getToolChain().getDriver(), CmdArgs, Args);
83 CmdArgs.push_back(
"-lmoldname");
84 CmdArgs.push_back(
"-lmingwex");
85 CmdArgs.push_back(
"-lmsvcrt");
92 const char *LinkingOutput)
const {
97 ArgStringList CmdArgs;
100 Args.ClaimAllArgs(options::OPT_g_Group);
102 Args.ClaimAllArgs(options::OPT_emit_llvm);
105 Args.ClaimAllArgs(options::OPT_w);
107 StringRef LinkerName = Args.getLastArgValue(options::OPT_fuse_ld_EQ,
"ld");
108 if (LinkerName.equals_lower(
"lld")) {
109 CmdArgs.push_back(
"-flavor");
110 CmdArgs.push_back(
"gnu");
111 }
else if (!LinkerName.equals_lower(
"ld")) {
112 D.
Diag(diag::err_drv_unsupported_linker) << LinkerName;
116 CmdArgs.push_back(Args.MakeArgString(
"--sysroot=" + D.
SysRoot));
118 if (Args.hasArg(options::OPT_s))
119 CmdArgs.push_back(
"-s");
121 CmdArgs.push_back(
"-m");
122 if (TC.
getArch() == llvm::Triple::x86)
123 CmdArgs.push_back(
"i386pe");
124 if (TC.
getArch() == llvm::Triple::x86_64)
125 CmdArgs.push_back(
"i386pep");
126 if (TC.
getArch() == llvm::Triple::arm)
127 CmdArgs.push_back(
"thumb2pe");
129 if (Args.hasArg(options::OPT_mwindows)) {
130 CmdArgs.push_back(
"--subsystem");
131 CmdArgs.push_back(
"windows");
132 }
else if (Args.hasArg(options::OPT_mconsole)) {
133 CmdArgs.push_back(
"--subsystem");
134 CmdArgs.push_back(
"console");
137 if (Args.hasArg(options::OPT_static))
138 CmdArgs.push_back(
"-Bstatic");
140 if (Args.hasArg(options::OPT_mdll))
141 CmdArgs.push_back(
"--dll");
142 else if (Args.hasArg(options::OPT_shared))
143 CmdArgs.push_back(
"--shared");
144 CmdArgs.push_back(
"-Bdynamic");
145 if (Args.hasArg(options::OPT_mdll) || Args.hasArg(options::OPT_shared)) {
146 CmdArgs.push_back(
"-e");
147 if (TC.
getArch() == llvm::Triple::x86)
148 CmdArgs.push_back(
"_DllMainCRTStartup@12");
150 CmdArgs.push_back(
"DllMainCRTStartup");
151 CmdArgs.push_back(
"--enable-auto-image-base");
155 CmdArgs.push_back(
"-o");
158 Args.AddAllArgs(CmdArgs, options::OPT_e);
160 Args.AddLastArg(CmdArgs, options::OPT_r);
161 Args.AddLastArg(CmdArgs, options::OPT_s);
162 Args.AddLastArg(CmdArgs, options::OPT_t);
163 Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
164 Args.AddLastArg(CmdArgs, options::OPT_Z_Flag);
166 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
167 if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_mdll)) {
168 CmdArgs.push_back(Args.MakeArgString(TC.
GetFilePath(
"dllcrt2.o")));
170 if (Args.hasArg(options::OPT_municode))
171 CmdArgs.push_back(Args.MakeArgString(TC.
GetFilePath(
"crt2u.o")));
173 CmdArgs.push_back(Args.MakeArgString(TC.
GetFilePath(
"crt2.o")));
175 if (Args.hasArg(options::OPT_pg))
176 CmdArgs.push_back(Args.MakeArgString(TC.
GetFilePath(
"gcrt2.o")));
177 CmdArgs.push_back(Args.MakeArgString(TC.
GetFilePath(
"crtbegin.o")));
180 Args.AddAllArgs(CmdArgs, options::OPT_L);
189 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
190 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
191 !Args.hasArg(options::OPT_static);
192 if (OnlyLibstdcxxStatic)
193 CmdArgs.push_back(
"-Bstatic");
195 if (OnlyLibstdcxxStatic)
196 CmdArgs.push_back(
"-Bdynamic");
199 if (!Args.hasArg(options::OPT_nostdlib)) {
200 if (!Args.hasArg(options::OPT_nodefaultlibs)) {
201 if (Args.hasArg(options::OPT_static))
202 CmdArgs.push_back(
"--start-group");
204 if (Args.hasArg(options::OPT_fstack_protector) ||
205 Args.hasArg(options::OPT_fstack_protector_strong) ||
206 Args.hasArg(options::OPT_fstack_protector_all)) {
207 CmdArgs.push_back(
"-lssp_nonshared");
208 CmdArgs.push_back(
"-lssp");
210 if (Args.hasArg(options::OPT_fopenmp))
211 CmdArgs.push_back(
"-lgomp");
213 AddLibGCC(Args, CmdArgs);
215 if (Args.hasArg(options::OPT_pg))
216 CmdArgs.push_back(
"-lgmon");
218 if (Args.hasArg(options::OPT_pthread))
219 CmdArgs.push_back(
"-lpthread");
222 if (Args.hasArg(options::OPT_mwindows)) {
223 CmdArgs.push_back(
"-lgdi32");
224 CmdArgs.push_back(
"-lcomdlg32");
226 CmdArgs.push_back(
"-ladvapi32");
227 CmdArgs.push_back(
"-lshell32");
228 CmdArgs.push_back(
"-luser32");
229 CmdArgs.push_back(
"-lkernel32");
231 if (Args.hasArg(options::OPT_static))
232 CmdArgs.push_back(
"--end-group");
233 else if (!LinkerName.equals_lower(
"lld"))
234 AddLibGCC(Args, CmdArgs);
237 if (!Args.hasArg(options::OPT_nostartfiles)) {
241 CmdArgs.push_back(Args.MakeArgString(TC.
GetFilePath(
"crtend.o")));
244 const char *Exec = Args.MakeArgString(TC.
GetProgramPath(LinkerName.data()));
245 C.
addCommand(llvm::make_unique<Command>(JA, *
this, Exec, CmdArgs, Inputs));
251 auto Version = toolchains::Generic_GCC::GCCVersion::Parse(
"0.0.0");
253 for (llvm::sys::fs::directory_iterator LI(LibDir, EC), LE; !EC && LI != LE;
254 LI = LI.increment(EC)) {
255 StringRef VersionText = llvm::sys::path::filename(LI->path());
256 auto CandidateVersion =
257 toolchains::Generic_GCC::GCCVersion::Parse(VersionText);
258 if (CandidateVersion.Major == -1)
260 if (CandidateVersion <= Version)
263 GccLibDir = LI->path();
268 void toolchains::MinGW::findGccLibDir() {
270 Archs.emplace_back(getTriple().getArchName());
271 Archs[0] +=
"-w64-mingw32";
272 Archs.emplace_back(
"mingw32");
273 Arch = Archs[0].str();
276 for (StringRef CandidateLib : {
"lib",
"lib64"}) {
277 for (StringRef CandidateArch : Archs) {
279 llvm::sys::path::append(LibDir, CandidateLib,
"gcc", CandidateArch);
281 Arch = CandidateArch;
288 llvm::ErrorOr<std::string> toolchains::MinGW::findGcc() {
290 Gccs.emplace_back(getTriple().getArchName());
291 Gccs[0] +=
"-w64-mingw32-gcc";
292 Gccs.emplace_back(
"mingw32-gcc");
294 for (StringRef CandidateGcc : Gccs)
295 if (llvm::ErrorOr<std::string> GPPName = llvm::sys::findProgramByName(CandidateGcc))
300 toolchains::MinGW::MinGW(
const Driver &D,
const llvm::Triple &Triple,
302 :
ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
307 else if (llvm::ErrorOr<std::string> GPPName = findGcc())
308 Base = llvm::sys::path::parent_path(
309 llvm::sys::path::parent_path(GPPName.get()));
311 Base = llvm::sys::path::parent_path(
getDriver().getInstalledDir());
313 Base += llvm::sys::path::get_separator();
319 (
Base + Arch + llvm::sys::path::get_separator() +
"lib").str());
336 return Compiler.get();
351 return getArch() == llvm::Triple::x86_64;
355 return getArch() == llvm::Triple::x86_64;
361 return getArch() == llvm::Triple::x86_64;
365 return getArch() == llvm::Triple::x86_64;
369 ArgStringList &CC1Args)
const {
370 CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
374 CudaInstallation.print(OS);
418 ArgStringList &CC1Args)
const {
419 if (DriverArgs.hasArg(options::OPT_nostdinc))
422 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
424 llvm::sys::path::append(P,
"include");
425 addSystemInclude(DriverArgs, CC1Args, P.str());
428 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
433 addSystemInclude(DriverArgs, CC1Args,
434 Base + Arch +
"/sys-root/mingw/include");
437 addSystemInclude(DriverArgs, CC1Args,
438 Base + Arch + llvm::sys::path::get_separator() +
"include");
439 addSystemInclude(DriverArgs, CC1Args,
Base +
"include");
443 const ArgList &DriverArgs, ArgStringList &CC1Args)
const {
444 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
445 DriverArgs.hasArg(options::OPT_nostdincxx))
448 switch (GetCXXStdlibType(DriverArgs)) {
450 addSystemInclude(DriverArgs, CC1Args,
451 Base +
"include" + llvm::sys::path::get_separator() +
452 "c++" + llvm::sys::path::get_separator() +
"v1");
457 CppIncludeBases.emplace_back(
Base);
458 llvm::sys::path::append(CppIncludeBases[0], Arch,
"include",
"c++");
459 CppIncludeBases.emplace_back(
Base);
460 llvm::sys::path::append(CppIncludeBases[1], Arch,
"include",
"c++", Ver);
461 CppIncludeBases.emplace_back(
Base);
462 llvm::sys::path::append(CppIncludeBases[2],
"include",
"c++", Ver);
463 CppIncludeBases.emplace_back(GccLibDir);
464 llvm::sys::path::append(CppIncludeBases[3],
"include",
"c++");
465 for (
auto &CppIncludeBase : CppIncludeBases) {
466 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase);
467 CppIncludeBase += llvm::sys::path::get_separator();
468 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch);
469 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase +
"backward");
static bool findGccVersion(StringRef LibDir, std::string &GccLibDir, std::string &Ver)
DiagnosticBuilder Diag(unsigned DiagID) const
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
std::error_code make_error_code(BuildPreambleError Error)
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
void addCommand(std::unique_ptr< Command > C)
std::string SysRoot
sysroot, if present
Compilation - A set of tasks to perform for a single driver invocation.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.