1 //===--- MinGWToolChain.cpp - MinGWToolChain Implementation
2 //-----------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
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"
18 using namespace clang::diag;
19 using namespace clang::driver;
20 using namespace clang::driver::toolchains;
21 using namespace clang;
22 using namespace llvm::opt;
24 MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
25 : ToolChain(D, Triple, Args) {
26 getProgramPaths().push_back(getDriver().getInstalledDir());
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()));
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();
41 // First look for mingw-w64.
42 Arch = getTriple().getArchName();
43 Arch += "-w64-mingw32";
45 llvm::sys::fs::directory_iterator MingW64Entry(LibDir + Arch, EC);
47 GccLibDir = MingW64Entry->path();
49 // If mingw-w64 not found, try looking for mingw.org.
51 llvm::sys::fs::directory_iterator MingwOrgEntry(LibDir + Arch, EC);
53 GccLibDir = MingwOrgEntry->path();
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");
63 bool MinGW::IsIntegratedAssemblerDefault() const { return true; }
65 Tool *MinGW::getTool(Action::ActionClass AC) const {
67 case Action::PreprocessJobClass:
69 Preprocessor.reset(new tools::gcc::Preprocessor(*this));
70 return Preprocessor.get();
71 case Action::CompileJobClass:
73 Compiler.reset(new tools::gcc::Compiler(*this));
74 return Compiler.get();
76 return ToolChain::getTool(AC);
80 Tool *MinGW::buildAssembler() const {
81 return new tools::MinGW::Assembler(*this);
84 Tool *MinGW::buildLinker() const { return new tools::MinGW::Linker(*this); }
86 bool MinGW::IsUnwindTablesDefault() const {
87 return getArch() == llvm::Triple::x86_64;
90 bool MinGW::isPICDefault() const { return getArch() == llvm::Triple::x86_64; }
92 bool MinGW::isPIEDefault() const { return false; }
94 bool MinGW::isPICDefaultForced() const {
95 return getArch() == llvm::Triple::x86_64;
98 bool MinGW::UseSEHExceptions() const {
99 return getArch() == llvm::Triple::x86_64;
102 void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
103 ArgStringList &CC1Args) const {
104 if (DriverArgs.hasArg(options::OPT_nostdinc))
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());
113 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
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");
125 void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
126 ArgStringList &CC1Args) const {
127 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
128 DriverArgs.hasArg(options::OPT_nostdincxx))
131 llvm::SmallString<1024> IncludeDir;
132 for (bool MingW64 : {true, false}) {
134 IncludeDir = Base + Arch;
136 IncludeDir = GccLibDir;
137 llvm::sys::path::append(IncludeDir, "include", "c++");
138 addSystemInclude(DriverArgs, CC1Args, IncludeDir.str());
139 IncludeDir += llvm::sys::path::get_separator();
140 addSystemInclude(DriverArgs, CC1Args, IncludeDir.str() + Arch);
141 addSystemInclude(DriverArgs, CC1Args, IncludeDir.str() + "backward");