blob: d68c8afdd78179e84ea4511cc658071fb7de08d0 [file] [log] [blame]
Yaron Kerenbfc481b2015-07-07 15:10:47 +00001//===--- MinGWToolChain.cpp - MinGWToolChain Implementation ---------------===//
Yaron Keren1c0070c2015-07-02 04:45:27 +00002//
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 "ToolChains.h"
11#include "clang/Driver/Driver.h"
12#include "clang/Driver/Options.h"
13#include "llvm/Option/ArgList.h"
14#include "llvm/Support/FileSystem.h"
15#include "llvm/Support/Path.h"
16
17using namespace clang::diag;
18using namespace clang::driver;
19using namespace clang::driver::toolchains;
20using namespace clang;
21using namespace llvm::opt;
22
Yaron Keren8cb250a2015-07-24 11:01:45 +000023namespace {
24bool findGccVersion(StringRef LibDir, std::string &GccLibDir,
25 std::string &Ver) {
26 std::error_code EC;
27 llvm::sys::fs::directory_iterator Entry(LibDir, EC);
28 while (!EC) {
29 GccLibDir = Entry->path();
30 Ver = llvm::sys::path::filename(GccLibDir);
31 if (Ver.size() && isdigit(Ver[0]))
32 return true;
33 Entry.increment(EC);
34 }
35 return false;
36}
37}
38
Yaron Keren28596532015-07-21 11:01:00 +000039void MinGW::findGccLibDir() {
Yaron Keren8cb250a2015-07-24 11:01:45 +000040 llvm::SmallVector<llvm::SmallString<32>, 2> Archs;
41 Archs.emplace_back(getTriple().getArchName());
42 Archs[0] += "-w64-mingw32";
43 Archs.emplace_back("mingw32");
44 Arch = "unknown";
Yaron Keren658df8b2015-07-20 06:38:39 +000045 // lib: Arch Linux, Ubuntu, Windows
46 // lib64: openSUSE Linux
Yaron Keren0050b482015-07-20 12:40:25 +000047 for (StringRef Lib : {"lib", "lib64"}) {
Yaron Keren8cb250a2015-07-24 11:01:45 +000048 for (StringRef MaybeArch : Archs) {
49 llvm::SmallString<1024> LibDir(Base);
50 llvm::sys::path::append(LibDir, Lib, "gcc", MaybeArch);
51 if (findGccVersion(LibDir, GccLibDir, Ver)) {
52 Arch = MaybeArch;
53 return;
54 }
Yaron Keren658df8b2015-07-20 06:38:39 +000055 }
Yaron Keren1c0070c2015-07-02 04:45:27 +000056 }
Yaron Keren28596532015-07-21 11:01:00 +000057}
Yaron Keren658df8b2015-07-20 06:38:39 +000058
Yaron Keren28596532015-07-21 11:01:00 +000059MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
60 : ToolChain(D, Triple, Args) {
61 getProgramPaths().push_back(getDriver().getInstalledDir());
62
Yaron Keren28596532015-07-21 11:01:00 +000063// In Windows there aren't any standard install locations, we search
64// for gcc on the PATH. In Linux the base is always /usr.
65#ifdef LLVM_ON_WIN32
66 if (getDriver().SysRoot.size())
67 Base = getDriver().SysRoot;
68 else if (llvm::ErrorOr<std::string> GPPName =
69 llvm::sys::findProgramByName("gcc"))
70 Base = llvm::sys::path::parent_path(
71 llvm::sys::path::parent_path(GPPName.get()));
72 else
73 Base = llvm::sys::path::parent_path(getDriver().getInstalledDir());
74#else
Yaron Keren327675b2015-07-24 08:50:15 +000075 if (getDriver().SysRoot.size())
76 Base = getDriver().SysRoot;
77 else
78 Base = "/usr";
Yaron Keren28596532015-07-21 11:01:00 +000079#endif
80
81 Base += llvm::sys::path::get_separator();
Yaron Keren327675b2015-07-24 08:50:15 +000082 findGccLibDir();
Yaron Keren1c0070c2015-07-02 04:45:27 +000083 // GccLibDir must precede Base/lib so that the
84 // correct crtbegin.o ,cetend.o would be found.
85 getFilePaths().push_back(GccLibDir);
Yaron Keren327675b2015-07-24 08:50:15 +000086 getFilePaths().push_back(
87 (Base + Arch + llvm::sys::path::get_separator() + "lib").str());
Yaron Keren658df8b2015-07-20 06:38:39 +000088 getFilePaths().push_back(Base + "lib");
Yaron Keren658df8b2015-07-20 06:38:39 +000089 // openSUSE
Yaron Keren327675b2015-07-24 08:50:15 +000090 getFilePaths().push_back(Base + Arch + "/sys-root/mingw/lib");
Yaron Keren1c0070c2015-07-02 04:45:27 +000091}
92
93bool MinGW::IsIntegratedAssemblerDefault() const { return true; }
94
95Tool *MinGW::getTool(Action::ActionClass AC) const {
96 switch (AC) {
97 case Action::PreprocessJobClass:
98 if (!Preprocessor)
99 Preprocessor.reset(new tools::gcc::Preprocessor(*this));
100 return Preprocessor.get();
101 case Action::CompileJobClass:
102 if (!Compiler)
103 Compiler.reset(new tools::gcc::Compiler(*this));
104 return Compiler.get();
105 default:
106 return ToolChain::getTool(AC);
107 }
108}
109
110Tool *MinGW::buildAssembler() const {
111 return new tools::MinGW::Assembler(*this);
112}
113
114Tool *MinGW::buildLinker() const { return new tools::MinGW::Linker(*this); }
115
116bool MinGW::IsUnwindTablesDefault() const {
117 return getArch() == llvm::Triple::x86_64;
118}
119
120bool MinGW::isPICDefault() const { return getArch() == llvm::Triple::x86_64; }
121
122bool MinGW::isPIEDefault() const { return false; }
123
124bool MinGW::isPICDefaultForced() const {
125 return getArch() == llvm::Triple::x86_64;
126}
127
128bool MinGW::UseSEHExceptions() const {
129 return getArch() == llvm::Triple::x86_64;
130}
131
Yaron Keren28596532015-07-21 11:01:00 +0000132// Include directories for various hosts:
133
134// Windows, mingw.org
Yaron Keren327675b2015-07-24 08:50:15 +0000135// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++
136// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\mingw32
137// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\backward
138// c:\mingw\lib\gcc\mingw32\4.8.1\include
139// c:\mingw\include
140// c:\mingw\lib\gcc\mingw32\4.8.1\include-fixed
Yaron Keren28596532015-07-21 11:01:00 +0000141// c:\mingw\mingw32\include
142
143// Windows, mingw-w64 mingw-builds
Yaron Keren327675b2015-07-24 08:50:15 +0000144// c:\mingw32\lib\gcc\i686-w64-mingw32\4.9.1\include
145// c:\mingw32\lib\gcc\i686-w64-mingw32\4.9.1\include-fixed
146// c:\mingw32\i686-w64-mingw32\include
147// c:\mingw32\i686-w64-mingw32\include\c++
148// c:\mingw32\i686-w64-mingw32\include\c++\i686-w64-mingw32
149// c:\mingw32\i686-w64-mingw32\include\c++\backward
Yaron Keren28596532015-07-21 11:01:00 +0000150
151// Windows, mingw-w64 msys2
Yaron Keren327675b2015-07-24 08:50:15 +0000152// c:\msys64\mingw32\lib\gcc\i686-w64-mingw32\4.9.2\include
153// c:\msys64\mingw32\include
154// c:\msys64\mingw32\lib\gcc\i686-w64-mingw32\4.9.2\include-fixed
155// c:\msys64\mingw32\i686-w64-mingw32\include
156// c:\msys64\mingw32\include\c++\4.9.2
157// c:\msys64\mingw32\include\c++\4.9.2\i686-w64-mingw32
Yaron Keren28596532015-07-21 11:01:00 +0000158// c:\msys64\mingw32\include\c++\4.9.2\backward
159
160// openSUSE
161// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++
162// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32
163// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/backward
164// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include
165// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include-fixed
166// /usr/x86_64-w64-mingw32/sys-root/mingw/include
167
168// Arch Linux
Yaron Keren327675b2015-07-24 08:50:15 +0000169// /usr/i686-w64-mingw32/include/c++/5.1.0
170// /usr/i686-w64-mingw32/include/c++/5.1.0/i686-w64-mingw32
171// /usr/i686-w64-mingw32/include/c++/5.1.0/backward
172// /usr/lib/gcc/i686-w64-mingw32/5.1.0/include
173// /usr/lib/gcc/i686-w64-mingw32/5.1.0/include-fixed
Yaron Keren28596532015-07-21 11:01:00 +0000174// /usr/i686-w64-mingw32/include
175
176// Ubuntu
Yaron Keren327675b2015-07-24 08:50:15 +0000177// /usr/include/c++/4.8
178// /usr/include/c++/4.8/x86_64-w64-mingw32
179// /usr/include/c++/4.8/backward
180// /usr/lib/gcc/x86_64-w64-mingw32/4.8/include
181// /usr/lib/gcc/x86_64-w64-mingw32/4.8/include-fixed
182// /usr/x86_64-w64-mingw32/include
Yaron Keren28596532015-07-21 11:01:00 +0000183
Yaron Keren1c0070c2015-07-02 04:45:27 +0000184void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
185 ArgStringList &CC1Args) const {
186 if (DriverArgs.hasArg(options::OPT_nostdinc))
187 return;
188
189 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
190 SmallString<1024> P(getDriver().ResourceDir);
191 llvm::sys::path::append(P, "include");
192 addSystemInclude(DriverArgs, CC1Args, P.str());
193 }
194
195 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
196 return;
197
Reid Kleckner0213a472015-07-22 16:01:38 +0000198 if (GetRuntimeLibType(DriverArgs) == ToolChain::RLT_Libgcc) {
199 llvm::SmallString<1024> IncludeDir(GccLibDir);
200 llvm::sys::path::append(IncludeDir, "include");
201 addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
202 IncludeDir += "-fixed";
Reid Kleckner0213a472015-07-22 16:01:38 +0000203 // openSUSE
204 addSystemInclude(DriverArgs, CC1Args,
205 "/usr/x86_64-w64-mingw32/sys-root/mingw/include");
Reid Kleckner0213a472015-07-22 16:01:38 +0000206 addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
207 }
Yaron Keren327675b2015-07-24 08:50:15 +0000208 addSystemInclude(DriverArgs, CC1Args,
209 Base + Arch + llvm::sys::path::get_separator() + "include");
Yaron Keren1c0070c2015-07-02 04:45:27 +0000210 addSystemInclude(DriverArgs, CC1Args, Base + "include");
211}
212
213void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
214 ArgStringList &CC1Args) const {
215 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
216 DriverArgs.hasArg(options::OPT_nostdincxx))
217 return;
218
Reid Kleckner0213a472015-07-22 16:01:38 +0000219 switch (GetCXXStdlibType(DriverArgs)) {
220 case ToolChain::CST_Libcxx:
Yaron Keren327675b2015-07-24 08:50:15 +0000221 addSystemInclude(DriverArgs, CC1Args,
222 Base + "include" + llvm::sys::path::get_separator() +
223 "c++" + llvm::sys::path::get_separator() + "v1");
Reid Kleckner0213a472015-07-22 16:01:38 +0000224 break;
225
226 case ToolChain::CST_Libstdcxx:
227 llvm::SmallVector<llvm::SmallString<1024>, 4> CppIncludeBases;
228 CppIncludeBases.emplace_back(Base);
229 llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++");
230 CppIncludeBases.emplace_back(Base);
231 llvm::sys::path::append(CppIncludeBases[1], Arch, "include", "c++", Ver);
232 CppIncludeBases.emplace_back(Base);
233 llvm::sys::path::append(CppIncludeBases[2], "include", "c++", Ver);
234 CppIncludeBases.emplace_back(GccLibDir);
235 llvm::sys::path::append(CppIncludeBases[3], "include", "c++");
236 for (auto &CppIncludeBase : CppIncludeBases) {
Reid Kleckner0213a472015-07-22 16:01:38 +0000237 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase);
Yaron Keren327675b2015-07-24 08:50:15 +0000238 CppIncludeBase += llvm::sys::path::get_separator();
Reid Kleckner0213a472015-07-22 16:01:38 +0000239 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch);
240 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward");
241 }
242 break;
Yaron Keren1c0070c2015-07-02 04:45:27 +0000243 }
244}