13 #include "clang/Config/config.h" 19 #include "llvm/Option/ArgList.h" 20 #include "llvm/Support/FileSystem.h" 21 #include "llvm/Support/Path.h" 22 #include <system_error> 26 using namespace clang;
34 const char *LinkingOutput)
const {
36 ArgStringList CmdArgs;
38 if (getToolChain().getArch() == llvm::Triple::x86) {
39 CmdArgs.push_back(
"--32");
40 }
else if (getToolChain().getArch() == llvm::Triple::x86_64) {
41 CmdArgs.push_back(
"--64");
44 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
46 CmdArgs.push_back(
"-o");
49 for (
const auto &II : Inputs)
50 CmdArgs.push_back(II.getFilename());
52 const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(
"as"));
53 C.
addCommand(llvm::make_unique<Command>(JA, *
this, Exec, CmdArgs, Inputs));
55 if (Args.hasArg(options::OPT_gsplit_dwarf))
60 void tools::MinGW::Linker::AddLibGCC(
const ArgList &Args,
61 ArgStringList &CmdArgs)
const {
62 if (Args.hasArg(options::OPT_mthreads))
63 CmdArgs.push_back(
"-lmingwthrd");
64 CmdArgs.push_back(
"-lmingw32");
68 if (RLT == ToolChain::RLT_Libgcc) {
69 bool Static = Args.hasArg(options::OPT_static_libgcc) ||
70 Args.hasArg(options::OPT_static);
71 bool Shared = Args.hasArg(options::OPT_shared);
72 bool CXX = getToolChain().getDriver().CCCIsCXX();
74 if (Static || (!CXX && !Shared)) {
75 CmdArgs.push_back(
"-lgcc");
76 CmdArgs.push_back(
"-lgcc_eh");
78 CmdArgs.push_back(
"-lgcc_s");
79 CmdArgs.push_back(
"-lgcc");
82 AddRunTimeLibs(getToolChain(), getToolChain().getDriver(), CmdArgs, Args);
85 CmdArgs.push_back(
"-lmoldname");
86 CmdArgs.push_back(
"-lmingwex");
87 for (
auto Lib : Args.getAllArgValues(options::OPT_l))
88 if (StringRef(Lib).startswith(
"msvcr") || StringRef(Lib).startswith(
"ucrt"))
90 CmdArgs.push_back(
"-lmsvcrt");
97 const char *LinkingOutput)
const {
102 ArgStringList CmdArgs;
105 Args.ClaimAllArgs(options::OPT_g_Group);
107 Args.ClaimAllArgs(options::OPT_emit_llvm);
110 Args.ClaimAllArgs(options::OPT_w);
113 CmdArgs.push_back(Args.MakeArgString(
"--sysroot=" + D.
SysRoot));
115 if (Args.hasArg(options::OPT_s))
116 CmdArgs.push_back(
"-s");
118 CmdArgs.push_back(
"-m");
120 case llvm::Triple::x86:
121 CmdArgs.push_back(
"i386pe");
123 case llvm::Triple::x86_64:
124 CmdArgs.push_back(
"i386pep");
126 case llvm::Triple::arm:
127 case llvm::Triple::thumb:
129 CmdArgs.push_back(
"thumb2pe");
131 case llvm::Triple::aarch64:
132 CmdArgs.push_back(
"arm64pe");
135 llvm_unreachable(
"Unsupported target architecture.");
138 if (Args.hasArg(options::OPT_mwindows)) {
139 CmdArgs.push_back(
"--subsystem");
140 CmdArgs.push_back(
"windows");
141 }
else if (Args.hasArg(options::OPT_mconsole)) {
142 CmdArgs.push_back(
"--subsystem");
143 CmdArgs.push_back(
"console");
146 if (Args.hasArg(options::OPT_mdll))
147 CmdArgs.push_back(
"--dll");
148 else if (Args.hasArg(options::OPT_shared))
149 CmdArgs.push_back(
"--shared");
150 if (Args.hasArg(options::OPT_static))
151 CmdArgs.push_back(
"-Bstatic");
153 CmdArgs.push_back(
"-Bdynamic");
154 if (Args.hasArg(options::OPT_mdll) || Args.hasArg(options::OPT_shared)) {
155 CmdArgs.push_back(
"-e");
156 if (TC.
getArch() == llvm::Triple::x86)
157 CmdArgs.push_back(
"_DllMainCRTStartup@12");
159 CmdArgs.push_back(
"DllMainCRTStartup");
160 CmdArgs.push_back(
"--enable-auto-image-base");
163 CmdArgs.push_back(
"-o");
166 Args.AddAllArgs(CmdArgs, options::OPT_e);
168 Args.AddLastArg(CmdArgs, options::OPT_r);
169 Args.AddLastArg(CmdArgs, options::OPT_s);
170 Args.AddLastArg(CmdArgs, options::OPT_t);
171 Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
172 Args.AddLastArg(CmdArgs, options::OPT_Z_Flag);
174 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
175 if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_mdll)) {
176 CmdArgs.push_back(Args.MakeArgString(TC.
GetFilePath(
"dllcrt2.o")));
178 if (Args.hasArg(options::OPT_municode))
179 CmdArgs.push_back(Args.MakeArgString(TC.
GetFilePath(
"crt2u.o")));
181 CmdArgs.push_back(Args.MakeArgString(TC.
GetFilePath(
"crt2.o")));
183 if (Args.hasArg(options::OPT_pg))
184 CmdArgs.push_back(Args.MakeArgString(TC.
GetFilePath(
"gcrt2.o")));
185 CmdArgs.push_back(Args.MakeArgString(TC.
GetFilePath(
"crtbegin.o")));
188 Args.AddAllArgs(CmdArgs, options::OPT_L);
195 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
196 !Args.hasArg(options::OPT_static);
197 if (OnlyLibstdcxxStatic)
198 CmdArgs.push_back(
"-Bstatic");
200 if (OnlyLibstdcxxStatic)
201 CmdArgs.push_back(
"-Bdynamic");
204 bool HasWindowsApp =
false;
205 for (
auto Lib : Args.getAllArgValues(options::OPT_l)) {
206 if (Lib ==
"windowsapp") {
207 HasWindowsApp =
true;
212 if (!Args.hasArg(options::OPT_nostdlib)) {
213 if (!Args.hasArg(options::OPT_nodefaultlibs)) {
214 if (Args.hasArg(options::OPT_static))
215 CmdArgs.push_back(
"--start-group");
217 if (Args.hasArg(options::OPT_fstack_protector) ||
218 Args.hasArg(options::OPT_fstack_protector_strong) ||
219 Args.hasArg(options::OPT_fstack_protector_all)) {
220 CmdArgs.push_back(
"-lssp_nonshared");
221 CmdArgs.push_back(
"-lssp");
224 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
225 options::OPT_fno_openmp,
false)) {
227 case Driver::OMPRT_OMP:
228 CmdArgs.push_back(
"-lomp");
230 case Driver::OMPRT_IOMP5:
231 CmdArgs.push_back(
"-liomp5md");
233 case Driver::OMPRT_GOMP:
234 CmdArgs.push_back(
"-lgomp");
236 case Driver::OMPRT_Unknown:
242 AddLibGCC(Args, CmdArgs);
244 if (Args.hasArg(options::OPT_pg))
245 CmdArgs.push_back(
"-lgmon");
247 if (Args.hasArg(options::OPT_pthread))
248 CmdArgs.push_back(
"-lpthread");
256 CmdArgs.push_back(Args.MakeArgString(
"--require-defined"));
257 CmdArgs.push_back(Args.MakeArgString(TC.
getArch() == llvm::Triple::x86
258 ?
"___asan_seh_interceptor" 259 :
"__asan_seh_interceptor"));
262 CmdArgs.push_back(Args.MakeArgString(
"--whole-archive"));
263 CmdArgs.push_back(Args.MakeArgString(
265 CmdArgs.push_back(Args.MakeArgString(
"--no-whole-archive"));
268 if (!HasWindowsApp) {
272 if (Args.hasArg(options::OPT_mwindows)) {
273 CmdArgs.push_back(
"-lgdi32");
274 CmdArgs.push_back(
"-lcomdlg32");
276 CmdArgs.push_back(
"-ladvapi32");
277 CmdArgs.push_back(
"-lshell32");
278 CmdArgs.push_back(
"-luser32");
279 CmdArgs.push_back(
"-lkernel32");
282 if (Args.hasArg(options::OPT_static))
283 CmdArgs.push_back(
"--end-group");
285 AddLibGCC(Args, CmdArgs);
288 if (!Args.hasArg(options::OPT_nostartfiles)) {
292 CmdArgs.push_back(Args.MakeArgString(TC.
GetFilePath(
"crtend.o")));
296 C.
addCommand(llvm::make_unique<Command>(JA, *
this, Exec, CmdArgs, Inputs));
302 auto Version = toolchains::Generic_GCC::GCCVersion::Parse(
"0.0.0");
304 for (llvm::sys::fs::directory_iterator LI(LibDir, EC), LE; !EC && LI != LE;
305 LI = LI.increment(EC)) {
306 StringRef VersionText = llvm::sys::path::filename(LI->path());
307 auto CandidateVersion =
308 toolchains::Generic_GCC::GCCVersion::Parse(VersionText);
309 if (CandidateVersion.Major == -1)
311 if (CandidateVersion <= Version)
314 GccLibDir = LI->path();
319 void toolchains::MinGW::findGccLibDir() {
321 Archs.emplace_back(getTriple().getArchName());
322 Archs[0] +=
"-w64-mingw32";
323 Archs.emplace_back(
"mingw32");
325 Arch = Archs[0].
str();
328 for (StringRef CandidateLib : {
"lib",
"lib64"}) {
329 for (StringRef CandidateArch : Archs) {
331 llvm::sys::path::append(LibDir, CandidateLib,
"gcc", CandidateArch);
333 Arch = CandidateArch;
340 llvm::ErrorOr<std::string> toolchains::MinGW::findGcc() {
342 Gccs.emplace_back(getTriple().getArchName());
343 Gccs[0] +=
"-w64-mingw32-gcc";
344 Gccs.emplace_back(
"mingw32-gcc");
346 for (StringRef CandidateGcc : Gccs)
347 if (llvm::ErrorOr<std::string> GPPName = llvm::sys::findProgramByName(CandidateGcc))
352 llvm::ErrorOr<std::string> toolchains::MinGW::findClangRelativeSysroot() {
354 Subdirs.emplace_back(getTriple().
str());
355 Subdirs.emplace_back(getTriple().getArchName());
356 Subdirs[1] +=
"-w64-mingw32";
357 StringRef ClangRoot =
358 llvm::sys::path::parent_path(getDriver().getInstalledDir());
359 StringRef Sep = llvm::sys::path::get_separator();
360 for (StringRef CandidateSubdir : Subdirs) {
361 if (llvm::sys::fs::is_directory(ClangRoot + Sep + CandidateSubdir)) {
362 Arch = CandidateSubdir;
363 return (ClangRoot + Sep + CandidateSubdir).str();
369 toolchains::MinGW::MinGW(
const Driver &D,
const llvm::Triple &Triple,
371 :
ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
378 else if (llvm::ErrorOr<std::string> TargetSubdir = findClangRelativeSysroot())
379 Base = llvm::sys::path::parent_path(TargetSubdir.get());
380 else if (llvm::ErrorOr<std::string> GPPName = findGcc())
381 Base = llvm::sys::path::parent_path(
382 llvm::sys::path::parent_path(GPPName.get()));
384 Base = llvm::sys::path::parent_path(
getDriver().getInstalledDir());
386 Base += llvm::sys::path::get_separator();
392 (
Base + Arch + llvm::sys::path::get_separator() +
"lib").
str());
398 Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER)
399 .equals_lower(
"lld");
413 return Compiler.get();
428 return NativeLLVMSupport;
432 Arg *ExceptionArg = Args.getLastArg(options::OPT_fsjlj_exceptions,
433 options::OPT_fseh_exceptions,
434 options::OPT_fdwarf_exceptions);
436 ExceptionArg->getOption().matches(options::OPT_fseh_exceptions))
438 return getArch() == llvm::Triple::x86_64;
442 return getArch() == llvm::Triple::x86_64;
448 return getArch() == llvm::Triple::x86_64;
451 llvm::ExceptionHandling
453 if (
getArch() == llvm::Triple::x86_64)
454 return llvm::ExceptionHandling::WinEH;
455 return llvm::ExceptionHandling::DwarfCFI;
460 Res |= SanitizerKind::Address;
465 ArgStringList &CC1Args)
const {
470 CudaInstallation.
print(OS);
514 ArgStringList &CC1Args)
const {
515 if (DriverArgs.hasArg(options::OPT_nostdinc))
518 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
520 llvm::sys::path::append(P,
"include");
524 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
530 Base + Arch +
"/sys-root/mingw/include");
534 Base + Arch + llvm::sys::path::get_separator() +
"include");
539 const ArgList &DriverArgs, ArgStringList &CC1Args)
const {
540 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
541 DriverArgs.hasArg(options::OPT_nostdincxx))
544 StringRef Slash = llvm::sys::path::get_separator();
549 Slash +
"c++" + Slash +
"v1");
551 Base +
"include" + Slash +
"c++" + Slash +
"v1");
556 CppIncludeBases.emplace_back(
Base);
557 llvm::sys::path::append(CppIncludeBases[0], Arch,
"include",
"c++");
558 CppIncludeBases.emplace_back(
Base);
559 llvm::sys::path::append(CppIncludeBases[1], Arch,
"include",
"c++", Ver);
560 CppIncludeBases.emplace_back(
Base);
561 llvm::sys::path::append(CppIncludeBases[2],
"include",
"c++", Ver);
562 CppIncludeBases.emplace_back(GccLibDir);
563 llvm::sys::path::append(CppIncludeBases[3],
"include",
"c++");
564 for (
auto &CppIncludeBase : CppIncludeBases) {
566 CppIncludeBase += Slash;
static bool findGccVersion(StringRef LibDir, std::string &GccLibDir, std::string &Ver)
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
void print(raw_ostream &OS) const
Print information about the detected CUDA installation.
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)
void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
Dataflow Directional Tag Classes.
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.