blob: a53c5c6a4b3c3ac253f40750d56cc049a7e991b0 [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 Keren28596532015-07-21 11:01:00 +000023void MinGW::findGccLibDir() {
Yaron Keren658df8b2015-07-20 06:38:39 +000024 // lib: Arch Linux, Ubuntu, Windows
25 // lib64: openSUSE Linux
Yaron Keren28596532015-07-21 11:01:00 +000026 llvm::SmallString<1024> LibDir;
Yaron Keren0050b482015-07-20 12:40:25 +000027 for (StringRef Lib : {"lib", "lib64"}) {
Yaron Keren658df8b2015-07-20 06:38:39 +000028 LibDir = Base;
29 llvm::sys::path::append(LibDir, Lib, "gcc");
30 LibDir += llvm::sys::path::get_separator();
31 std::error_code EC;
32 // First look for mingw-w64.
33 llvm::sys::fs::directory_iterator MingW64Entry(LibDir + Arch, EC);
34 if (!EC) {
35 GccLibDir = MingW64Entry->path();
Yaron Keren658df8b2015-07-20 06:38:39 +000036 break;
37 }
Yaron Keren1c0070c2015-07-02 04:45:27 +000038 // If mingw-w64 not found, try looking for mingw.org.
Yaron Keren658df8b2015-07-20 06:38:39 +000039 llvm::sys::fs::directory_iterator MingwOrgEntry(LibDir + "mingw32", EC);
40 if (!EC) {
Yaron Keren1c0070c2015-07-02 04:45:27 +000041 GccLibDir = MingwOrgEntry->path();
Yaron Keren658df8b2015-07-20 06:38:39 +000042 // Replace Arch with mingw32 arch.
Yaron Keren327675b2015-07-24 08:50:15 +000043 Arch = "mingw32";
Yaron Keren658df8b2015-07-20 06:38:39 +000044 break;
45 }
Yaron Keren1c0070c2015-07-02 04:45:27 +000046 }
Yaron Keren28596532015-07-21 11:01:00 +000047}
Yaron Keren658df8b2015-07-20 06:38:39 +000048
Yaron Keren28596532015-07-21 11:01:00 +000049MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
50 : ToolChain(D, Triple, Args) {
51 getProgramPaths().push_back(getDriver().getInstalledDir());
52
53 // Default Arch is mingw-w64.
Yaron Keren327675b2015-07-24 08:50:15 +000054 Arch = (getTriple().getArchName() + "-w64-mingw32").str();
Yaron Keren28596532015-07-21 11:01:00 +000055
56// In Windows there aren't any standard install locations, we search
57// for gcc on the PATH. In Linux the base is always /usr.
58#ifdef LLVM_ON_WIN32
59 if (getDriver().SysRoot.size())
60 Base = getDriver().SysRoot;
61 else if (llvm::ErrorOr<std::string> GPPName =
62 llvm::sys::findProgramByName("gcc"))
63 Base = llvm::sys::path::parent_path(
64 llvm::sys::path::parent_path(GPPName.get()));
65 else
66 Base = llvm::sys::path::parent_path(getDriver().getInstalledDir());
67#else
Yaron Keren327675b2015-07-24 08:50:15 +000068 if (getDriver().SysRoot.size())
69 Base = getDriver().SysRoot;
70 else
71 Base = "/usr";
Yaron Keren28596532015-07-21 11:01:00 +000072#endif
73
74 Base += llvm::sys::path::get_separator();
Yaron Keren327675b2015-07-24 08:50:15 +000075 findGccLibDir();
Yaron Keren28596532015-07-21 11:01:00 +000076 Ver = llvm::sys::path::filename(GccLibDir);
Yaron Keren1c0070c2015-07-02 04:45:27 +000077 // GccLibDir must precede Base/lib so that the
78 // correct crtbegin.o ,cetend.o would be found.
79 getFilePaths().push_back(GccLibDir);
Yaron Keren327675b2015-07-24 08:50:15 +000080 getFilePaths().push_back(
81 (Base + Arch + llvm::sys::path::get_separator() + "lib").str());
Yaron Keren658df8b2015-07-20 06:38:39 +000082 getFilePaths().push_back(Base + "lib");
Yaron Keren658df8b2015-07-20 06:38:39 +000083 // openSUSE
Yaron Keren327675b2015-07-24 08:50:15 +000084 getFilePaths().push_back(Base + Arch + "/sys-root/mingw/lib");
Yaron Keren1c0070c2015-07-02 04:45:27 +000085}
86
87bool MinGW::IsIntegratedAssemblerDefault() const { return true; }
88
89Tool *MinGW::getTool(Action::ActionClass AC) const {
90 switch (AC) {
91 case Action::PreprocessJobClass:
92 if (!Preprocessor)
93 Preprocessor.reset(new tools::gcc::Preprocessor(*this));
94 return Preprocessor.get();
95 case Action::CompileJobClass:
96 if (!Compiler)
97 Compiler.reset(new tools::gcc::Compiler(*this));
98 return Compiler.get();
99 default:
100 return ToolChain::getTool(AC);
101 }
102}
103
104Tool *MinGW::buildAssembler() const {
105 return new tools::MinGW::Assembler(*this);
106}
107
108Tool *MinGW::buildLinker() const { return new tools::MinGW::Linker(*this); }
109
110bool MinGW::IsUnwindTablesDefault() const {
111 return getArch() == llvm::Triple::x86_64;
112}
113
114bool MinGW::isPICDefault() const { return getArch() == llvm::Triple::x86_64; }
115
116bool MinGW::isPIEDefault() const { return false; }
117
118bool MinGW::isPICDefaultForced() const {
119 return getArch() == llvm::Triple::x86_64;
120}
121
122bool MinGW::UseSEHExceptions() const {
123 return getArch() == llvm::Triple::x86_64;
124}
125
Yaron Keren28596532015-07-21 11:01:00 +0000126// Include directories for various hosts:
127
128// Windows, mingw.org
Yaron Keren327675b2015-07-24 08:50:15 +0000129// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++
130// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\mingw32
131// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\backward
132// c:\mingw\lib\gcc\mingw32\4.8.1\include
133// c:\mingw\include
134// c:\mingw\lib\gcc\mingw32\4.8.1\include-fixed
Yaron Keren28596532015-07-21 11:01:00 +0000135// c:\mingw\mingw32\include
136
137// Windows, mingw-w64 mingw-builds
Yaron Keren327675b2015-07-24 08:50:15 +0000138// c:\mingw32\lib\gcc\i686-w64-mingw32\4.9.1\include
139// c:\mingw32\lib\gcc\i686-w64-mingw32\4.9.1\include-fixed
140// c:\mingw32\i686-w64-mingw32\include
141// c:\mingw32\i686-w64-mingw32\include\c++
142// c:\mingw32\i686-w64-mingw32\include\c++\i686-w64-mingw32
143// c:\mingw32\i686-w64-mingw32\include\c++\backward
Yaron Keren28596532015-07-21 11:01:00 +0000144
145// Windows, mingw-w64 msys2
Yaron Keren327675b2015-07-24 08:50:15 +0000146// c:\msys64\mingw32\lib\gcc\i686-w64-mingw32\4.9.2\include
147// c:\msys64\mingw32\include
148// c:\msys64\mingw32\lib\gcc\i686-w64-mingw32\4.9.2\include-fixed
149// c:\msys64\mingw32\i686-w64-mingw32\include
150// c:\msys64\mingw32\include\c++\4.9.2
151// c:\msys64\mingw32\include\c++\4.9.2\i686-w64-mingw32
Yaron Keren28596532015-07-21 11:01:00 +0000152// c:\msys64\mingw32\include\c++\4.9.2\backward
153
154// openSUSE
155// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++
156// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32
157// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/backward
158// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include
159// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include-fixed
160// /usr/x86_64-w64-mingw32/sys-root/mingw/include
161
162// Arch Linux
Yaron Keren327675b2015-07-24 08:50:15 +0000163// /usr/i686-w64-mingw32/include/c++/5.1.0
164// /usr/i686-w64-mingw32/include/c++/5.1.0/i686-w64-mingw32
165// /usr/i686-w64-mingw32/include/c++/5.1.0/backward
166// /usr/lib/gcc/i686-w64-mingw32/5.1.0/include
167// /usr/lib/gcc/i686-w64-mingw32/5.1.0/include-fixed
Yaron Keren28596532015-07-21 11:01:00 +0000168// /usr/i686-w64-mingw32/include
169
170// Ubuntu
Yaron Keren327675b2015-07-24 08:50:15 +0000171// /usr/include/c++/4.8
172// /usr/include/c++/4.8/x86_64-w64-mingw32
173// /usr/include/c++/4.8/backward
174// /usr/lib/gcc/x86_64-w64-mingw32/4.8/include
175// /usr/lib/gcc/x86_64-w64-mingw32/4.8/include-fixed
176// /usr/x86_64-w64-mingw32/include
Yaron Keren28596532015-07-21 11:01:00 +0000177
Yaron Keren1c0070c2015-07-02 04:45:27 +0000178void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
179 ArgStringList &CC1Args) const {
180 if (DriverArgs.hasArg(options::OPT_nostdinc))
181 return;
182
183 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
184 SmallString<1024> P(getDriver().ResourceDir);
185 llvm::sys::path::append(P, "include");
186 addSystemInclude(DriverArgs, CC1Args, P.str());
187 }
188
189 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
190 return;
191
Reid Kleckner0213a472015-07-22 16:01:38 +0000192 if (GetRuntimeLibType(DriverArgs) == ToolChain::RLT_Libgcc) {
193 llvm::SmallString<1024> IncludeDir(GccLibDir);
194 llvm::sys::path::append(IncludeDir, "include");
195 addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
196 IncludeDir += "-fixed";
Reid Kleckner0213a472015-07-22 16:01:38 +0000197 // openSUSE
198 addSystemInclude(DriverArgs, CC1Args,
199 "/usr/x86_64-w64-mingw32/sys-root/mingw/include");
Reid Kleckner0213a472015-07-22 16:01:38 +0000200 addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
201 }
Yaron Keren327675b2015-07-24 08:50:15 +0000202 addSystemInclude(DriverArgs, CC1Args,
203 Base + Arch + llvm::sys::path::get_separator() + "include");
Yaron Keren1c0070c2015-07-02 04:45:27 +0000204 addSystemInclude(DriverArgs, CC1Args, Base + "include");
205}
206
207void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
208 ArgStringList &CC1Args) const {
209 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
210 DriverArgs.hasArg(options::OPT_nostdincxx))
211 return;
212
Reid Kleckner0213a472015-07-22 16:01:38 +0000213 switch (GetCXXStdlibType(DriverArgs)) {
214 case ToolChain::CST_Libcxx:
Yaron Keren327675b2015-07-24 08:50:15 +0000215 addSystemInclude(DriverArgs, CC1Args,
216 Base + "include" + llvm::sys::path::get_separator() +
217 "c++" + llvm::sys::path::get_separator() + "v1");
Reid Kleckner0213a472015-07-22 16:01:38 +0000218 break;
219
220 case ToolChain::CST_Libstdcxx:
221 llvm::SmallVector<llvm::SmallString<1024>, 4> CppIncludeBases;
222 CppIncludeBases.emplace_back(Base);
223 llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++");
224 CppIncludeBases.emplace_back(Base);
225 llvm::sys::path::append(CppIncludeBases[1], Arch, "include", "c++", Ver);
226 CppIncludeBases.emplace_back(Base);
227 llvm::sys::path::append(CppIncludeBases[2], "include", "c++", Ver);
228 CppIncludeBases.emplace_back(GccLibDir);
229 llvm::sys::path::append(CppIncludeBases[3], "include", "c++");
230 for (auto &CppIncludeBase : CppIncludeBases) {
Reid Kleckner0213a472015-07-22 16:01:38 +0000231 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase);
Yaron Keren327675b2015-07-24 08:50:15 +0000232 CppIncludeBase += llvm::sys::path::get_separator();
Reid Kleckner0213a472015-07-22 16:01:38 +0000233 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch);
234 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward");
235 }
236 break;
Yaron Keren1c0070c2015-07-02 04:45:27 +0000237 }
238}