blob: d3dc235216d0c87104445b283b97ea77486adc59 [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();
Yaron Keren763a38a2015-07-06 07:40:10 +000048 Ver = llvm::sys::path::filename(GccLibDir);
Yaron Keren1c0070c2015-07-02 04:45:27 +000049 } else {
50 // If mingw-w64 not found, try looking for mingw.org.
51 Arch = "mingw32";
52 llvm::sys::fs::directory_iterator MingwOrgEntry(LibDir + Arch, EC);
53 if (!EC)
54 GccLibDir = MingwOrgEntry->path();
55 }
56 Arch += llvm::sys::path::get_separator();
57 // GccLibDir must precede Base/lib so that the
58 // correct crtbegin.o ,cetend.o would be found.
59 getFilePaths().push_back(GccLibDir);
60 getFilePaths().push_back(Base + "lib");
61 getFilePaths().push_back(Base + Arch + "lib");
62}
63
64bool MinGW::IsIntegratedAssemblerDefault() const { return true; }
65
66Tool *MinGW::getTool(Action::ActionClass AC) const {
67 switch (AC) {
68 case Action::PreprocessJobClass:
69 if (!Preprocessor)
70 Preprocessor.reset(new tools::gcc::Preprocessor(*this));
71 return Preprocessor.get();
72 case Action::CompileJobClass:
73 if (!Compiler)
74 Compiler.reset(new tools::gcc::Compiler(*this));
75 return Compiler.get();
76 default:
77 return ToolChain::getTool(AC);
78 }
79}
80
81Tool *MinGW::buildAssembler() const {
82 return new tools::MinGW::Assembler(*this);
83}
84
85Tool *MinGW::buildLinker() const { return new tools::MinGW::Linker(*this); }
86
87bool MinGW::IsUnwindTablesDefault() const {
88 return getArch() == llvm::Triple::x86_64;
89}
90
91bool MinGW::isPICDefault() const { return getArch() == llvm::Triple::x86_64; }
92
93bool MinGW::isPIEDefault() const { return false; }
94
95bool MinGW::isPICDefaultForced() const {
96 return getArch() == llvm::Triple::x86_64;
97}
98
99bool MinGW::UseSEHExceptions() const {
100 return getArch() == llvm::Triple::x86_64;
101}
102
103void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
104 ArgStringList &CC1Args) const {
105 if (DriverArgs.hasArg(options::OPT_nostdinc))
106 return;
107
108 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
109 SmallString<1024> P(getDriver().ResourceDir);
110 llvm::sys::path::append(P, "include");
111 addSystemInclude(DriverArgs, CC1Args, P.str());
112 }
113
114 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
115 return;
116
117 llvm::SmallString<1024> IncludeDir(GccLibDir);
118 llvm::sys::path::append(IncludeDir, "include");
119 addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
120 IncludeDir += "-fixed";
121 addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
122 addSystemInclude(DriverArgs, CC1Args, Base + Arch + "include");
123 addSystemInclude(DriverArgs, CC1Args, Base + "include");
124}
125
126void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
127 ArgStringList &CC1Args) const {
128 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
129 DriverArgs.hasArg(options::OPT_nostdincxx))
130 return;
131
Yaron Keren763a38a2015-07-06 07:40:10 +0000132 // C++ includes may be found in several locations depending on distribution.
133 // mingw-w64 mingw-builds: $sysroot/i686-w64-mingw32/include/c++.
134 // mingw-w64 msys2: $sysroot/include/c++/4.9.2
135 // mingw.org: GccLibDir/include/c++
136 llvm::SmallVector<llvm::SmallString<1024>, 3> CppIncludeBases;
137 CppIncludeBases.emplace_back(Base);
138 llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++");
139 CppIncludeBases.emplace_back(Base);
140 llvm::sys::path::append(CppIncludeBases[1], "include", "c++", Ver);
141 CppIncludeBases.emplace_back(GccLibDir);
142 llvm::sys::path::append(CppIncludeBases[2], "include", "c++");
143 for (auto &CppIncludeBase : CppIncludeBases) {
144 CppIncludeBase += llvm::sys::path::get_separator();
145 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase);
146 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch);
147 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward");
Yaron Keren1c0070c2015-07-02 04:45:27 +0000148 }
149}