1 //===--- MinGWToolChain.cpp - MinGWToolChain Implementation ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
17 using namespace clang::diag;
18 using namespace clang::driver;
19 using namespace clang::driver::toolchains;
20 using namespace clang;
21 using namespace llvm::opt;
23 MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
24 : ToolChain(D, Triple, Args) {
25 getProgramPaths().push_back(getDriver().getInstalledDir());
27 llvm::SmallString<1024> LibDir;
30 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()));
37 Base = llvm::sys::path::parent_path(getDriver().getInstalledDir());
38 Base += llvm::sys::path::get_separator();
40 llvm::sys::path::append(LibDir, "lib", "gcc");
42 if (getDriver().SysRoot.size())
43 Base = getDriver().SysRoot;
47 llvm::sys::path::append(LibDir, "lib64", "gcc");
50 LibDir += llvm::sys::path::get_separator();
52 // First look for mingw-w64.
53 Arch = getTriple().getArchName();
54 Arch += "-w64-mingw32";
56 llvm::sys::fs::directory_iterator MingW64Entry(LibDir + Arch, EC);
58 GccLibDir = MingW64Entry->path();
59 Ver = llvm::sys::path::filename(GccLibDir);
61 // If mingw-w64 not found, try looking for mingw.org.
63 llvm::sys::fs::directory_iterator MingwOrgEntry(LibDir + Arch, EC);
65 GccLibDir = MingwOrgEntry->path();
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");
75 getFilePaths().push_back(Base + Arch + "sys-root/mingw/lib");
79 bool MinGW::IsIntegratedAssemblerDefault() const { return true; }
81 Tool *MinGW::getTool(Action::ActionClass AC) const {
83 case Action::PreprocessJobClass:
85 Preprocessor.reset(new tools::gcc::Preprocessor(*this));
86 return Preprocessor.get();
87 case Action::CompileJobClass:
89 Compiler.reset(new tools::gcc::Compiler(*this));
90 return Compiler.get();
92 return ToolChain::getTool(AC);
96 Tool *MinGW::buildAssembler() const {
97 return new tools::MinGW::Assembler(*this);
100 Tool *MinGW::buildLinker() const { return new tools::MinGW::Linker(*this); }
102 bool MinGW::IsUnwindTablesDefault() const {
103 return getArch() == llvm::Triple::x86_64;
106 bool MinGW::isPICDefault() const { return getArch() == llvm::Triple::x86_64; }
108 bool MinGW::isPIEDefault() const { return false; }
110 bool MinGW::isPICDefaultForced() const {
111 return getArch() == llvm::Triple::x86_64;
114 bool MinGW::UseSEHExceptions() const {
115 return getArch() == llvm::Triple::x86_64;
118 void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
119 ArgStringList &CC1Args) const {
120 if (DriverArgs.hasArg(options::OPT_nostdinc))
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());
129 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
132 llvm::SmallString<1024> IncludeDir(GccLibDir);
133 llvm::sys::path::append(IncludeDir, "include");
134 addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
135 IncludeDir += "-fixed";
138 addSystemInclude(DriverArgs, CC1Args,
139 "/usr/x86_64-w64-mingw32/sys-root/mingw/include");
141 addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
142 addSystemInclude(DriverArgs, CC1Args, Base + Arch + "include");
143 addSystemInclude(DriverArgs, CC1Args, Base + "include");
146 void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
147 ArgStringList &CC1Args) const {
148 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
149 DriverArgs.hasArg(options::OPT_nostdincxx))
152 // C++ includes may be found in several locations depending on distribution.
155 // 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++
161 // openSUSE: GccLibDir/include/c++
162 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");