blob: 197c19e91413c688a3af17287cfadafabee1e4de [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
Yaron Keren88e69e42015-07-14 15:02:09 +000027 llvm::SmallString<1024> LibDir;
28
29#ifdef LLVM_ON_WIN32
Yaron Keren1c0070c2015-07-02 04:45:27 +000030 if (getDriver().SysRoot.size())
31 Base = getDriver().SysRoot;
32 else if (llvm::ErrorOr<std::string> GPPName =
33 llvm::sys::findProgramByName("gcc"))
34 Base = llvm::sys::path::parent_path(
35 llvm::sys::path::parent_path(GPPName.get()));
36 else
37 Base = llvm::sys::path::parent_path(getDriver().getInstalledDir());
38 Base += llvm::sys::path::get_separator();
Yaron Keren88e69e42015-07-14 15:02:09 +000039 LibDir = Base;
Yaron Keren1c0070c2015-07-02 04:45:27 +000040 llvm::sys::path::append(LibDir, "lib", "gcc");
Yaron Keren88e69e42015-07-14 15:02:09 +000041#else
42 if (getDriver().SysRoot.size())
43 Base = getDriver().SysRoot;
44 else
45 Base = "/usr/";
46 LibDir = Base;
47 llvm::sys::path::append(LibDir, "lib64", "gcc");
48#endif
49
Yaron Keren1c0070c2015-07-02 04:45:27 +000050 LibDir += llvm::sys::path::get_separator();
51
52 // First look for mingw-w64.
53 Arch = getTriple().getArchName();
54 Arch += "-w64-mingw32";
55 std::error_code EC;
56 llvm::sys::fs::directory_iterator MingW64Entry(LibDir + Arch, EC);
57 if (!EC) {
58 GccLibDir = MingW64Entry->path();
Yaron Keren763a38a2015-07-06 07:40:10 +000059 Ver = llvm::sys::path::filename(GccLibDir);
Yaron Keren1c0070c2015-07-02 04:45:27 +000060 } else {
61 // If mingw-w64 not found, try looking for mingw.org.
62 Arch = "mingw32";
63 llvm::sys::fs::directory_iterator MingwOrgEntry(LibDir + Arch, EC);
64 if (!EC)
65 GccLibDir = MingwOrgEntry->path();
66 }
67 Arch += llvm::sys::path::get_separator();
68 // GccLibDir must precede Base/lib so that the
69 // correct crtbegin.o ,cetend.o would be found.
70 getFilePaths().push_back(GccLibDir);
71 getFilePaths().push_back(Base + "lib");
72 getFilePaths().push_back(Base + Arch + "lib");
Yaron Keren88e69e42015-07-14 15:02:09 +000073#ifdef LLVM_ON_UNIX
74 // For openSUSE.
75 getFilePaths().push_back(Base + Arch + "sys-root/mingw/lib");
76#endif
Yaron Keren1c0070c2015-07-02 04:45:27 +000077}
78
79bool MinGW::IsIntegratedAssemblerDefault() const { return true; }
80
81Tool *MinGW::getTool(Action::ActionClass AC) const {
82 switch (AC) {
83 case Action::PreprocessJobClass:
84 if (!Preprocessor)
85 Preprocessor.reset(new tools::gcc::Preprocessor(*this));
86 return Preprocessor.get();
87 case Action::CompileJobClass:
88 if (!Compiler)
89 Compiler.reset(new tools::gcc::Compiler(*this));
90 return Compiler.get();
91 default:
92 return ToolChain::getTool(AC);
93 }
94}
95
96Tool *MinGW::buildAssembler() const {
97 return new tools::MinGW::Assembler(*this);
98}
99
100Tool *MinGW::buildLinker() const { return new tools::MinGW::Linker(*this); }
101
102bool MinGW::IsUnwindTablesDefault() const {
103 return getArch() == llvm::Triple::x86_64;
104}
105
106bool MinGW::isPICDefault() const { return getArch() == llvm::Triple::x86_64; }
107
108bool MinGW::isPIEDefault() const { return false; }
109
110bool MinGW::isPICDefaultForced() const {
111 return getArch() == llvm::Triple::x86_64;
112}
113
114bool MinGW::UseSEHExceptions() const {
115 return getArch() == llvm::Triple::x86_64;
116}
117
118void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
119 ArgStringList &CC1Args) const {
120 if (DriverArgs.hasArg(options::OPT_nostdinc))
121 return;
122
123 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
124 SmallString<1024> P(getDriver().ResourceDir);
125 llvm::sys::path::append(P, "include");
126 addSystemInclude(DriverArgs, CC1Args, P.str());
127 }
128
129 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
130 return;
131
132 llvm::SmallString<1024> IncludeDir(GccLibDir);
133 llvm::sys::path::append(IncludeDir, "include");
134 addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
135 IncludeDir += "-fixed";
Yaron Keren88e69e42015-07-14 15:02:09 +0000136#ifdef LLVM_ON_UNIX
137 // For openSUSE.
138 addSystemInclude(DriverArgs, CC1Args,
139 "/usr/x86_64-w64-mingw32/sys-root/mingw/include");
140#endif
Yaron Keren1c0070c2015-07-02 04:45:27 +0000141 addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
142 addSystemInclude(DriverArgs, CC1Args, Base + Arch + "include");
143 addSystemInclude(DriverArgs, CC1Args, Base + "include");
144}
145
146void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
147 ArgStringList &CC1Args) const {
148 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
149 DriverArgs.hasArg(options::OPT_nostdincxx))
150 return;
151
Yaron Keren763a38a2015-07-06 07:40:10 +0000152 // C++ includes may be found in several locations depending on distribution.
Yaron Keren88e69e42015-07-14 15:02:09 +0000153 // Windows
154 // -------
Yaron Keren763a38a2015-07-06 07:40:10 +0000155 // mingw-w64 mingw-builds: $sysroot/i686-w64-mingw32/include/c++.
156 // mingw-w64 msys2: $sysroot/include/c++/4.9.2
157 // mingw.org: GccLibDir/include/c++
Yaron Keren88e69e42015-07-14 15:02:09 +0000158 //
159 // Linux
160 // -----
161 // openSUSE: GccLibDir/include/c++
Yaron Keren763a38a2015-07-06 07:40:10 +0000162 llvm::SmallVector<llvm::SmallString<1024>, 3> CppIncludeBases;
163 CppIncludeBases.emplace_back(Base);
164 llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++");
165 CppIncludeBases.emplace_back(Base);
166 llvm::sys::path::append(CppIncludeBases[1], "include", "c++", Ver);
167 CppIncludeBases.emplace_back(GccLibDir);
168 llvm::sys::path::append(CppIncludeBases[2], "include", "c++");
169 for (auto &CppIncludeBase : CppIncludeBases) {
170 CppIncludeBase += llvm::sys::path::get_separator();
171 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase);
172 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch);
173 addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward");
Yaron Keren1c0070c2015-07-02 04:45:27 +0000174 }
175}