blob: 2896bde9c9ef152d307ca1a57c033acdd3449aad [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 {
Yaron Kerene8969392015-07-24 20:18:27 +000024// Simplified from Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple.
Yaron Keren8cb250a2015-07-24 11:01:45 +000025bool findGccVersion(StringRef LibDir, std::string &GccLibDir,
26 std::string &Ver) {
Yaron Kerene8969392015-07-24 20:18:27 +000027 Generic_GCC::GCCVersion Version = Generic_GCC::GCCVersion::Parse("0.0.0");
Yaron Keren8cb250a2015-07-24 11:01:45 +000028 std::error_code EC;
Yaron Kerene8969392015-07-24 20:18:27 +000029 for (llvm::sys::fs::directory_iterator LI(LibDir, EC), LE; !EC && LI != LE;
30 LI = LI.increment(EC)) {
31 StringRef VersionText = llvm::sys::path::filename(LI->path());
32 Generic_GCC::GCCVersion CandidateVersion =
33 Generic_GCC::GCCVersion::Parse(VersionText);
34 if (CandidateVersion.Major == -1)
35 continue;
36 if (CandidateVersion <= Version)
37 continue;
38 Ver = VersionText;
39 GccLibDir = LI->path();
Yaron Keren8cb250a2015-07-24 11:01:45 +000040 }
Yaron Kerene8969392015-07-24 20:18:27 +000041 return Ver.size();
Yaron Keren8cb250a2015-07-24 11:01:45 +000042}
43}
44
Yaron Keren28596532015-07-21 11:01:00 +000045void MinGW::findGccLibDir() {
Yaron Keren8cb250a2015-07-24 11:01:45 +000046 llvm::SmallVector<llvm::SmallString<32>, 2> Archs;
47 Archs.emplace_back(getTriple().getArchName());
48 Archs[0] += "-w64-mingw32";
49 Archs.emplace_back("mingw32");
Martell Malone1bc12bb2015-08-13 15:41:04 +000050 Arch = Archs[0].str();
Yaron Keren658df8b2015-07-20 06:38:39 +000051 // lib: Arch Linux, Ubuntu, Windows
52 // lib64: openSUSE Linux
Yaron Kerene8969392015-07-24 20:18:27 +000053 for (StringRef CandidateLib : {"lib", "lib64"}) {
54 for (StringRef CandidateArch : Archs) {
Yaron Keren8cb250a2015-07-24 11:01:45 +000055 llvm::SmallString<1024> LibDir(Base);
Yaron Kerene8969392015-07-24 20:18:27 +000056 llvm::sys::path::append(LibDir, CandidateLib, "gcc", CandidateArch);
Yaron Keren8cb250a2015-07-24 11:01:45 +000057 if (findGccVersion(LibDir, GccLibDir, Ver)) {
Yaron Kerene8969392015-07-24 20:18:27 +000058 Arch = CandidateArch;
Yaron Keren8cb250a2015-07-24 11:01:45 +000059 return;
60 }
Yaron Keren658df8b2015-07-20 06:38:39 +000061 }
Yaron Keren1c0070c2015-07-02 04:45:27 +000062 }
Yaron Keren28596532015-07-21 11:01:00 +000063}
Yaron Keren658df8b2015-07-20 06:38:39 +000064
Yaron Keren28596532015-07-21 11:01:00 +000065MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
66 : ToolChain(D, Triple, Args) {
67 getProgramPaths().push_back(getDriver().getInstalledDir());
68
Martell Malonef6301fa2015-11-23 18:59:48 +000069// On Windows if there is no sysroot we search for gcc on the PATH.
70
71if (getDriver().SysRoot.size())
72 Base = getDriver().SysRoot;
Yaron Keren28596532015-07-21 11:01:00 +000073#ifdef LLVM_ON_WIN32
Martell Malonef6301fa2015-11-23 18:59:48 +000074else if (llvm::ErrorOr<std::string> GPPName =
75 llvm::sys::findProgramByName("gcc"))
76 Base = llvm::sys::path::parent_path(
77 llvm::sys::path::parent_path(GPPName.get()));
Yaron Keren28596532015-07-21 11:01:00 +000078#endif
79
Martell Malonef6301fa2015-11-23 18:59:48 +000080if (!Base.size())
81 Base = llvm::sys::path::parent_path(getDriver().getInstalledDir());
82
Yaron Keren28596532015-07-21 11:01:00 +000083 Base += llvm::sys::path::get_separator();
Yaron Keren327675b2015-07-24 08:50:15 +000084 findGccLibDir();
Yaron Keren1c0070c2015-07-02 04:45:27 +000085 // GccLibDir must precede Base/lib so that the
86 // correct crtbegin.o ,cetend.o would be found.
87 getFilePaths().push_back(GccLibDir);
Yaron Keren327675b2015-07-24 08:50:15 +000088 getFilePaths().push_back(
89 (Base + Arch + llvm::sys::path::get_separator() + "lib").str());
Yaron Keren658df8b2015-07-20 06:38:39 +000090 getFilePaths().push_back(Base + "lib");
Yaron Keren658df8b2015-07-20 06:38:39 +000091 // openSUSE
Yaron Keren327675b2015-07-24 08:50:15 +000092 getFilePaths().push_back(Base + Arch + "/sys-root/mingw/lib");
Yaron Keren1c0070c2015-07-02 04:45:27 +000093}
94
95bool MinGW::IsIntegratedAssemblerDefault() const { return true; }
96
97Tool *MinGW::getTool(Action::ActionClass AC) const {
98 switch (AC) {
99 case Action::PreprocessJobClass:
100 if (!Preprocessor)
101 Preprocessor.reset(new tools::gcc::Preprocessor(*this));
102 return Preprocessor.get();
103 case Action::CompileJobClass:
104 if (!Compiler)
105 Compiler.reset(new tools::gcc::Compiler(*this));
106 return Compiler.get();
107 default:
108 return ToolChain::getTool(AC);
109 }
110}
111
112Tool *MinGW::buildAssembler() const {
113 return new tools::MinGW::Assembler(*this);
114}
115
116Tool *MinGW::buildLinker() const { return new tools::MinGW::Linker(*this); }
117
118bool MinGW::IsUnwindTablesDefault() const {
119 return getArch() == llvm::Triple::x86_64;
120}
121
122bool MinGW::isPICDefault() const { return getArch() == llvm::Triple::x86_64; }
123
124bool MinGW::isPIEDefault() const { return false; }
125
126bool MinGW::isPICDefaultForced() const {
127 return getArch() == llvm::Triple::x86_64;
128}
129
130bool MinGW::UseSEHExceptions() const {
131 return getArch() == llvm::Triple::x86_64;
132}
133
Yaron Keren28596532015-07-21 11:01:00 +0000134// Include directories for various hosts:
135
136// Windows, mingw.org
Yaron Keren327675b2015-07-24 08:50:15 +0000137// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++
138// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\mingw32
139// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\backward
140// c:\mingw\lib\gcc\mingw32\4.8.1\include
141// c:\mingw\include
142// c:\mingw\lib\gcc\mingw32\4.8.1\include-fixed
Yaron Keren28596532015-07-21 11:01:00 +0000143// c:\mingw\mingw32\include
144
145// Windows, mingw-w64 mingw-builds
Yaron Keren327675b2015-07-24 08:50:15 +0000146// c:\mingw32\lib\gcc\i686-w64-mingw32\4.9.1\include
147// c:\mingw32\lib\gcc\i686-w64-mingw32\4.9.1\include-fixed
148// c:\mingw32\i686-w64-mingw32\include
149// c:\mingw32\i686-w64-mingw32\include\c++
150// c:\mingw32\i686-w64-mingw32\include\c++\i686-w64-mingw32
151// c:\mingw32\i686-w64-mingw32\include\c++\backward
Yaron Keren28596532015-07-21 11:01:00 +0000152
153// Windows, mingw-w64 msys2
Yaron Keren327675b2015-07-24 08:50:15 +0000154// c:\msys64\mingw32\lib\gcc\i686-w64-mingw32\4.9.2\include
155// c:\msys64\mingw32\include
156// c:\msys64\mingw32\lib\gcc\i686-w64-mingw32\4.9.2\include-fixed
157// c:\msys64\mingw32\i686-w64-mingw32\include
158// c:\msys64\mingw32\include\c++\4.9.2
159// c:\msys64\mingw32\include\c++\4.9.2\i686-w64-mingw32
Yaron Keren28596532015-07-21 11:01:00 +0000160// c:\msys64\mingw32\include\c++\4.9.2\backward
161
162// openSUSE
163// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++
164// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32
165// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/backward
166// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include
167// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include-fixed
168// /usr/x86_64-w64-mingw32/sys-root/mingw/include
169
170// Arch Linux
Yaron Keren327675b2015-07-24 08:50:15 +0000171// /usr/i686-w64-mingw32/include/c++/5.1.0
172// /usr/i686-w64-mingw32/include/c++/5.1.0/i686-w64-mingw32
173// /usr/i686-w64-mingw32/include/c++/5.1.0/backward
174// /usr/lib/gcc/i686-w64-mingw32/5.1.0/include
175// /usr/lib/gcc/i686-w64-mingw32/5.1.0/include-fixed
Yaron Keren28596532015-07-21 11:01:00 +0000176// /usr/i686-w64-mingw32/include
177
178// Ubuntu
Yaron Keren327675b2015-07-24 08:50:15 +0000179// /usr/include/c++/4.8
180// /usr/include/c++/4.8/x86_64-w64-mingw32
181// /usr/include/c++/4.8/backward
182// /usr/lib/gcc/x86_64-w64-mingw32/4.8/include
183// /usr/lib/gcc/x86_64-w64-mingw32/4.8/include-fixed
184// /usr/x86_64-w64-mingw32/include
Yaron Keren28596532015-07-21 11:01:00 +0000185
Yaron Keren1c0070c2015-07-02 04:45:27 +0000186void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
187 ArgStringList &CC1Args) const {
188 if (DriverArgs.hasArg(options::OPT_nostdinc))
189 return;
190
191 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
192 SmallString<1024> P(getDriver().ResourceDir);
193 llvm::sys::path::append(P, "include");
194 addSystemInclude(DriverArgs, CC1Args, P.str());
195 }
196
197 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
198 return;
199
Reid Kleckner0213a472015-07-22 16:01:38 +0000200 if (GetRuntimeLibType(DriverArgs) == ToolChain::RLT_Libgcc) {
201 llvm::SmallString<1024> IncludeDir(GccLibDir);
202 llvm::sys::path::append(IncludeDir, "include");
203 addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
204 IncludeDir += "-fixed";
Reid Kleckner0213a472015-07-22 16:01:38 +0000205 // openSUSE
206 addSystemInclude(DriverArgs, CC1Args,
Yaron Kerena749b1b2015-07-24 19:18:17 +0000207 Base + Arch + "/sys-root/mingw/include");
Reid Kleckner0213a472015-07-22 16:01:38 +0000208 addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
209 }
Yaron Keren327675b2015-07-24 08:50:15 +0000210 addSystemInclude(DriverArgs, CC1Args,
211 Base + Arch + llvm::sys::path::get_separator() + "include");
Yaron Keren1c0070c2015-07-02 04:45:27 +0000212 addSystemInclude(DriverArgs, CC1Args, Base + "include");
213}
214
215void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
216 ArgStringList &CC1Args) const {
217 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
218 DriverArgs.hasArg(options::OPT_nostdincxx))
219 return;
220
Reid Kleckner0213a472015-07-22 16:01:38 +0000221 switch (GetCXXStdlibType(DriverArgs)) {
222 case ToolChain::CST_Libcxx:
Yaron Keren327675b2015-07-24 08:50:15 +0000223 addSystemInclude(DriverArgs, CC1Args,
224 Base + "include" + llvm::sys::path::get_separator() +
225 "c++" + llvm::sys::path::get_separator() + "v1");
Reid Kleckner0213a472015-07-22 16:01:38 +0000226 break;
227
228 case ToolChain::CST_Libstdcxx:
229 llvm::SmallVector<llvm::SmallString<1024>, 4> CppIncludeBases;
230 CppIncludeBases.emplace_back(Base);
231 llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++");
232 CppIncludeBases.emplace_back(Base);
233 llvm::sys::path::append(CppIncludeBases[1], Arch, "include", "c++", Ver);
234 CppIncludeBases.emplace_back(Base);
235 llvm::sys::path::append(CppIncludeBases[2], "include", "c++", Ver);
236 CppIncludeBases.emplace_back(GccLibDir);
237 llvm::sys::path::append(CppIncludeBases[3], "include", "c++");
238 for (auto &CppIncludeBase : CppIncludeBases) {
Reid Kleckner0213a472015-07-22 16:01:38 +0000239 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase);
Yaron Keren327675b2015-07-24 08:50:15 +0000240 CppIncludeBase += llvm::sys::path::get_separator();
Reid Kleckner0213a472015-07-22 16:01:38 +0000241 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch);
242 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward");
243 }
244 break;
Yaron Keren1c0070c2015-07-02 04:45:27 +0000245 }
246}