clang  3.7.0
MinGWToolChain.cpp
Go to the documentation of this file.
1 //===--- MinGWToolChain.cpp - MinGWToolChain Implementation ---------------===//
2 //
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 
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;
22 
23 namespace {
24 // Simplified from Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple.
25 bool findGccVersion(StringRef LibDir, std::string &GccLibDir,
26  std::string &Ver) {
27  Generic_GCC::GCCVersion Version = Generic_GCC::GCCVersion::Parse("0.0.0");
28  std::error_code EC;
29  for (llvm::sys::fs::directory_iterator LI(LibDir, EC), LE; !EC && LI != LE;
30  LI = LI.increment(EC)) {
31  StringRef VersionText = llvm::sys::path::filename(LI->path());
32  Generic_GCC::GCCVersion CandidateVersion =
33  Generic_GCC::GCCVersion::Parse(VersionText);
34  if (CandidateVersion.Major == -1)
35  continue;
36  if (CandidateVersion <= Version)
37  continue;
38  Ver = VersionText;
39  GccLibDir = LI->path();
40  }
41  return Ver.size();
42 }
43 }
44 
45 void MinGW::findGccLibDir() {
47  Archs.emplace_back(getTriple().getArchName());
48  Archs[0] += "-w64-mingw32";
49  Archs.emplace_back("mingw32");
50  Arch = Archs[0].str();
51  // lib: Arch Linux, Ubuntu, Windows
52  // lib64: openSUSE Linux
53  for (StringRef CandidateLib : {"lib", "lib64"}) {
54  for (StringRef CandidateArch : Archs) {
56  llvm::sys::path::append(LibDir, CandidateLib, "gcc", CandidateArch);
57  if (findGccVersion(LibDir, GccLibDir, Ver)) {
58  Arch = CandidateArch;
59  return;
60  }
61  }
62  }
63 }
64 
65 MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
66  : ToolChain(D, Triple, Args) {
67  getProgramPaths().push_back(getDriver().getInstalledDir());
68 
69 // In Windows there aren't any standard install locations, we search
70 // for gcc on the PATH. In Linux the base is always /usr.
71 #ifdef LLVM_ON_WIN32
72  if (getDriver().SysRoot.size())
74  else if (llvm::ErrorOr<std::string> GPPName =
75  llvm::sys::findProgramByName("gcc"))
76  Base = llvm::sys::path::parent_path(
77  llvm::sys::path::parent_path(GPPName.get()));
78  else
79  Base = llvm::sys::path::parent_path(getDriver().getInstalledDir());
80 #else
81  if (getDriver().SysRoot.size())
83  else
84  Base = "/usr";
85 #endif
86 
87  Base += llvm::sys::path::get_separator();
88  findGccLibDir();
89  // GccLibDir must precede Base/lib so that the
90  // correct crtbegin.o ,cetend.o would be found.
91  getFilePaths().push_back(GccLibDir);
92  getFilePaths().push_back(
93  (Base + Arch + llvm::sys::path::get_separator() + "lib").str());
94  getFilePaths().push_back(Base + "lib");
95  // openSUSE
96  getFilePaths().push_back(Base + Arch + "/sys-root/mingw/lib");
97 }
98 
99 bool MinGW::IsIntegratedAssemblerDefault() const { return true; }
100 
102  switch (AC) {
104  if (!Preprocessor)
105  Preprocessor.reset(new tools::gcc::Preprocessor(*this));
106  return Preprocessor.get();
108  if (!Compiler)
109  Compiler.reset(new tools::gcc::Compiler(*this));
110  return Compiler.get();
111  default:
112  return ToolChain::getTool(AC);
113  }
114 }
115 
117  return new tools::MinGW::Assembler(*this);
118 }
119 
120 Tool *MinGW::buildLinker() const { return new tools::MinGW::Linker(*this); }
121 
123  return getArch() == llvm::Triple::x86_64;
124 }
125 
126 bool MinGW::isPICDefault() const { return getArch() == llvm::Triple::x86_64; }
127 
128 bool MinGW::isPIEDefault() const { return false; }
129 
131  return getArch() == llvm::Triple::x86_64;
132 }
133 
135  return getArch() == llvm::Triple::x86_64;
136 }
137 
138 // Include directories for various hosts:
139 
140 // Windows, mingw.org
141 // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++
142 // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\mingw32
143 // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\backward
144 // c:\mingw\lib\gcc\mingw32\4.8.1\include
145 // c:\mingw\include
146 // c:\mingw\lib\gcc\mingw32\4.8.1\include-fixed
147 // c:\mingw\mingw32\include
148 
149 // Windows, mingw-w64 mingw-builds
150 // c:\mingw32\lib\gcc\i686-w64-mingw32\4.9.1\include
151 // c:\mingw32\lib\gcc\i686-w64-mingw32\4.9.1\include-fixed
152 // c:\mingw32\i686-w64-mingw32\include
153 // c:\mingw32\i686-w64-mingw32\include\c++
154 // c:\mingw32\i686-w64-mingw32\include\c++\i686-w64-mingw32
155 // c:\mingw32\i686-w64-mingw32\include\c++\backward
156 
157 // Windows, mingw-w64 msys2
158 // c:\msys64\mingw32\lib\gcc\i686-w64-mingw32\4.9.2\include
159 // c:\msys64\mingw32\include
160 // c:\msys64\mingw32\lib\gcc\i686-w64-mingw32\4.9.2\include-fixed
161 // c:\msys64\mingw32\i686-w64-mingw32\include
162 // c:\msys64\mingw32\include\c++\4.9.2
163 // c:\msys64\mingw32\include\c++\4.9.2\i686-w64-mingw32
164 // c:\msys64\mingw32\include\c++\4.9.2\backward
165 
166 // openSUSE
167 // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++
168 // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32
169 // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/backward
170 // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include
171 // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include-fixed
172 // /usr/x86_64-w64-mingw32/sys-root/mingw/include
173 
174 // Arch Linux
175 // /usr/i686-w64-mingw32/include/c++/5.1.0
176 // /usr/i686-w64-mingw32/include/c++/5.1.0/i686-w64-mingw32
177 // /usr/i686-w64-mingw32/include/c++/5.1.0/backward
178 // /usr/lib/gcc/i686-w64-mingw32/5.1.0/include
179 // /usr/lib/gcc/i686-w64-mingw32/5.1.0/include-fixed
180 // /usr/i686-w64-mingw32/include
181 
182 // Ubuntu
183 // /usr/include/c++/4.8
184 // /usr/include/c++/4.8/x86_64-w64-mingw32
185 // /usr/include/c++/4.8/backward
186 // /usr/lib/gcc/x86_64-w64-mingw32/4.8/include
187 // /usr/lib/gcc/x86_64-w64-mingw32/4.8/include-fixed
188 // /usr/x86_64-w64-mingw32/include
189 
190 void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
191  ArgStringList &CC1Args) const {
192  if (DriverArgs.hasArg(options::OPT_nostdinc))
193  return;
194 
195  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
196  SmallString<1024> P(getDriver().ResourceDir);
197  llvm::sys::path::append(P, "include");
198  addSystemInclude(DriverArgs, CC1Args, P.str());
199  }
200 
201  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
202  return;
203 
204  if (GetRuntimeLibType(DriverArgs) == ToolChain::RLT_Libgcc) {
205  llvm::SmallString<1024> IncludeDir(GccLibDir);
206  llvm::sys::path::append(IncludeDir, "include");
207  addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
208  IncludeDir += "-fixed";
209  // openSUSE
210  addSystemInclude(DriverArgs, CC1Args,
211  Base + Arch + "/sys-root/mingw/include");
212  addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
213  }
214  addSystemInclude(DriverArgs, CC1Args,
215  Base + Arch + llvm::sys::path::get_separator() + "include");
216  addSystemInclude(DriverArgs, CC1Args, Base + "include");
217 }
218 
219 void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
220  ArgStringList &CC1Args) const {
221  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
222  DriverArgs.hasArg(options::OPT_nostdincxx))
223  return;
224 
225  switch (GetCXXStdlibType(DriverArgs)) {
227  addSystemInclude(DriverArgs, CC1Args,
228  Base + "include" + llvm::sys::path::get_separator() +
229  "c++" + llvm::sys::path::get_separator() + "v1");
230  break;
231 
233  llvm::SmallVector<llvm::SmallString<1024>, 4> CppIncludeBases;
234  CppIncludeBases.emplace_back(Base);
235  llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++");
236  CppIncludeBases.emplace_back(Base);
237  llvm::sys::path::append(CppIncludeBases[1], Arch, "include", "c++", Ver);
238  CppIncludeBases.emplace_back(Base);
239  llvm::sys::path::append(CppIncludeBases[2], "include", "c++", Ver);
240  CppIncludeBases.emplace_back(GccLibDir);
241  llvm::sys::path::append(CppIncludeBases[3], "include", "c++");
242  for (auto &CppIncludeBase : CppIncludeBases) {
243  addSystemInclude(DriverArgs, CC1Args, CppIncludeBase);
244  CppIncludeBase += llvm::sys::path::get_separator();
245  addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch);
246  addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward");
247  }
248  break;
249  }
250 }
virtual Tool * getTool(Action::ActionClass AC) const
Definition: ToolChain.cpp:144
bool isPICDefault() const override
Test whether this toolchain defaults to PIC.
virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const
Definition: ToolChain.cpp:379
bool IsUnwindTablesDefault() const override
const Driver & getDriver() const
Definition: ToolChain.cpp:75
Struct to store and manipulate GCC versions.
Definition: ToolChains.h:48
llvm::Triple::ArchType getArch() const
Definition: ToolChain.h:125
path_list & getProgramPaths()
Definition: ToolChain.h:141
bool isPICDefaultForced() const override
Tests whether this toolchain forces its default for PIC, PIE or non-PIC. If this returns true...
path_list & getFilePaths()
Definition: ToolChain.h:138
AnnotatingParser & P
Tool * buildAssembler() const override
virtual RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const
Definition: ToolChain.cpp:363
bool IsIntegratedAssemblerDefault() const override
bool isPIEDefault() const override
Test whether this toolchain defaults to PIE.
static void addSystemInclude(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
Utility function to add a system include directory to CC1 arguments.
Definition: ToolChain.cpp:394
std::string SysRoot
sysroot, if present
Definition: Driver.h:102
Tool - Information on a specific compilation tool.
Definition: Tool.h:34
void AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Tool * getTool(Action::ActionClass AC) const override
Tool * buildLinker() const override
void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add the clang cc1 arguments for system include paths.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:96
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:43