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