blob: 606508da69648758dadd41b98150882783e9de02 [file] [log] [blame]
Yaron Keren1c0070c2015-07-02 04:45:27 +00001//===--- MinGWToolChain.cpp - MinGWToolChain Implementation
2//-----------------------===//
3//
4// The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#include "ToolChains.h"
12#include "clang/Driver/Driver.h"
13#include "clang/Driver/Options.h"
14#include "llvm/Option/ArgList.h"
15#include "llvm/Support/FileSystem.h"
16#include "llvm/Support/Path.h"
17
18using namespace clang::diag;
19using namespace clang::driver;
20using namespace clang::driver::toolchains;
21using namespace clang;
22using namespace llvm::opt;
23
24MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
25 : ToolChain(D, Triple, Args) {
26 getProgramPaths().push_back(getDriver().getInstalledDir());
27
28 if (getDriver().SysRoot.size())
29 Base = getDriver().SysRoot;
30 else if (llvm::ErrorOr<std::string> GPPName =
31 llvm::sys::findProgramByName("gcc"))
32 Base = llvm::sys::path::parent_path(
33 llvm::sys::path::parent_path(GPPName.get()));
34 else
35 Base = llvm::sys::path::parent_path(getDriver().getInstalledDir());
36 Base += llvm::sys::path::get_separator();
37 llvm::SmallString<1024> LibDir(Base);
38 llvm::sys::path::append(LibDir, "lib", "gcc");
39 LibDir += llvm::sys::path::get_separator();
40
41 // First look for mingw-w64.
42 Arch = getTriple().getArchName();
43 Arch += "-w64-mingw32";
44 std::error_code EC;
45 llvm::sys::fs::directory_iterator MingW64Entry(LibDir + Arch, EC);
46 if (!EC) {
47 GccLibDir = MingW64Entry->path();
48 } else {
49 // If mingw-w64 not found, try looking for mingw.org.
50 Arch = "mingw32";
51 llvm::sys::fs::directory_iterator MingwOrgEntry(LibDir + Arch, EC);
52 if (!EC)
53 GccLibDir = MingwOrgEntry->path();
54 }
55 Arch += llvm::sys::path::get_separator();
56 // GccLibDir must precede Base/lib so that the
57 // correct crtbegin.o ,cetend.o would be found.
58 getFilePaths().push_back(GccLibDir);
59 getFilePaths().push_back(Base + "lib");
60 getFilePaths().push_back(Base + Arch + "lib");
61}
62
63bool MinGW::IsIntegratedAssemblerDefault() const { return true; }
64
65Tool *MinGW::getTool(Action::ActionClass AC) const {
66 switch (AC) {
67 case Action::PreprocessJobClass:
68 if (!Preprocessor)
69 Preprocessor.reset(new tools::gcc::Preprocessor(*this));
70 return Preprocessor.get();
71 case Action::CompileJobClass:
72 if (!Compiler)
73 Compiler.reset(new tools::gcc::Compiler(*this));
74 return Compiler.get();
75 default:
76 return ToolChain::getTool(AC);
77 }
78}
79
80Tool *MinGW::buildAssembler() const {
81 return new tools::MinGW::Assembler(*this);
82}
83
84Tool *MinGW::buildLinker() const { return new tools::MinGW::Linker(*this); }
85
86bool MinGW::IsUnwindTablesDefault() const {
87 return getArch() == llvm::Triple::x86_64;
88}
89
90bool MinGW::isPICDefault() const { return getArch() == llvm::Triple::x86_64; }
91
92bool MinGW::isPIEDefault() const { return false; }
93
94bool MinGW::isPICDefaultForced() const {
95 return getArch() == llvm::Triple::x86_64;
96}
97
98bool MinGW::UseSEHExceptions() const {
99 return getArch() == llvm::Triple::x86_64;
100}
101
102void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
103 ArgStringList &CC1Args) const {
104 if (DriverArgs.hasArg(options::OPT_nostdinc))
105 return;
106
107 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
108 SmallString<1024> P(getDriver().ResourceDir);
109 llvm::sys::path::append(P, "include");
110 addSystemInclude(DriverArgs, CC1Args, P.str());
111 }
112
113 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
114 return;
115
116 llvm::SmallString<1024> IncludeDir(GccLibDir);
117 llvm::sys::path::append(IncludeDir, "include");
118 addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
119 IncludeDir += "-fixed";
120 addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
121 addSystemInclude(DriverArgs, CC1Args, Base + Arch + "include");
122 addSystemInclude(DriverArgs, CC1Args, Base + "include");
123}
124
125void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
126 ArgStringList &CC1Args) const {
127 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
128 DriverArgs.hasArg(options::OPT_nostdincxx))
129 return;
130
131 llvm::SmallString<1024> IncludeDir;
132 for (bool MingW64 : {true, false}) {
133 if (MingW64)
134 IncludeDir = Base + Arch;
135 else
136 IncludeDir = GccLibDir;
137 llvm::sys::path::append(IncludeDir, "include", "c++");
138 addSystemInclude(DriverArgs, CC1Args, IncludeDir.str());
139 IncludeDir += llvm::sys::path::get_separator();
140 addSystemInclude(DriverArgs, CC1Args, IncludeDir.str() + Arch);
141 addSystemInclude(DriverArgs, CC1Args, IncludeDir.str() + "backward");
142 }
143}