blob: f4862cae14e23f0d644160783607706dbe1c85e8 [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 Keren28596532015-07-21 11:01:00 +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.
54 Arch = (getTriple().getArchName() + "-w64-mingw32" +
55 llvm::sys::path::get_separator()).str();
56
57// In Windows there aren't any standard install locations, we search
58// for gcc on the PATH. In Linux the base is always /usr.
59#ifdef LLVM_ON_WIN32
60 if (getDriver().SysRoot.size())
61 Base = getDriver().SysRoot;
62 else if (llvm::ErrorOr<std::string> GPPName =
63 llvm::sys::findProgramByName("gcc"))
64 Base = llvm::sys::path::parent_path(
65 llvm::sys::path::parent_path(GPPName.get()));
66 else
67 Base = llvm::sys::path::parent_path(getDriver().getInstalledDir());
68#else
69 Base = "/usr";
70#endif
71
72 Base += llvm::sys::path::get_separator();
73 if (getDriver().SysRoot.size())
74 GccLibDir = getDriver().SysRoot;
75 else
76 findGccLibDir();
77 Ver = llvm::sys::path::filename(GccLibDir);
Yaron Keren1c0070c2015-07-02 04:45:27 +000078 // GccLibDir must precede Base/lib so that the
79 // correct crtbegin.o ,cetend.o would be found.
80 getFilePaths().push_back(GccLibDir);
Yaron Keren1c0070c2015-07-02 04:45:27 +000081 getFilePaths().push_back(Base + Arch + "lib");
Yaron Keren658df8b2015-07-20 06:38:39 +000082#ifdef LLVM_ON_WIN32
83 getFilePaths().push_back(Base + "lib");
84#else
85 // openSUSE
Yaron Keren88e69e42015-07-14 15:02:09 +000086 getFilePaths().push_back(Base + Arch + "sys-root/mingw/lib");
87#endif
Yaron Keren1c0070c2015-07-02 04:45:27 +000088}
89
90bool MinGW::IsIntegratedAssemblerDefault() const { return true; }
91
92Tool *MinGW::getTool(Action::ActionClass AC) const {
93 switch (AC) {
94 case Action::PreprocessJobClass:
95 if (!Preprocessor)
96 Preprocessor.reset(new tools::gcc::Preprocessor(*this));
97 return Preprocessor.get();
98 case Action::CompileJobClass:
99 if (!Compiler)
100 Compiler.reset(new tools::gcc::Compiler(*this));
101 return Compiler.get();
102 default:
103 return ToolChain::getTool(AC);
104 }
105}
106
107Tool *MinGW::buildAssembler() const {
108 return new tools::MinGW::Assembler(*this);
109}
110
111Tool *MinGW::buildLinker() const { return new tools::MinGW::Linker(*this); }
112
113bool MinGW::IsUnwindTablesDefault() const {
114 return getArch() == llvm::Triple::x86_64;
115}
116
117bool MinGW::isPICDefault() const { return getArch() == llvm::Triple::x86_64; }
118
119bool MinGW::isPIEDefault() const { return false; }
120
121bool MinGW::isPICDefaultForced() const {
122 return getArch() == llvm::Triple::x86_64;
123}
124
125bool MinGW::UseSEHExceptions() const {
126 return getArch() == llvm::Triple::x86_64;
127}
128
Yaron Keren28596532015-07-21 11:01:00 +0000129// Include directories for various hosts:
130
131// Windows, mingw.org
132// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++
133// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\mingw32
134// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\backward
135// c:\mingw\lib\gcc\mingw32\4.8.1\include
136// c:\mingw\include
137// c:\mingw\lib\gcc\mingw32\4.8.1\include-fixed
138// c:\mingw\mingw32\include
139
140// Windows, mingw-w64 mingw-builds
141// c:\mingw32\lib\gcc\i686-w64-mingw32\4.9.1\include
142// c:\mingw32\lib\gcc\i686-w64-mingw32\4.9.1\include-fixed
143// c:\mingw32\i686-w64-mingw32\include
144// c:\mingw32\i686-w64-mingw32\include\c++
145// c:\mingw32\i686-w64-mingw32\include\c++\i686-w64-mingw32
146// c:\mingw32\i686-w64-mingw32\include\c++\backward
147
148// Windows, mingw-w64 msys2
149// c:\msys64\mingw32\lib\gcc\i686-w64-mingw32\4.9.2\include
150// c:\msys64\mingw32\include
151// c:\msys64\mingw32\lib\gcc\i686-w64-mingw32\4.9.2\include-fixed
152// c:\msys64\mingw32\i686-w64-mingw32\include
153// c:\msys64\mingw32\include\c++\4.9.2
154// c:\msys64\mingw32\include\c++\4.9.2\i686-w64-mingw32
155// c:\msys64\mingw32\include\c++\4.9.2\backward
156
157// openSUSE
158// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++
159// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32
160// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/backward
161// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include
162// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include-fixed
163// /usr/x86_64-w64-mingw32/sys-root/mingw/include
164
165// Arch Linux
166// /usr/i686-w64-mingw32/include/c++/5.1.0
167// /usr/i686-w64-mingw32/include/c++/5.1.0/i686-w64-mingw32
168// /usr/i686-w64-mingw32/include/c++/5.1.0/backward
169// /usr/lib/gcc/i686-w64-mingw32/5.1.0/include
170// /usr/lib/gcc/i686-w64-mingw32/5.1.0/include-fixed
171// /usr/i686-w64-mingw32/include
172
173// Ubuntu
174// /usr/include/c++/4.8
175// /usr/include/c++/4.8/x86_64-w64-mingw32
176// /usr/include/c++/4.8/backward
177// /usr/lib/gcc/x86_64-w64-mingw32/4.8/include
178// /usr/lib/gcc/x86_64-w64-mingw32/4.8/include-fixed
179// /usr/x86_64-w64-mingw32/include
180
Yaron Keren1c0070c2015-07-02 04:45:27 +0000181void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
182 ArgStringList &CC1Args) const {
183 if (DriverArgs.hasArg(options::OPT_nostdinc))
184 return;
185
186 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
187 SmallString<1024> P(getDriver().ResourceDir);
188 llvm::sys::path::append(P, "include");
189 addSystemInclude(DriverArgs, CC1Args, P.str());
190 }
191
192 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
193 return;
194
195 llvm::SmallString<1024> IncludeDir(GccLibDir);
196 llvm::sys::path::append(IncludeDir, "include");
197 addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
198 IncludeDir += "-fixed";
Yaron Keren88e69e42015-07-14 15:02:09 +0000199#ifdef LLVM_ON_UNIX
Yaron Keren658df8b2015-07-20 06:38:39 +0000200 // openSUSE
Yaron Keren88e69e42015-07-14 15:02:09 +0000201 addSystemInclude(DriverArgs, CC1Args,
202 "/usr/x86_64-w64-mingw32/sys-root/mingw/include");
203#endif
Yaron Keren1c0070c2015-07-02 04:45:27 +0000204 addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
205 addSystemInclude(DriverArgs, CC1Args, Base + Arch + "include");
206 addSystemInclude(DriverArgs, CC1Args, Base + "include");
207}
208
209void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
210 ArgStringList &CC1Args) const {
211 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
212 DriverArgs.hasArg(options::OPT_nostdincxx))
213 return;
214
Yaron Keren658df8b2015-07-20 06:38:39 +0000215 llvm::SmallVector<llvm::SmallString<1024>, 4> CppIncludeBases;
Yaron Keren763a38a2015-07-06 07:40:10 +0000216 CppIncludeBases.emplace_back(Base);
217 llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++");
218 CppIncludeBases.emplace_back(Base);
Yaron Keren658df8b2015-07-20 06:38:39 +0000219 llvm::sys::path::append(CppIncludeBases[1], Arch, "include", "c++", Ver);
220 CppIncludeBases.emplace_back(Base);
221 llvm::sys::path::append(CppIncludeBases[2], "include", "c++", Ver);
Yaron Keren763a38a2015-07-06 07:40:10 +0000222 CppIncludeBases.emplace_back(GccLibDir);
Yaron Keren658df8b2015-07-20 06:38:39 +0000223 llvm::sys::path::append(CppIncludeBases[3], "include", "c++");
Yaron Keren763a38a2015-07-06 07:40:10 +0000224 for (auto &CppIncludeBase : CppIncludeBases) {
225 CppIncludeBase += llvm::sys::path::get_separator();
226 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase);
227 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch);
228 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward");
Yaron Keren1c0070c2015-07-02 04:45:27 +0000229 }
230}