/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/clang/lib/Driver/ToolChains.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- ToolChains.cpp - ToolChain Implementations -------------*- C++ -*-===// |
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/Basic/Cuda.h" |
12 | | #include "clang/Basic/ObjCRuntime.h" |
13 | | #include "clang/Basic/Version.h" |
14 | | #include "clang/Basic/VirtualFileSystem.h" |
15 | | #include "clang/Config/config.h" // for GCC_INSTALL_PREFIX |
16 | | #include "clang/Driver/Compilation.h" |
17 | | #include "clang/Driver/Distro.h" |
18 | | #include "clang/Driver/Driver.h" |
19 | | #include "clang/Driver/DriverDiagnostic.h" |
20 | | #include "clang/Driver/Options.h" |
21 | | #include "clang/Driver/SanitizerArgs.h" |
22 | | #include "llvm/ADT/STLExtras.h" |
23 | | #include "llvm/ADT/SmallString.h" |
24 | | #include "llvm/ADT/StringExtras.h" |
25 | | #include "llvm/ADT/StringSwitch.h" |
26 | | #include "llvm/Option/Arg.h" |
27 | | #include "llvm/Option/ArgList.h" |
28 | | #include "llvm/Option/OptTable.h" |
29 | | #include "llvm/Option/Option.h" |
30 | | #include "llvm/ProfileData/InstrProf.h" |
31 | | #include "llvm/Support/ErrorHandling.h" |
32 | | #include "llvm/Support/FileSystem.h" |
33 | | #include "llvm/Support/MemoryBuffer.h" |
34 | | #include "llvm/Support/Path.h" |
35 | | #include "llvm/Support/Program.h" |
36 | | #include "llvm/Support/TargetParser.h" |
37 | | #include "llvm/Support/raw_ostream.h" |
38 | | #include <cstdlib> // ::getenv |
39 | | #include <system_error> |
40 | | |
41 | | using namespace clang::driver; |
42 | | using namespace clang::driver::toolchains; |
43 | | using namespace clang; |
44 | | using namespace llvm::opt; |
45 | | |
46 | | MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) |
47 | 19.3k | : ToolChain(D, Triple, Args) { |
48 | 19.3k | // We expect 'as', 'ld', etc. to be adjacent to our install dir. |
49 | 19.3k | getProgramPaths().push_back(getDriver().getInstalledDir()); |
50 | 19.3k | if (getDriver().getInstalledDir() != getDriver().Dir) |
51 | 1.42k | getProgramPaths().push_back(getDriver().Dir); |
52 | 19.3k | } |
53 | | |
54 | | /// Darwin - Darwin tool chain for i386 and x86_64. |
55 | | Darwin::Darwin(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) |
56 | | : MachO(D, Triple, Args), TargetInitialized(false), |
57 | 19.2k | CudaInstallation(D, Triple, Args) {} |
58 | | |
59 | 30.4k | types::ID MachO::LookupTypeForExtension(StringRef Ext) const { |
60 | 30.4k | types::ID Ty = types::lookupTypeForExtension(Ext); |
61 | 30.4k | |
62 | 30.4k | // Darwin always preprocesses assembly files (unless -x is used explicitly). |
63 | 30.4k | if (Ty == types::TY_PP_Asm) |
64 | 20 | return types::TY_Asm; |
65 | 30.4k | |
66 | 30.3k | return Ty; |
67 | 30.4k | } |
68 | | |
69 | 29.3k | bool MachO::HasNativeLLVMSupport() const { return true; } |
70 | | |
71 | 19.5k | ToolChain::CXXStdlibType Darwin::GetDefaultCXXStdlibType() const { |
72 | 19.5k | // Default to use libc++ on OS X 10.9+ and iOS 7+. |
73 | 19.5k | if ((isTargetMacOS() && 19.5k !isMacosxVersionLT(10, 9)2.88k ) || |
74 | 17.2k | (isTargetIOSBased() && 17.2k !isIPhoneOSVersionLT(7, 0)16.6k ) || |
75 | 790 | isTargetWatchOSBased()) |
76 | 18.7k | return ToolChain::CST_Libcxx; |
77 | 19.5k | |
78 | 762 | return ToolChain::CST_Libstdcxx; |
79 | 19.5k | } |
80 | | |
81 | | /// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0. |
82 | 15.3k | ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const { |
83 | 15.3k | if (isTargetWatchOSBased()) |
84 | 23 | return ObjCRuntime(ObjCRuntime::WatchOS, TargetVersion); |
85 | 15.3k | if (15.3k isTargetIOSBased()15.3k ) |
86 | 12.8k | return ObjCRuntime(ObjCRuntime::iOS, TargetVersion); |
87 | 2.53k | if (2.53k isNonFragile2.53k ) |
88 | 2.44k | return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion); |
89 | 90 | return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion); |
90 | 2.53k | } |
91 | | |
92 | | /// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2. |
93 | 15.3k | bool Darwin::hasBlocksRuntime() const { |
94 | 15.3k | if (isTargetWatchOSBased()) |
95 | 23 | return true; |
96 | 15.3k | else if (15.3k isTargetIOSBased()15.3k ) |
97 | 12.8k | return !isIPhoneOSVersionLT(3, 2); |
98 | 2.54k | else { |
99 | 2.54k | assert(isTargetMacOS() && "unexpected darwin target"); |
100 | 2.54k | return !isMacosxVersionLT(10, 6); |
101 | 2.54k | } |
102 | 15.3k | } |
103 | | |
104 | | void Darwin::AddCudaIncludeArgs(const ArgList &DriverArgs, |
105 | 20 | ArgStringList &CC1Args) const { |
106 | 20 | CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); |
107 | 20 | } |
108 | | |
109 | | // This is just a MachO name translation routine and there's no |
110 | | // way to join this into ARMTargetParser without breaking all |
111 | | // other assumptions. Maybe MachO should consider standardising |
112 | | // their nomenclature. |
113 | 114 | static const char *ArmMachOArchName(StringRef Arch) { |
114 | 114 | return llvm::StringSwitch<const char *>(Arch) |
115 | 114 | .Case("armv6k", "armv6") |
116 | 114 | .Case("armv6m", "armv6m") |
117 | 114 | .Case("armv5tej", "armv5") |
118 | 114 | .Case("xscale", "xscale") |
119 | 114 | .Case("armv4t", "armv4t") |
120 | 114 | .Case("armv7", "armv7") |
121 | 114 | .Cases("armv7a", "armv7-a", "armv7") |
122 | 114 | .Cases("armv7r", "armv7-r", "armv7") |
123 | 114 | .Cases("armv7em", "armv7e-m", "armv7em") |
124 | 114 | .Cases("armv7k", "armv7-k", "armv7k") |
125 | 114 | .Cases("armv7m", "armv7-m", "armv7m") |
126 | 114 | .Cases("armv7s", "armv7-s", "armv7s") |
127 | 114 | .Default(nullptr); |
128 | 114 | } |
129 | | |
130 | 0 | static const char *ArmMachOArchNameCPU(StringRef CPU) { |
131 | 0 | unsigned ArchKind = llvm::ARM::parseCPUArch(CPU); |
132 | 0 | if (ArchKind == llvm::ARM::AK_INVALID) |
133 | 0 | return nullptr; |
134 | 0 | StringRef Arch = llvm::ARM::getArchName(ArchKind); |
135 | 0 |
|
136 | 0 | // FIXME: Make sure this MachO triple mangling is really necessary. |
137 | 0 | // ARMv5* normalises to ARMv5. |
138 | 0 | if (Arch.startswith("armv5")) |
139 | 0 | Arch = Arch.substr(0, 5); |
140 | 0 | // ARMv6*, except ARMv6M, normalises to ARMv6. |
141 | 0 | else if (0 Arch.startswith("armv6") && 0 !Arch.endswith("6m")0 ) |
142 | 0 | Arch = Arch.substr(0, 5); |
143 | 0 | // ARMv7A normalises to ARMv7. |
144 | 0 | else if (0 Arch.endswith("v7a")0 ) |
145 | 0 | Arch = Arch.substr(0, 5); |
146 | 0 | return Arch.data(); |
147 | 0 | } |
148 | | |
149 | 374 | static bool isSoftFloatABI(const ArgList &Args) { |
150 | 374 | Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, |
151 | 374 | options::OPT_mfloat_abi_EQ); |
152 | 374 | if (!A) |
153 | 166 | return false; |
154 | 374 | |
155 | 208 | return A->getOption().matches(options::OPT_msoft_float) || |
156 | 138 | (A->getOption().matches(options::OPT_mfloat_abi_EQ) && |
157 | 4 | A->getValue() == StringRef("soft")); |
158 | 374 | } |
159 | | |
160 | 5.56k | StringRef MachO::getMachOArchName(const ArgList &Args) const { |
161 | 5.56k | switch (getTriple().getArch()) { |
162 | 1.70k | default: |
163 | 1.70k | return getDefaultUniversalArchName(); |
164 | 1.70k | |
165 | 3.74k | case llvm::Triple::aarch64: |
166 | 3.74k | return "arm64"; |
167 | 1.70k | |
168 | 114 | case llvm::Triple::thumb: |
169 | 114 | case llvm::Triple::arm: |
170 | 114 | if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) |
171 | 114 | if (const char *114 Arch114 = ArmMachOArchName(A->getValue())) |
172 | 114 | return Arch; |
173 | 114 | |
174 | 0 | if (const Arg *0 A0 = Args.getLastArg(options::OPT_mcpu_EQ)) |
175 | 0 | if (const char *0 Arch0 = ArmMachOArchNameCPU(A->getValue())) |
176 | 0 | return Arch; |
177 | 0 |
|
178 | 0 | return "arm"; |
179 | 5.56k | } |
180 | 5.56k | } |
181 | | |
182 | 19.2k | Darwin::~Darwin() {} |
183 | | |
184 | 19.3k | MachO::~MachO() {} |
185 | | |
186 | | std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args, |
187 | 19.6k | types::ID InputType) const { |
188 | 19.6k | llvm::Triple Triple(ComputeLLVMTriple(Args, InputType)); |
189 | 19.6k | |
190 | 19.6k | // If the target isn't initialized (e.g., an unknown Darwin platform, return |
191 | 19.6k | // the default triple). |
192 | 19.6k | if (!isTargetInitialized()) |
193 | 1 | return Triple.getTriple(); |
194 | 19.6k | |
195 | 19.6k | SmallString<16> Str; |
196 | 19.6k | if (isTargetWatchOSBased()) |
197 | 35 | Str += "watchos"; |
198 | 19.5k | else if (19.5k isTargetTvOSBased()19.5k ) |
199 | 20 | Str += "tvos"; |
200 | 19.5k | else if (19.5k isTargetIOSBased()19.5k ) |
201 | 16.5k | Str += "ios"; |
202 | 19.5k | else |
203 | 2.96k | Str += "macosx"; |
204 | 19.6k | Str += getTargetVersion().getAsString(); |
205 | 19.6k | Triple.setOSName(Str); |
206 | 19.6k | |
207 | 19.6k | return Triple.getTriple(); |
208 | 19.6k | } |
209 | | |
210 | 0 | void Generic_ELF::anchor() {} |
211 | | |
212 | 4.18k | Tool *MachO::getTool(Action::ActionClass AC) const { |
213 | 4.18k | switch (AC) { |
214 | 8 | case Action::LipoJobClass: |
215 | 8 | if (!Lipo) |
216 | 8 | Lipo.reset(new tools::darwin::Lipo(*this)); |
217 | 8 | return Lipo.get(); |
218 | 12 | case Action::DsymutilJobClass: |
219 | 12 | if (!Dsymutil) |
220 | 12 | Dsymutil.reset(new tools::darwin::Dsymutil(*this)); |
221 | 12 | return Dsymutil.get(); |
222 | 2 | case Action::VerifyDebugInfoJobClass: |
223 | 2 | if (!VerifyDebug) |
224 | 2 | VerifyDebug.reset(new tools::darwin::VerifyDebug(*this)); |
225 | 2 | return VerifyDebug.get(); |
226 | 4.16k | default: |
227 | 4.16k | return ToolChain::getTool(AC); |
228 | 4.18k | } |
229 | 4.18k | } |
230 | | |
231 | 4.14k | Tool *MachO::buildLinker() const { return new tools::darwin::Linker(*this); } |
232 | | |
233 | 14 | Tool *MachO::buildAssembler() const { |
234 | 14 | return new tools::darwin::Assembler(*this); |
235 | 14 | } |
236 | | |
237 | | DarwinClang::DarwinClang(const Driver &D, const llvm::Triple &Triple, |
238 | | const ArgList &Args) |
239 | 19.2k | : Darwin(D, Triple, Args) {} |
240 | | |
241 | 15.4k | void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const { |
242 | 15.4k | // For modern targets, promote certain warnings to errors. |
243 | 15.4k | if (isTargetWatchOSBased() || 15.4k getTriple().isArch64Bit()15.3k ) {15.2k |
244 | 15.2k | // Always enable -Wdeprecated-objc-isa-usage and promote it |
245 | 15.2k | // to an error. |
246 | 15.2k | CC1Args.push_back("-Wdeprecated-objc-isa-usage"); |
247 | 15.2k | CC1Args.push_back("-Werror=deprecated-objc-isa-usage"); |
248 | 15.2k | |
249 | 15.2k | // For iOS and watchOS, also error about implicit function declarations, |
250 | 15.2k | // as that can impact calling conventions. |
251 | 15.2k | if (!isTargetMacOS()) |
252 | 12.7k | CC1Args.push_back("-Werror=implicit-function-declaration"); |
253 | 15.2k | } |
254 | 15.4k | } |
255 | | |
256 | | /// \brief Determine whether Objective-C automated reference counting is |
257 | | /// enabled. |
258 | 0 | static bool isObjCAutoRefCount(const ArgList &Args) { |
259 | 0 | return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false); |
260 | 0 | } |
261 | | |
262 | | void DarwinClang::AddLinkARCArgs(const ArgList &Args, |
263 | 4 | ArgStringList &CmdArgs) const { |
264 | 4 | // Avoid linking compatibility stubs on i386 mac. |
265 | 4 | if (isTargetMacOS() && 4 getArch() == llvm::Triple::x864 ) |
266 | 1 | return; |
267 | 4 | |
268 | 3 | ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true); |
269 | 3 | |
270 | 3 | if ((runtime.hasNativeARC() || 3 !isObjCAutoRefCount(Args)0 ) && |
271 | 3 | runtime.hasSubscripting()) |
272 | 1 | return; |
273 | 3 | |
274 | 2 | CmdArgs.push_back("-force_load"); |
275 | 2 | SmallString<128> P(getDriver().ClangExecutable); |
276 | 2 | llvm::sys::path::remove_filename(P); // 'clang' |
277 | 2 | llvm::sys::path::remove_filename(P); // 'bin' |
278 | 2 | llvm::sys::path::append(P, "lib", "arc", "libarclite_"); |
279 | 2 | // Mash in the platform. |
280 | 2 | if (isTargetWatchOSSimulator()) |
281 | 0 | P += "watchsimulator"; |
282 | 2 | else if (2 isTargetWatchOS()2 ) |
283 | 0 | P += "watchos"; |
284 | 2 | else if (2 isTargetTvOSSimulator()2 ) |
285 | 0 | P += "appletvsimulator"; |
286 | 2 | else if (2 isTargetTvOS()2 ) |
287 | 0 | P += "appletvos"; |
288 | 2 | else if (2 isTargetIOSSimulator()2 ) |
289 | 0 | P += "iphonesimulator"; |
290 | 2 | else if (2 isTargetIPhoneOS()2 ) |
291 | 0 | P += "iphoneos"; |
292 | 2 | else |
293 | 2 | P += "macosx"; |
294 | 2 | P += ".a"; |
295 | 2 | |
296 | 2 | CmdArgs.push_back(Args.MakeArgString(P)); |
297 | 2 | } |
298 | | |
299 | 125 | unsigned DarwinClang::GetDefaultDwarfVersion() const { |
300 | 125 | // Default to use DWARF 2 on OS X 10.10 / iOS 8 and lower. |
301 | 125 | if ((isTargetMacOS() && 125 isMacosxVersionLT(10, 11)117 ) || |
302 | 103 | (isTargetIOSBased() && 103 isIPhoneOSVersionLT(9)7 )) |
303 | 27 | return 2; |
304 | 98 | return 4; |
305 | 125 | } |
306 | | |
307 | | void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs, |
308 | | StringRef DarwinLibName, bool AlwaysLink, |
309 | 4.15k | bool IsEmbedded, bool AddRPath) const { |
310 | 4.15k | SmallString<128> Dir(getDriver().ResourceDir); |
311 | 4.14k | llvm::sys::path::append(Dir, "lib", IsEmbedded ? "macho_embedded"10 : "darwin"4.14k ); |
312 | 4.15k | |
313 | 4.15k | SmallString<128> P(Dir); |
314 | 4.15k | llvm::sys::path::append(P, DarwinLibName); |
315 | 4.15k | |
316 | 4.15k | // For now, allow missing resource libraries to support developers who may |
317 | 4.15k | // not have compiler-rt checked out or integrated into their build (unless |
318 | 4.15k | // we explicitly force linking with this library). |
319 | 4.15k | if (AlwaysLink || 4.15k getVFS().exists(P)4.12k ) |
320 | 38 | CmdArgs.push_back(Args.MakeArgString(P)); |
321 | 4.15k | |
322 | 4.15k | // Adding the rpaths might negatively interact when other rpaths are involved, |
323 | 4.15k | // so we should make sure we add the rpaths last, after all user-specified |
324 | 4.15k | // rpaths. This is currently true from this place, but we need to be |
325 | 4.15k | // careful if this function is ever called before user's rpaths are emitted. |
326 | 4.15k | if (AddRPath4.15k ) {21 |
327 | 21 | assert(DarwinLibName.endswith(".dylib") && "must be a dynamic library"); |
328 | 21 | |
329 | 21 | // Add @executable_path to rpath to support having the dylib copied with |
330 | 21 | // the executable. |
331 | 21 | CmdArgs.push_back("-rpath"); |
332 | 21 | CmdArgs.push_back("@executable_path"); |
333 | 21 | |
334 | 21 | // Add the path to the resource dir to rpath to support using the dylib |
335 | 21 | // from the default location without copying. |
336 | 21 | CmdArgs.push_back("-rpath"); |
337 | 21 | CmdArgs.push_back(Args.MakeArgString(Dir)); |
338 | 21 | } |
339 | 4.15k | } |
340 | | |
341 | 17.6k | StringRef Darwin::getPlatformFamily() const { |
342 | 17.6k | switch (TargetPlatform) { |
343 | 1.16k | case DarwinPlatformKind::MacOS: |
344 | 1.16k | return "MacOSX"; |
345 | 16.4k | case DarwinPlatformKind::IPhoneOS: |
346 | 16.4k | case DarwinPlatformKind::IPhoneOSSimulator: |
347 | 16.4k | return "iPhone"; |
348 | 4 | case DarwinPlatformKind::TvOS: |
349 | 4 | case DarwinPlatformKind::TvOSSimulator: |
350 | 4 | return "AppleTV"; |
351 | 4 | case DarwinPlatformKind::WatchOS: |
352 | 4 | case DarwinPlatformKind::WatchOSSimulator: |
353 | 4 | return "Watch"; |
354 | 17.6k | } |
355 | 0 | llvm_unreachable0 ("Unsupported platform");0 |
356 | 0 | } |
357 | | |
358 | 35.2k | StringRef Darwin::getSDKName(StringRef isysroot) { |
359 | 35.2k | // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk |
360 | 35.2k | llvm::sys::path::const_iterator SDKDir; |
361 | 35.2k | auto BeginSDK = llvm::sys::path::begin(isysroot); |
362 | 35.2k | auto EndSDK = llvm::sys::path::end(isysroot); |
363 | 352k | for (auto IT = BeginSDK; IT != EndSDK352k ; ++IT317k ) {352k |
364 | 352k | StringRef SDK = *IT; |
365 | 352k | if (SDK.endswith(".sdk")) |
366 | 35.2k | return SDK.slice(0, SDK.size() - 4); |
367 | 352k | } |
368 | 48 | return ""; |
369 | 35.2k | } |
370 | | |
371 | 29 | StringRef Darwin::getOSLibraryNameSuffix() const { |
372 | 29 | switch(TargetPlatform) { |
373 | 16 | case DarwinPlatformKind::MacOS: |
374 | 16 | return "osx"; |
375 | 3 | case DarwinPlatformKind::IPhoneOS: |
376 | 3 | return "ios"; |
377 | 2 | case DarwinPlatformKind::IPhoneOSSimulator: |
378 | 2 | return "iossim"; |
379 | 3 | case DarwinPlatformKind::TvOS: |
380 | 3 | return "tvos"; |
381 | 1 | case DarwinPlatformKind::TvOSSimulator: |
382 | 1 | return "tvossim"; |
383 | 3 | case DarwinPlatformKind::WatchOS: |
384 | 3 | return "watchos"; |
385 | 1 | case DarwinPlatformKind::WatchOSSimulator: |
386 | 1 | return "watchossim"; |
387 | 29 | } |
388 | 0 | llvm_unreachable0 ("Unsupported platform");0 |
389 | 0 | } |
390 | | |
391 | | void Darwin::addProfileRTLibs(const ArgList &Args, |
392 | 4.12k | ArgStringList &CmdArgs) const { |
393 | 4.12k | if (!needsProfileRT(Args)4.12k ) return4.11k ; |
394 | 4.12k | |
395 | 8 | AddLinkRuntimeLib(Args, CmdArgs, (Twine("libclang_rt.profile_") + |
396 | 8 | getOSLibraryNameSuffix() + ".a").str(), |
397 | 8 | /*AlwaysLink*/ true); |
398 | 8 | } |
399 | | |
400 | | void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args, |
401 | | ArgStringList &CmdArgs, |
402 | 21 | StringRef Sanitizer) const { |
403 | 21 | AddLinkRuntimeLib( |
404 | 21 | Args, CmdArgs, |
405 | 21 | (Twine("libclang_rt.") + Sanitizer + "_" + |
406 | 21 | getOSLibraryNameSuffix() + "_dynamic.dylib").str(), |
407 | 21 | /*AlwaysLink*/ true, /*IsEmbedded*/ false, |
408 | 21 | /*AddRPath*/ true); |
409 | 21 | } |
410 | | |
411 | | ToolChain::RuntimeLibType DarwinClang::GetRuntimeLibType( |
412 | 4.11k | const ArgList &Args) const { |
413 | 4.11k | if (Arg* A4.11k = Args.getLastArg(options::OPT_rtlib_EQ)) {0 |
414 | 0 | StringRef Value = A->getValue(); |
415 | 0 | if (Value != "compiler-rt") |
416 | 0 | getDriver().Diag(diag::err_drv_unsupported_rtlib_for_platform) |
417 | 0 | << Value << "darwin"; |
418 | 0 | } |
419 | 4.11k | |
420 | 4.11k | return ToolChain::RLT_CompilerRT; |
421 | 4.11k | } |
422 | | |
423 | | void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, |
424 | 4.11k | ArgStringList &CmdArgs) const { |
425 | 4.11k | // Call once to ensure diagnostic is printed if wrong value was specified |
426 | 4.11k | GetRuntimeLibType(Args); |
427 | 4.11k | |
428 | 4.11k | // Darwin doesn't support real static executables, don't link any runtime |
429 | 4.11k | // libraries with -static. |
430 | 4.11k | if (Args.hasArg(options::OPT_static) || |
431 | 4.11k | Args.hasArg(options::OPT_fapple_kext) || |
432 | 4.11k | Args.hasArg(options::OPT_mkernel)) |
433 | 2 | return; |
434 | 4.11k | |
435 | 4.11k | // Reject -static-libgcc for now, we can deal with this when and if someone |
436 | 4.11k | // cares. This is useful in situations where someone wants to statically link |
437 | 4.11k | // something like libstdc++, and needs its runtime support routines. |
438 | 4.11k | if (const Arg *4.11k A4.11k = Args.getLastArg(options::OPT_static_libgcc)) {0 |
439 | 0 | getDriver().Diag(diag::err_drv_unsupported_opt) << A->getAsString(Args); |
440 | 0 | return; |
441 | 0 | } |
442 | 4.11k | |
443 | 4.11k | const SanitizerArgs &Sanitize = getSanitizerArgs(); |
444 | 4.11k | if (Sanitize.needsAsanRt()) |
445 | 10 | AddLinkSanitizerLibArgs(Args, CmdArgs, "asan"); |
446 | 4.11k | if (Sanitize.needsUbsanRt()) |
447 | 5 | AddLinkSanitizerLibArgs(Args, CmdArgs, "ubsan"); |
448 | 4.11k | if (Sanitize.needsTsanRt()) |
449 | 5 | AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan"); |
450 | 4.11k | if (Sanitize.needsStatsRt()4.11k ) {1 |
451 | 1 | StringRef OS = isTargetMacOS() ? "osx"1 : "iossim"0 ; |
452 | 1 | AddLinkRuntimeLib(Args, CmdArgs, |
453 | 1 | (Twine("libclang_rt.stats_client_") + OS + ".a").str(), |
454 | 1 | /*AlwaysLink=*/true); |
455 | 1 | AddLinkSanitizerLibArgs(Args, CmdArgs, "stats"); |
456 | 1 | } |
457 | 4.11k | if (Sanitize.needsEsanRt()) |
458 | 0 | AddLinkSanitizerLibArgs(Args, CmdArgs, "esan"); |
459 | 4.11k | |
460 | 4.11k | // Otherwise link libSystem, then the dynamic runtime library, and finally any |
461 | 4.11k | // target specific static runtime library. |
462 | 4.11k | CmdArgs.push_back("-lSystem"); |
463 | 4.11k | |
464 | 4.11k | // Select the dynamic runtime library and the target specific static library. |
465 | 4.11k | if (isTargetWatchOSBased()4.11k ) {12 |
466 | 12 | // We currently always need a static runtime library for watchOS. |
467 | 12 | AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.watchos.a"); |
468 | 4.09k | } else if (4.09k isTargetTvOSBased()4.09k ) {8 |
469 | 8 | // We currently always need a static runtime library for tvOS. |
470 | 8 | AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.tvos.a"); |
471 | 4.09k | } else if (4.09k isTargetIOSBased()4.09k ) {3.77k |
472 | 3.77k | // If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1, |
473 | 3.77k | // it never went into the SDK. |
474 | 3.77k | // Linking against libgcc_s.1 isn't needed for iOS 5.0+ |
475 | 3.77k | if (isIPhoneOSVersionLT(5, 0) && 3.77k !isTargetIOSSimulator()12 && |
476 | 9 | getTriple().getArch() != llvm::Triple::aarch64) |
477 | 8 | CmdArgs.push_back("-lgcc_s.1"); |
478 | 3.77k | |
479 | 3.77k | // We currently always need a static runtime library for iOS. |
480 | 3.77k | AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ios.a"); |
481 | 320 | } else { |
482 | 320 | assert(isTargetMacOS() && "unexpected non MacOS platform"); |
483 | 320 | // The dynamic runtime library was merged with libSystem for 10.6 and |
484 | 320 | // beyond; only 10.4 and 10.5 need an additional runtime library. |
485 | 320 | if (isMacosxVersionLT(10, 5)) |
486 | 57 | CmdArgs.push_back("-lgcc_s.10.4"); |
487 | 263 | else if (263 isMacosxVersionLT(10, 6)263 ) |
488 | 10 | CmdArgs.push_back("-lgcc_s.10.5"); |
489 | 320 | |
490 | 320 | // Originally for OS X, we thought we would only need a static runtime |
491 | 320 | // library when targeting 10.4, to provide versions of the static functions |
492 | 320 | // which were omitted from 10.4.dylib. This led to the creation of the 10.4 |
493 | 320 | // builtins library. |
494 | 320 | // |
495 | 320 | // Unfortunately, that turned out to not be true, because Darwin system |
496 | 320 | // headers can still use eprintf on i386, and it is not exported from |
497 | 320 | // libSystem. Therefore, we still must provide a runtime library just for |
498 | 320 | // the tiny tiny handful of projects that *might* use that symbol. |
499 | 320 | // |
500 | 320 | // Then over time, we figured out it was useful to add more things to the |
501 | 320 | // runtime so we created libclang_rt.osx.a to provide new functions when |
502 | 320 | // deploying to old OS builds, and for a long time we had both eprintf and |
503 | 320 | // osx builtin libraries. Which just seems excessive. So with PR 28855, we |
504 | 320 | // are removing the eprintf library and expecting eprintf to be provided by |
505 | 320 | // the OS X builtins library. |
506 | 320 | if (isMacosxVersionLT(10, 5)) |
507 | 57 | AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.10.4.a"); |
508 | 320 | else |
509 | 263 | AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.osx.a"); |
510 | 320 | } |
511 | 4.11k | } |
512 | | |
513 | 19.1k | void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { |
514 | 19.1k | const OptTable &Opts = getDriver().getOpts(); |
515 | 19.1k | |
516 | 19.1k | // Support allowing the SDKROOT environment variable used by xcrun and other |
517 | 19.1k | // Xcode tools to define the default sysroot, by making it the default for |
518 | 19.1k | // isysroot. |
519 | 19.1k | if (const Arg *A19.1k = Args.getLastArg(options::OPT_isysroot)) {16.4k |
520 | 16.4k | // Warn if the path does not exist. |
521 | 16.4k | if (!getVFS().exists(A->getValue())) |
522 | 14 | getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue(); |
523 | 2.69k | } else { |
524 | 2.69k | if (char *env2.69k = ::getenv("SDKROOT")) {1.17k |
525 | 1.17k | // We only use this value as the default if it is an absolute path, |
526 | 1.17k | // exists, and it is not the root path. |
527 | 1.17k | if (llvm::sys::path::is_absolute(env) && 1.17k getVFS().exists(env)1.17k && |
528 | 1.17k | StringRef(env) != "/"1.17k ) {1.17k |
529 | 1.17k | Args.append(Args.MakeSeparateArg( |
530 | 1.17k | nullptr, Opts.getOption(options::OPT_isysroot), env)); |
531 | 1.17k | } |
532 | 1.17k | } |
533 | 2.69k | } |
534 | 19.1k | |
535 | 19.1k | Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ); |
536 | 19.1k | Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ); |
537 | 19.1k | Arg *TvOSVersion = Args.getLastArg(options::OPT_mtvos_version_min_EQ); |
538 | 19.1k | Arg *WatchOSVersion = Args.getLastArg(options::OPT_mwatchos_version_min_EQ); |
539 | 19.1k | |
540 | 19.1k | if (OSXVersion && 19.1k (iOSVersion || 48 TvOSVersion48 || WatchOSVersion48 )) {0 |
541 | 0 | getDriver().Diag(diag::err_drv_argument_not_allowed_with) |
542 | 0 | << OSXVersion->getAsString(Args) |
543 | 0 | << (iOSVersion ? iOSVersion : |
544 | 0 | TvOSVersion ? 0 TvOSVersion0 : WatchOSVersion0 )->getAsString(Args); |
545 | 0 | iOSVersion = TvOSVersion = WatchOSVersion = nullptr; |
546 | 19.1k | } else if (19.1k iOSVersion && 19.1k (TvOSVersion || 56 WatchOSVersion56 )) {0 |
547 | 0 | getDriver().Diag(diag::err_drv_argument_not_allowed_with) |
548 | 0 | << iOSVersion->getAsString(Args) |
549 | 0 | << (TvOSVersion ? TvOSVersion0 : WatchOSVersion0 )->getAsString(Args); |
550 | 0 | TvOSVersion = WatchOSVersion = nullptr; |
551 | 19.1k | } else if (19.1k TvOSVersion && 19.1k WatchOSVersion12 ) {0 |
552 | 0 | getDriver().Diag(diag::err_drv_argument_not_allowed_with) |
553 | 0 | << TvOSVersion->getAsString(Args) |
554 | 0 | << WatchOSVersion->getAsString(Args); |
555 | 0 | WatchOSVersion = nullptr; |
556 | 19.1k | } else if (19.1k !OSXVersion && 19.1k !iOSVersion19.1k && !TvOSVersion19.0k && !WatchOSVersion19.0k ) {19.0k |
557 | 19.0k | // If no deployment target was specified on the command line, check for |
558 | 19.0k | // environment defines. |
559 | 19.0k | std::string OSXTarget; |
560 | 19.0k | std::string iOSTarget; |
561 | 19.0k | std::string TvOSTarget; |
562 | 19.0k | std::string WatchOSTarget; |
563 | 19.0k | |
564 | 19.0k | if (char *env = ::getenv("MACOSX_DEPLOYMENT_TARGET")) |
565 | 6 | OSXTarget = env; |
566 | 19.0k | if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET")) |
567 | 5 | iOSTarget = env; |
568 | 19.0k | if (char *env = ::getenv("TVOS_DEPLOYMENT_TARGET")) |
569 | 5 | TvOSTarget = env; |
570 | 19.0k | if (char *env = ::getenv("WATCHOS_DEPLOYMENT_TARGET")) |
571 | 4 | WatchOSTarget = env; |
572 | 19.0k | |
573 | 19.0k | // If there is no command-line argument to specify the Target version and |
574 | 19.0k | // no environment variable defined, see if we can set the default based |
575 | 19.0k | // on -isysroot. |
576 | 19.0k | if (OSXTarget.empty() && 19.0k iOSTarget.empty()19.0k && WatchOSTarget.empty()19.0k && |
577 | 19.0k | TvOSTarget.empty()19.0k && Args.hasArg(options::OPT_isysroot)19.0k ) {17.6k |
578 | 17.6k | if (const Arg *A17.6k = Args.getLastArg(options::OPT_isysroot)) {17.6k |
579 | 17.6k | StringRef isysroot = A->getValue(); |
580 | 17.6k | StringRef SDK = getSDKName(isysroot); |
581 | 17.6k | if (SDK.size() > 017.6k ) {17.6k |
582 | 17.6k | // Slice the version number out. |
583 | 17.6k | // Version number is between the first and the last number. |
584 | 17.6k | size_t StartVer = SDK.find_first_of("0123456789"); |
585 | 17.6k | size_t EndVer = SDK.find_last_of("0123456789"); |
586 | 17.6k | if (StartVer != StringRef::npos && 17.6k EndVer > StartVer17.6k ) {17.6k |
587 | 17.6k | StringRef Version = SDK.slice(StartVer, EndVer + 1); |
588 | 17.6k | if (SDK.startswith("iPhoneOS") || |
589 | 1.16k | SDK.startswith("iPhoneSimulator")) |
590 | 16.4k | iOSTarget = Version; |
591 | 1.16k | else if (1.16k SDK.startswith("MacOSX")1.16k ) |
592 | 1.16k | OSXTarget = Version; |
593 | 0 | else if (0 SDK.startswith("WatchOS") ||0 |
594 | 0 | SDK.startswith("WatchSimulator")) |
595 | 0 | WatchOSTarget = Version; |
596 | 0 | else if (0 SDK.startswith("AppleTVOS") ||0 |
597 | 0 | SDK.startswith("AppleTVSimulator")) |
598 | 0 | TvOSTarget = Version; |
599 | 17.6k | } |
600 | 17.6k | } |
601 | 17.6k | } |
602 | 17.6k | } |
603 | 19.0k | |
604 | 19.0k | // If no OSX or iOS target has been specified, try to guess platform |
605 | 19.0k | // from arch name and compute the version from the triple. |
606 | 19.0k | if (OSXTarget.empty() && 19.0k iOSTarget.empty()17.8k && TvOSTarget.empty()1.42k && |
607 | 1.41k | WatchOSTarget.empty()1.41k ) {1.41k |
608 | 1.41k | StringRef MachOArchName = getMachOArchName(Args); |
609 | 1.41k | unsigned Major, Minor, Micro; |
610 | 1.41k | if (MachOArchName == "armv7" || 1.41k MachOArchName == "armv7s"1.39k || |
611 | 1.38k | MachOArchName == "arm64"1.38k ) {46 |
612 | 46 | getTriple().getiOSVersion(Major, Minor, Micro); |
613 | 46 | llvm::raw_string_ostream(iOSTarget) << Major << '.' << Minor << '.' |
614 | 46 | << Micro; |
615 | 1.37k | } else if (1.37k MachOArchName == "armv7k"1.37k ) {7 |
616 | 7 | getTriple().getWatchOSVersion(Major, Minor, Micro); |
617 | 7 | llvm::raw_string_ostream(WatchOSTarget) << Major << '.' << Minor << '.' |
618 | 7 | << Micro; |
619 | 1.36k | } else if (1.36k MachOArchName != "armv6m" && 1.36k MachOArchName != "armv7m"1.36k && |
620 | 1.36k | MachOArchName != "armv7em"1.36k ) {1.36k |
621 | 1.36k | if (!getTriple().getMacOSXVersion(Major, Minor, Micro)1.36k ) {0 |
622 | 0 | getDriver().Diag(diag::err_drv_invalid_darwin_version) |
623 | 0 | << getTriple().getOSName(); |
624 | 0 | } |
625 | 1.36k | llvm::raw_string_ostream(OSXTarget) << Major << '.' << Minor << '.' |
626 | 1.36k | << Micro; |
627 | 1.36k | } |
628 | 1.41k | } |
629 | 19.0k | |
630 | 19.0k | // Do not allow conflicts with the watchOS target. |
631 | 19.0k | if (!WatchOSTarget.empty() && 19.0k (!iOSTarget.empty() || 11 !TvOSTarget.empty()11 )) {0 |
632 | 0 | getDriver().Diag(diag::err_drv_conflicting_deployment_targets) |
633 | 0 | << "WATCHOS_DEPLOYMENT_TARGET" |
634 | 0 | << (!iOSTarget.empty() ? "IPHONEOS_DEPLOYMENT_TARGET" : |
635 | 0 | "TVOS_DEPLOYMENT_TARGET"); |
636 | 0 | } |
637 | 19.0k | |
638 | 19.0k | // Do not allow conflicts with the tvOS target. |
639 | 19.0k | if (!TvOSTarget.empty() && 19.0k !iOSTarget.empty()5 ) {0 |
640 | 0 | getDriver().Diag(diag::err_drv_conflicting_deployment_targets) |
641 | 0 | << "TVOS_DEPLOYMENT_TARGET" |
642 | 0 | << "IPHONEOS_DEPLOYMENT_TARGET"; |
643 | 0 | } |
644 | 19.0k | |
645 | 19.0k | // Allow conflicts among OSX and iOS for historical reasons, but choose the |
646 | 19.0k | // default platform. |
647 | 19.0k | if (!OSXTarget.empty() && 19.0k (!iOSTarget.empty() ||2.52k |
648 | 2.52k | !WatchOSTarget.empty() || |
649 | 2.52k | !TvOSTarget.empty()2.52k )) {4 |
650 | 4 | if (getTriple().getArch() == llvm::Triple::arm || |
651 | 1 | getTriple().getArch() == llvm::Triple::aarch64 || |
652 | 1 | getTriple().getArch() == llvm::Triple::thumb) |
653 | 3 | OSXTarget = ""; |
654 | 4 | else |
655 | 1 | iOSTarget = WatchOSTarget = TvOSTarget = ""; |
656 | 4 | } |
657 | 19.0k | |
658 | 19.0k | if (!OSXTarget.empty()19.0k ) {2.52k |
659 | 2.52k | const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ); |
660 | 2.52k | OSXVersion = Args.MakeJoinedArg(nullptr, O, OSXTarget); |
661 | 2.52k | Args.append(OSXVersion); |
662 | 16.5k | } else if (16.5k !iOSTarget.empty()16.5k ) {16.4k |
663 | 16.4k | const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ); |
664 | 16.4k | iOSVersion = Args.MakeJoinedArg(nullptr, O, iOSTarget); |
665 | 16.4k | Args.append(iOSVersion); |
666 | 16 | } else if (16 !TvOSTarget.empty()16 ) {5 |
667 | 5 | const Option O = Opts.getOption(options::OPT_mtvos_version_min_EQ); |
668 | 5 | TvOSVersion = Args.MakeJoinedArg(nullptr, O, TvOSTarget); |
669 | 5 | Args.append(TvOSVersion); |
670 | 11 | } else if (11 !WatchOSTarget.empty()11 ) {11 |
671 | 11 | const Option O = Opts.getOption(options::OPT_mwatchos_version_min_EQ); |
672 | 11 | WatchOSVersion = Args.MakeJoinedArg(nullptr, O, WatchOSTarget); |
673 | 11 | Args.append(WatchOSVersion); |
674 | 11 | } |
675 | 19.0k | } |
676 | 19.1k | |
677 | 19.1k | DarwinPlatformKind Platform; |
678 | 19.1k | if (OSXVersion) |
679 | 2.57k | Platform = MacOS; |
680 | 16.5k | else if (16.5k iOSVersion16.5k ) |
681 | 16.5k | Platform = IPhoneOS; |
682 | 45 | else if (45 TvOSVersion45 ) |
683 | 17 | Platform = TvOS; |
684 | 28 | else if (28 WatchOSVersion28 ) |
685 | 28 | Platform = WatchOS; |
686 | 28 | else |
687 | 0 | llvm_unreachable("Unable to infer Darwin variant"); |
688 | 19.1k | |
689 | 19.1k | // Set the tool chain target information. |
690 | 19.1k | unsigned Major, Minor, Micro; |
691 | 19.1k | bool HadExtra; |
692 | 19.1k | if (Platform == MacOS19.1k ) {2.57k |
693 | 2.57k | assert((!iOSVersion && !TvOSVersion && !WatchOSVersion) && |
694 | 2.57k | "Unknown target platform!"); |
695 | 2.57k | if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor, Micro, |
696 | 2.57k | HadExtra) || |
697 | 2.57k | HadExtra2.57k || Major != 102.57k || Minor >= 1002.57k || Micro >= 1002.57k ) |
698 | 1 | getDriver().Diag(diag::err_drv_invalid_version_number) |
699 | 1 | << OSXVersion->getAsString(Args); |
700 | 16.5k | } else if (16.5k Platform == IPhoneOS16.5k ) {16.5k |
701 | 16.5k | assert(iOSVersion && "Unknown target platform!"); |
702 | 16.5k | if (!Driver::GetReleaseVersion(iOSVersion->getValue(), Major, Minor, Micro, |
703 | 16.5k | HadExtra) || |
704 | 16.5k | HadExtra16.5k || Major >= 10016.5k || Minor >= 10016.5k || Micro >= 10016.5k ) |
705 | 0 | getDriver().Diag(diag::err_drv_invalid_version_number) |
706 | 0 | << iOSVersion->getAsString(Args); |
707 | 45 | } else if (45 Platform == TvOS45 ) {17 |
708 | 17 | if (!Driver::GetReleaseVersion(TvOSVersion->getValue(), Major, Minor, |
709 | 17 | Micro, HadExtra) || HadExtra || |
710 | 17 | Major >= 10017 || Minor >= 10017 || Micro >= 10017 ) |
711 | 0 | getDriver().Diag(diag::err_drv_invalid_version_number) |
712 | 0 | << TvOSVersion->getAsString(Args); |
713 | 28 | } else if (28 Platform == WatchOS28 ) {28 |
714 | 28 | if (!Driver::GetReleaseVersion(WatchOSVersion->getValue(), Major, Minor, |
715 | 28 | Micro, HadExtra) || HadExtra || |
716 | 28 | Major >= 1028 || Minor >= 10028 || Micro >= 10028 ) |
717 | 0 | getDriver().Diag(diag::err_drv_invalid_version_number) |
718 | 0 | << WatchOSVersion->getAsString(Args); |
719 | 28 | } else |
720 | 0 | llvm_unreachable("unknown kind of Darwin platform"); |
721 | 19.1k | |
722 | 19.1k | // Recognize iOS targets with an x86 architecture as the iOS simulator. |
723 | 19.1k | if (iOSVersion && 19.1k (getTriple().getArch() == llvm::Triple::x86 ||16.5k |
724 | 16.5k | getTriple().getArch() == llvm::Triple::x86_64)) |
725 | 18 | Platform = IPhoneOSSimulator; |
726 | 19.1k | if (TvOSVersion && 19.1k (getTriple().getArch() == llvm::Triple::x86 ||17 |
727 | 15 | getTriple().getArch() == llvm::Triple::x86_64)) |
728 | 7 | Platform = TvOSSimulator; |
729 | 19.1k | if (WatchOSVersion && 19.1k (getTriple().getArch() == llvm::Triple::x86 ||28 |
730 | 24 | getTriple().getArch() == llvm::Triple::x86_64)) |
731 | 6 | Platform = WatchOSSimulator; |
732 | 19.1k | |
733 | 19.1k | setTarget(Platform, Major, Minor, Micro); |
734 | 19.1k | |
735 | 19.1k | if (const Arg *A19.1k = Args.getLastArg(options::OPT_isysroot)) {17.6k |
736 | 17.6k | StringRef SDK = getSDKName(A->getValue()); |
737 | 17.6k | if (SDK.size() > 017.6k ) {17.6k |
738 | 17.6k | size_t StartVer = SDK.find_first_of("0123456789"); |
739 | 17.6k | StringRef SDKName = SDK.slice(0, StartVer); |
740 | 17.6k | if (!SDKName.startswith(getPlatformFamily())) |
741 | 11 | getDriver().Diag(diag::warn_incompatible_sysroot) |
742 | 11 | << SDKName << getPlatformFamily(); |
743 | 17.6k | } |
744 | 17.6k | } |
745 | 19.1k | } |
746 | | |
747 | | void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args, |
748 | 3.18k | ArgStringList &CmdArgs) const { |
749 | 3.18k | CXXStdlibType Type = GetCXXStdlibType(Args); |
750 | 3.18k | |
751 | 3.18k | switch (Type) { |
752 | 3.18k | case ToolChain::CST_Libcxx: |
753 | 3.18k | CmdArgs.push_back("-lc++"); |
754 | 3.18k | break; |
755 | 3.18k | |
756 | 1 | case ToolChain::CST_Libstdcxx: |
757 | 1 | // Unfortunately, -lstdc++ doesn't always exist in the standard search path; |
758 | 1 | // it was previously found in the gcc lib dir. However, for all the Darwin |
759 | 1 | // platforms we care about it was -lstdc++.6, so we search for that |
760 | 1 | // explicitly if we can't see an obvious -lstdc++ candidate. |
761 | 1 | |
762 | 1 | // Check in the sysroot first. |
763 | 1 | if (const Arg *A1 = Args.getLastArg(options::OPT_isysroot)) {0 |
764 | 0 | SmallString<128> P(A->getValue()); |
765 | 0 | llvm::sys::path::append(P, "usr", "lib", "libstdc++.dylib"); |
766 | 0 |
|
767 | 0 | if (!getVFS().exists(P)0 ) {0 |
768 | 0 | llvm::sys::path::remove_filename(P); |
769 | 0 | llvm::sys::path::append(P, "libstdc++.6.dylib"); |
770 | 0 | if (getVFS().exists(P)0 ) {0 |
771 | 0 | CmdArgs.push_back(Args.MakeArgString(P)); |
772 | 0 | return; |
773 | 0 | } |
774 | 0 | } |
775 | 0 | } |
776 | 1 | |
777 | 1 | // Otherwise, look in the root. |
778 | 1 | // FIXME: This should be removed someday when we don't have to care about |
779 | 1 | // 10.6 and earlier, where /usr/lib/libstdc++.dylib does not exist. |
780 | 1 | if (1 !getVFS().exists("/usr/lib/libstdc++.dylib") &&1 |
781 | 0 | getVFS().exists("/usr/lib/libstdc++.6.dylib")0 ) {0 |
782 | 0 | CmdArgs.push_back("/usr/lib/libstdc++.6.dylib"); |
783 | 0 | return; |
784 | 0 | } |
785 | 1 | |
786 | 1 | // Otherwise, let the linker search. |
787 | 1 | CmdArgs.push_back("-lstdc++"); |
788 | 1 | break; |
789 | 3.18k | } |
790 | 3.18k | } |
791 | | |
792 | | void DarwinClang::AddCCKextLibArgs(const ArgList &Args, |
793 | 2 | ArgStringList &CmdArgs) const { |
794 | 2 | // For Darwin platforms, use the compiler-rt-based support library |
795 | 2 | // instead of the gcc-provided one (which is also incidentally |
796 | 2 | // only present in the gcc lib dir, which makes it hard to find). |
797 | 2 | |
798 | 2 | SmallString<128> P(getDriver().ResourceDir); |
799 | 2 | llvm::sys::path::append(P, "lib", "darwin"); |
800 | 2 | |
801 | 2 | // Use the newer cc_kext for iOS ARM after 6.0. |
802 | 2 | if (isTargetWatchOS()2 ) {1 |
803 | 1 | llvm::sys::path::append(P, "libclang_rt.cc_kext_watchos.a"); |
804 | 1 | } else if (1 isTargetTvOS()1 ) {1 |
805 | 1 | llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a"); |
806 | 0 | } else if (0 isTargetIPhoneOS()0 ) {0 |
807 | 0 | llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a"); |
808 | 0 | } else { |
809 | 0 | llvm::sys::path::append(P, "libclang_rt.cc_kext.a"); |
810 | 0 | } |
811 | 2 | |
812 | 2 | // For now, allow missing resource libraries to support developers who may |
813 | 2 | // not have compiler-rt checked out or integrated into their build. |
814 | 2 | if (getVFS().exists(P)) |
815 | 0 | CmdArgs.push_back(Args.MakeArgString(P)); |
816 | 2 | } |
817 | | |
818 | | DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args, |
819 | | StringRef BoundArch, |
820 | 19.2k | Action::OffloadKind) const { |
821 | 19.2k | DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); |
822 | 19.2k | const OptTable &Opts = getDriver().getOpts(); |
823 | 19.2k | |
824 | 19.2k | // FIXME: We really want to get out of the tool chain level argument |
825 | 19.2k | // translation business, as it makes the driver functionality much |
826 | 19.2k | // more opaque. For now, we follow gcc closely solely for the |
827 | 19.2k | // purpose of easily achieving feature parity & testability. Once we |
828 | 19.2k | // have something that works, we should reevaluate each translation |
829 | 19.2k | // and try to push it down into tool specific logic. |
830 | 19.2k | |
831 | 345k | for (Arg *A : Args) { |
832 | 345k | if (A->getOption().matches(options::OPT_Xarch__)345k ) {13 |
833 | 13 | // Skip this argument unless the architecture matches either the toolchain |
834 | 13 | // triple arch, or the arch being bound. |
835 | 13 | llvm::Triple::ArchType XarchArch = |
836 | 13 | tools::darwin::getArchTypeForMachOArchName(A->getValue(0)); |
837 | 13 | if (!(XarchArch == getArch() || |
838 | 4 | (!BoundArch.empty() && |
839 | 3 | XarchArch == |
840 | 3 | tools::darwin::getArchTypeForMachOArchName(BoundArch)))) |
841 | 4 | continue; |
842 | 13 | |
843 | 9 | Arg *OriginalArg = A; |
844 | 9 | unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1)); |
845 | 9 | unsigned Prev = Index; |
846 | 9 | std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index)); |
847 | 9 | |
848 | 9 | // If the argument parsing failed or more than one argument was |
849 | 9 | // consumed, the -Xarch_ argument's parameter tried to consume |
850 | 9 | // extra arguments. Emit an error and ignore. |
851 | 9 | // |
852 | 9 | // We also want to disallow any options which would alter the |
853 | 9 | // driver behavior; that isn't going to work in our model. We |
854 | 9 | // use isDriverOption() as an approximation, although things |
855 | 9 | // like -O4 are going to slip through. |
856 | 9 | if (!XarchArg || 9 Index > Prev + 17 ) {2 |
857 | 2 | getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args) |
858 | 2 | << A->getAsString(Args); |
859 | 2 | continue; |
860 | 7 | } else if (7 XarchArg->getOption().hasFlag(options::DriverOption)7 ) {1 |
861 | 1 | getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver) |
862 | 1 | << A->getAsString(Args); |
863 | 1 | continue; |
864 | 1 | } |
865 | 9 | |
866 | 6 | XarchArg->setBaseArg(A); |
867 | 6 | |
868 | 6 | A = XarchArg.release(); |
869 | 6 | DAL->AddSynthesizedArg(A); |
870 | 6 | |
871 | 6 | // Linker input arguments require custom handling. The problem is that we |
872 | 6 | // have already constructed the phase actions, so we can not treat them as |
873 | 6 | // "input arguments". |
874 | 6 | if (A->getOption().hasFlag(options::LinkerInput)6 ) {2 |
875 | 2 | // Convert the argument into individual Zlinker_input_args. |
876 | 2 | for (const char *Value : A->getValues()) { |
877 | 2 | DAL->AddSeparateArg( |
878 | 2 | OriginalArg, Opts.getOption(options::OPT_Zlinker_input), Value); |
879 | 2 | } |
880 | 2 | continue; |
881 | 2 | } |
882 | 6 | } |
883 | 345k | |
884 | 345k | // Sob. These is strictly gcc compatible for the time being. Apple |
885 | 345k | // gcc translates options twice, which means that self-expanding |
886 | 345k | // options add duplicates. |
887 | 345k | switch ((options::ID)A->getOption().getID()) { |
888 | 345k | default: |
889 | 345k | DAL->append(A); |
890 | 345k | break; |
891 | 345k | |
892 | 21 | case options::OPT_mkernel: |
893 | 21 | case options::OPT_fapple_kext: |
894 | 21 | DAL->append(A); |
895 | 21 | DAL->AddFlagArg(A, Opts.getOption(options::OPT_static)); |
896 | 21 | break; |
897 | 21 | |
898 | 0 | case options::OPT_dependency_file: |
899 | 0 | DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue()); |
900 | 0 | break; |
901 | 21 | |
902 | 0 | case options::OPT_gfull: |
903 | 0 | DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); |
904 | 0 | DAL->AddFlagArg( |
905 | 0 | A, Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)); |
906 | 0 | break; |
907 | 21 | |
908 | 0 | case options::OPT_gused: |
909 | 0 | DAL->AddFlagArg(A, Opts.getOption(options::OPT_g_Flag)); |
910 | 0 | DAL->AddFlagArg( |
911 | 0 | A, Opts.getOption(options::OPT_feliminate_unused_debug_symbols)); |
912 | 0 | break; |
913 | 21 | |
914 | 3 | case options::OPT_shared: |
915 | 3 | DAL->AddFlagArg(A, Opts.getOption(options::OPT_dynamiclib)); |
916 | 3 | break; |
917 | 21 | |
918 | 0 | case options::OPT_fconstant_cfstrings: |
919 | 0 | DAL->AddFlagArg(A, Opts.getOption(options::OPT_mconstant_cfstrings)); |
920 | 0 | break; |
921 | 21 | |
922 | 0 | case options::OPT_fno_constant_cfstrings: |
923 | 0 | DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_constant_cfstrings)); |
924 | 0 | break; |
925 | 21 | |
926 | 0 | case options::OPT_Wnonportable_cfstrings: |
927 | 0 | DAL->AddFlagArg(A, |
928 | 0 | Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)); |
929 | 0 | break; |
930 | 21 | |
931 | 0 | case options::OPT_Wno_nonportable_cfstrings: |
932 | 0 | DAL->AddFlagArg( |
933 | 0 | A, Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)); |
934 | 0 | break; |
935 | 21 | |
936 | 5 | case options::OPT_fpascal_strings: |
937 | 5 | DAL->AddFlagArg(A, Opts.getOption(options::OPT_mpascal_strings)); |
938 | 5 | break; |
939 | 21 | |
940 | 4 | case options::OPT_fno_pascal_strings: |
941 | 4 | DAL->AddFlagArg(A, Opts.getOption(options::OPT_mno_pascal_strings)); |
942 | 4 | break; |
943 | 345k | } |
944 | 345k | } |
945 | 19.2k | |
946 | 19.2k | if (19.2k getTriple().getArch() == llvm::Triple::x86 ||19.2k |
947 | 19.0k | getTriple().getArch() == llvm::Triple::x86_64) |
948 | 2.60k | if (2.60k !Args.hasArgNoClaim(options::OPT_mtune_EQ)2.60k ) |
949 | 2.60k | DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_mtune_EQ), |
950 | 2.60k | "core2"); |
951 | 19.2k | |
952 | 19.2k | // Add the arch options based on the particular spelling of -arch, to match |
953 | 19.2k | // how the driver driver works. |
954 | 19.2k | if (!BoundArch.empty()19.2k ) {19.1k |
955 | 19.1k | StringRef Name = BoundArch; |
956 | 19.1k | const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ); |
957 | 19.1k | const Option MArch = Opts.getOption(options::OPT_march_EQ); |
958 | 19.1k | |
959 | 19.1k | // This code must be kept in sync with LLVM's getArchTypeForDarwinArch, |
960 | 19.1k | // which defines the list of which architectures we accept. |
961 | 19.1k | if (Name == "ppc") |
962 | 5 | ; |
963 | 19.1k | else if (19.1k Name == "ppc601"19.1k ) |
964 | 0 | DAL->AddJoinedArg(nullptr, MCpu, "601"); |
965 | 19.1k | else if (19.1k Name == "ppc603"19.1k ) |
966 | 0 | DAL->AddJoinedArg(nullptr, MCpu, "603"); |
967 | 19.1k | else if (19.1k Name == "ppc604"19.1k ) |
968 | 0 | DAL->AddJoinedArg(nullptr, MCpu, "604"); |
969 | 19.1k | else if (19.1k Name == "ppc604e"19.1k ) |
970 | 0 | DAL->AddJoinedArg(nullptr, MCpu, "604e"); |
971 | 19.1k | else if (19.1k Name == "ppc750"19.1k ) |
972 | 0 | DAL->AddJoinedArg(nullptr, MCpu, "750"); |
973 | 19.1k | else if (19.1k Name == "ppc7400"19.1k ) |
974 | 0 | DAL->AddJoinedArg(nullptr, MCpu, "7400"); |
975 | 19.1k | else if (19.1k Name == "ppc7450"19.1k ) |
976 | 0 | DAL->AddJoinedArg(nullptr, MCpu, "7450"); |
977 | 19.1k | else if (19.1k Name == "ppc970"19.1k ) |
978 | 0 | DAL->AddJoinedArg(nullptr, MCpu, "970"); |
979 | 19.1k | |
980 | 19.1k | else if (19.1k Name == "ppc64" || 19.1k Name == "ppc64le"19.1k ) |
981 | 2 | DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64)); |
982 | 19.1k | |
983 | 19.1k | else if (19.1k Name == "i386"19.1k ) |
984 | 108 | ; |
985 | 19.0k | else if (19.0k Name == "i486"19.0k ) |
986 | 0 | DAL->AddJoinedArg(nullptr, MArch, "i486"); |
987 | 19.0k | else if (19.0k Name == "i586"19.0k ) |
988 | 0 | DAL->AddJoinedArg(nullptr, MArch, "i586"); |
989 | 19.0k | else if (19.0k Name == "i686"19.0k ) |
990 | 10 | DAL->AddJoinedArg(nullptr, MArch, "i686"); |
991 | 19.0k | else if (19.0k Name == "pentium"19.0k ) |
992 | 0 | DAL->AddJoinedArg(nullptr, MArch, "pentium"); |
993 | 19.0k | else if (19.0k Name == "pentium2"19.0k ) |
994 | 0 | DAL->AddJoinedArg(nullptr, MArch, "pentium2"); |
995 | 19.0k | else if (19.0k Name == "pentpro"19.0k ) |
996 | 0 | DAL->AddJoinedArg(nullptr, MArch, "pentiumpro"); |
997 | 19.0k | else if (19.0k Name == "pentIIm3"19.0k ) |
998 | 0 | DAL->AddJoinedArg(nullptr, MArch, "pentium2"); |
999 | 19.0k | |
1000 | 19.0k | else if (19.0k Name == "x86_64"19.0k ) |
1001 | 2.43k | DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64)); |
1002 | 16.6k | else if (16.6k Name == "x86_64h"16.6k ) {4 |
1003 | 4 | DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64)); |
1004 | 4 | DAL->AddJoinedArg(nullptr, MArch, "x86_64h"); |
1005 | 4 | } |
1006 | 16.6k | |
1007 | 16.6k | else if (16.6k Name == "arm"16.6k ) |
1008 | 4 | DAL->AddJoinedArg(nullptr, MArch, "armv4t"); |
1009 | 16.6k | else if (16.6k Name == "armv4t"16.6k ) |
1010 | 0 | DAL->AddJoinedArg(nullptr, MArch, "armv4t"); |
1011 | 16.6k | else if (16.6k Name == "armv5"16.6k ) |
1012 | 1 | DAL->AddJoinedArg(nullptr, MArch, "armv5tej"); |
1013 | 16.6k | else if (16.6k Name == "xscale"16.6k ) |
1014 | 0 | DAL->AddJoinedArg(nullptr, MArch, "xscale"); |
1015 | 16.6k | else if (16.6k Name == "armv6"16.6k ) |
1016 | 12 | DAL->AddJoinedArg(nullptr, MArch, "armv6k"); |
1017 | 16.6k | else if (16.6k Name == "armv6m"16.6k ) |
1018 | 6 | DAL->AddJoinedArg(nullptr, MArch, "armv6m"); |
1019 | 16.6k | else if (16.6k Name == "armv7"16.6k ) |
1020 | 61 | DAL->AddJoinedArg(nullptr, MArch, "armv7a"); |
1021 | 16.5k | else if (16.5k Name == "armv7em"16.5k ) |
1022 | 8 | DAL->AddJoinedArg(nullptr, MArch, "armv7em"); |
1023 | 16.5k | else if (16.5k Name == "armv7k"16.5k ) |
1024 | 21 | DAL->AddJoinedArg(nullptr, MArch, "armv7k"); |
1025 | 16.5k | else if (16.5k Name == "armv7m"16.5k ) |
1026 | 9 | DAL->AddJoinedArg(nullptr, MArch, "armv7m"); |
1027 | 16.5k | else if (16.5k Name == "armv7s"16.5k ) |
1028 | 12 | DAL->AddJoinedArg(nullptr, MArch, "armv7s"); |
1029 | 19.1k | } |
1030 | 19.2k | |
1031 | 19.2k | return DAL; |
1032 | 19.2k | } |
1033 | | |
1034 | | void MachO::AddLinkRuntimeLibArgs(const ArgList &Args, |
1035 | 10 | ArgStringList &CmdArgs) const { |
1036 | 10 | // Embedded targets are simple at the moment, not supporting sanitizers and |
1037 | 10 | // with different libraries for each member of the product { static, PIC } x |
1038 | 10 | // { hard-float, soft-float } |
1039 | 10 | llvm::SmallString<32> CompilerRT = StringRef("libclang_rt."); |
1040 | 10 | CompilerRT += |
1041 | 10 | (tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard) |
1042 | 3 | ? "hard" |
1043 | 7 | : "soft"; |
1044 | 6 | CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic.a"4 : "_static.a"6 ; |
1045 | 10 | |
1046 | 10 | AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, false, true); |
1047 | 10 | } |
1048 | | |
1049 | | DerivedArgList * |
1050 | | Darwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch, |
1051 | 19.2k | Action::OffloadKind DeviceOffloadKind) const { |
1052 | 19.2k | // First get the generic Apple args, before moving onto Darwin-specific ones. |
1053 | 19.2k | DerivedArgList *DAL = |
1054 | 19.2k | MachO::TranslateArgs(Args, BoundArch, DeviceOffloadKind); |
1055 | 19.2k | const OptTable &Opts = getDriver().getOpts(); |
1056 | 19.2k | |
1057 | 19.2k | // If no architecture is bound, none of the translations here are relevant. |
1058 | 19.2k | if (BoundArch.empty()) |
1059 | 32 | return DAL; |
1060 | 19.2k | |
1061 | 19.2k | // Add an explicit version min argument for the deployment target. We do this |
1062 | 19.2k | // after argument translation because -Xarch_ arguments may add a version min |
1063 | 19.2k | // argument. |
1064 | 19.1k | AddDeploymentTarget(*DAL); |
1065 | 19.1k | |
1066 | 19.1k | // For iOS 6, undo the translation to add -static for -mkernel/-fapple-kext. |
1067 | 19.1k | // FIXME: It would be far better to avoid inserting those -static arguments, |
1068 | 19.1k | // but we can't check the deployment target in the translation code until |
1069 | 19.1k | // it is set here. |
1070 | 19.1k | if (isTargetWatchOSBased() || |
1071 | 19.1k | (isTargetIOSBased() && 19.1k !isIPhoneOSVersionLT(6, 0)16.5k )) {16.5k |
1072 | 363k | for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie363k ; ) {347k |
1073 | 347k | Arg *A = *it; |
1074 | 347k | ++it; |
1075 | 347k | if (A->getOption().getID() != options::OPT_mkernel && |
1076 | 347k | A->getOption().getID() != options::OPT_fapple_kext) |
1077 | 347k | continue; |
1078 | 7 | assert(it != ie && "unexpected argument translation"); |
1079 | 7 | A = *it; |
1080 | 7 | assert(A->getOption().getID() == options::OPT_static && |
1081 | 7 | "missing expected -static argument"); |
1082 | 7 | it = DAL->getArgs().erase(it); |
1083 | 7 | } |
1084 | 16.5k | } |
1085 | 19.1k | |
1086 | 19.1k | if (!Args.getLastArg(options::OPT_stdlib_EQ) && |
1087 | 19.1k | GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) |
1088 | 18.7k | DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_stdlib_EQ), |
1089 | 18.7k | "libc++"); |
1090 | 19.1k | |
1091 | 19.1k | // Validate the C++ standard library choice. |
1092 | 19.1k | CXXStdlibType Type = GetCXXStdlibType(*DAL); |
1093 | 19.1k | if (Type == ToolChain::CST_Libcxx19.1k ) {18.7k |
1094 | 18.7k | // Check whether the target provides libc++. |
1095 | 18.7k | StringRef where; |
1096 | 18.7k | |
1097 | 18.7k | // Complain about targeting iOS < 5.0 in any way. |
1098 | 18.7k | if (isTargetIOSBased() && 18.7k isIPhoneOSVersionLT(5, 0)16.4k ) |
1099 | 0 | where = "iOS 5.0"; |
1100 | 18.7k | |
1101 | 18.7k | if (where != StringRef()18.7k ) {0 |
1102 | 0 | getDriver().Diag(clang::diag::err_drv_invalid_libcxx_deployment) << where; |
1103 | 0 | } |
1104 | 18.7k | } |
1105 | 19.1k | |
1106 | 19.1k | auto Arch = tools::darwin::getArchTypeForMachOArchName(BoundArch); |
1107 | 19.1k | if ((Arch == llvm::Triple::arm || 19.1k Arch == llvm::Triple::thumb19.0k )) {108 |
1108 | 108 | if (Args.hasFlag(options::OPT_fomit_frame_pointer, |
1109 | 108 | options::OPT_fno_omit_frame_pointer, false)) |
1110 | 2 | getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target) |
1111 | 2 | << "-fomit-frame-pointer" << BoundArch; |
1112 | 108 | } |
1113 | 19.1k | |
1114 | 19.1k | return DAL; |
1115 | 19.2k | } |
1116 | | |
1117 | 15.4k | bool MachO::IsUnwindTablesDefault() const { |
1118 | 15.4k | return getArch() == llvm::Triple::x86_64; |
1119 | 15.4k | } |
1120 | | |
1121 | 15.4k | bool MachO::UseDwarfDebugFlags() const { |
1122 | 15.4k | if (const char *S = ::getenv("RC_DEBUG_OPTIONS")) |
1123 | 11 | return S[0] != '\0'; |
1124 | 15.4k | return false; |
1125 | 15.4k | } |
1126 | | |
1127 | 15.3k | bool Darwin::UseSjLjExceptions(const ArgList &Args) const { |
1128 | 15.3k | // Darwin uses SjLj exceptions on ARM. |
1129 | 15.3k | if (getTriple().getArch() != llvm::Triple::arm && |
1130 | 15.3k | getTriple().getArch() != llvm::Triple::thumb) |
1131 | 15.3k | return false; |
1132 | 15.3k | |
1133 | 15.3k | // Only watchOS uses the new DWARF/Compact unwinding method. |
1134 | 88 | llvm::Triple Triple(ComputeLLVMTriple(Args)); |
1135 | 88 | return !Triple.isWatchABI(); |
1136 | 15.3k | } |
1137 | | |
1138 | 7 | bool Darwin::SupportsEmbeddedBitcode() const { |
1139 | 7 | assert(TargetInitialized && "Target not initialized!"); |
1140 | 7 | if (isTargetIPhoneOS() && 7 isIPhoneOSVersionLT(6, 0)7 ) |
1141 | 1 | return false; |
1142 | 6 | return true; |
1143 | 7 | } |
1144 | | |
1145 | 30.8k | bool MachO::isPICDefault() const { return true; } |
1146 | | |
1147 | 15.4k | bool MachO::isPIEDefault() const { return false; } |
1148 | | |
1149 | 15.4k | bool MachO::isPICDefaultForced() const { |
1150 | 15.4k | return (getArch() == llvm::Triple::x86_64 || |
1151 | 12.9k | getArch() == llvm::Triple::aarch64); |
1152 | 15.4k | } |
1153 | | |
1154 | 30.8k | bool MachO::SupportsProfiling() const { |
1155 | 30.8k | // Profiling instrumentation is only supported on x86. |
1156 | 30.6k | return getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64; |
1157 | 30.8k | } |
1158 | | |
1159 | | void Darwin::addMinVersionArgs(const ArgList &Args, |
1160 | 4.12k | ArgStringList &CmdArgs) const { |
1161 | 4.12k | VersionTuple TargetVersion = getTargetVersion(); |
1162 | 4.12k | |
1163 | 4.12k | if (isTargetWatchOS()) |
1164 | 10 | CmdArgs.push_back("-watchos_version_min"); |
1165 | 4.11k | else if (4.11k isTargetWatchOSSimulator()4.11k ) |
1166 | 2 | CmdArgs.push_back("-watchos_simulator_version_min"); |
1167 | 4.10k | else if (4.10k isTargetTvOS()4.10k ) |
1168 | 6 | CmdArgs.push_back("-tvos_version_min"); |
1169 | 4.10k | else if (4.10k isTargetTvOSSimulator()4.10k ) |
1170 | 2 | CmdArgs.push_back("-tvos_simulator_version_min"); |
1171 | 4.10k | else if (4.10k isTargetIOSSimulator()4.10k ) |
1172 | 7 | CmdArgs.push_back("-ios_simulator_version_min"); |
1173 | 4.09k | else if (4.09k isTargetIOSBased()4.09k ) |
1174 | 3.76k | CmdArgs.push_back("-iphoneos_version_min"); |
1175 | 327 | else { |
1176 | 327 | assert(isTargetMacOS() && "unexpected target"); |
1177 | 327 | CmdArgs.push_back("-macosx_version_min"); |
1178 | 327 | } |
1179 | 4.12k | |
1180 | 4.12k | CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); |
1181 | 4.12k | } |
1182 | | |
1183 | | void Darwin::addStartObjectFileArgs(const ArgList &Args, |
1184 | 4.11k | ArgStringList &CmdArgs) const { |
1185 | 4.11k | // Derived from startfile spec. |
1186 | 4.11k | if (Args.hasArg(options::OPT_dynamiclib)4.11k ) {6 |
1187 | 6 | // Derived from darwin_dylib1 spec. |
1188 | 6 | if (isTargetWatchOSBased()6 ) {0 |
1189 | 0 | ; // watchOS does not need dylib1.o. |
1190 | 6 | } else if (6 isTargetIOSSimulator()6 ) {1 |
1191 | 1 | ; // iOS simulator does not need dylib1.o. |
1192 | 5 | } else if (5 isTargetIPhoneOS()5 ) {2 |
1193 | 2 | if (isIPhoneOSVersionLT(3, 1)) |
1194 | 1 | CmdArgs.push_back("-ldylib1.o"); |
1195 | 3 | } else { |
1196 | 3 | if (isMacosxVersionLT(10, 5)) |
1197 | 3 | CmdArgs.push_back("-ldylib1.o"); |
1198 | 0 | else if (0 isMacosxVersionLT(10, 6)0 ) |
1199 | 0 | CmdArgs.push_back("-ldylib1.10.5.o"); |
1200 | 3 | } |
1201 | 4.10k | } else { |
1202 | 4.10k | if (Args.hasArg(options::OPT_bundle)4.10k ) {3 |
1203 | 3 | if (!Args.hasArg(options::OPT_static)3 ) {3 |
1204 | 3 | // Derived from darwin_bundle1 spec. |
1205 | 3 | if (isTargetWatchOSBased()3 ) {0 |
1206 | 0 | ; // watchOS does not need bundle1.o. |
1207 | 3 | } else if (3 isTargetIOSSimulator()3 ) {1 |
1208 | 1 | ; // iOS simulator does not need bundle1.o. |
1209 | 2 | } else if (2 isTargetIPhoneOS()2 ) {2 |
1210 | 2 | if (isIPhoneOSVersionLT(3, 1)) |
1211 | 1 | CmdArgs.push_back("-lbundle1.o"); |
1212 | 0 | } else { |
1213 | 0 | if (isMacosxVersionLT(10, 6)) |
1214 | 0 | CmdArgs.push_back("-lbundle1.o"); |
1215 | 0 | } |
1216 | 3 | } |
1217 | 4.10k | } else { |
1218 | 4.10k | if (Args.hasArg(options::OPT_pg) && 4.10k SupportsProfiling()1 ) {1 |
1219 | 1 | if (Args.hasArg(options::OPT_static) || |
1220 | 1 | Args.hasArg(options::OPT_object) || |
1221 | 1 | Args.hasArg(options::OPT_preload)1 ) {0 |
1222 | 0 | CmdArgs.push_back("-lgcrt0.o"); |
1223 | 1 | } else { |
1224 | 1 | CmdArgs.push_back("-lgcrt1.o"); |
1225 | 1 | |
1226 | 1 | // darwin_crt2 spec is empty. |
1227 | 1 | } |
1228 | 1 | // By default on OS X 10.8 and later, we don't link with a crt1.o |
1229 | 1 | // file and the linker knows to use _main as the entry point. But, |
1230 | 1 | // when compiling with -pg, we need to link with the gcrt1.o file, |
1231 | 1 | // so pass the -no_new_main option to tell the linker to use the |
1232 | 1 | // "start" symbol as the entry point. |
1233 | 1 | if (isTargetMacOS() && 1 !isMacosxVersionLT(10, 8)1 ) |
1234 | 1 | CmdArgs.push_back("-no_new_main"); |
1235 | 4.10k | } else { |
1236 | 4.10k | if (Args.hasArg(options::OPT_static) || |
1237 | 4.10k | Args.hasArg(options::OPT_object) || |
1238 | 4.10k | Args.hasArg(options::OPT_preload)4.10k ) {2 |
1239 | 2 | CmdArgs.push_back("-lcrt0.o"); |
1240 | 4.10k | } else { |
1241 | 4.10k | // Derived from darwin_crt1 spec. |
1242 | 4.10k | if (isTargetWatchOSBased()4.10k ) {12 |
1243 | 12 | ; // watchOS does not need crt1.o. |
1244 | 4.08k | } else if (4.08k isTargetIOSSimulator()4.08k ) {7 |
1245 | 7 | ; // iOS simulator does not need crt1.o. |
1246 | 4.08k | } else if (4.08k isTargetIPhoneOS()4.08k ) {3.76k |
1247 | 3.76k | if (getArch() == llvm::Triple::aarch64) |
1248 | 3.73k | ; // iOS does not need any crt1 files for arm64 |
1249 | 34 | else if (34 isIPhoneOSVersionLT(3, 1)34 ) |
1250 | 2 | CmdArgs.push_back("-lcrt1.o"); |
1251 | 32 | else if (32 isIPhoneOSVersionLT(6, 0)32 ) |
1252 | 16 | CmdArgs.push_back("-lcrt1.3.1.o"); |
1253 | 316 | } else { |
1254 | 316 | if (isMacosxVersionLT(10, 5)) |
1255 | 54 | CmdArgs.push_back("-lcrt1.o"); |
1256 | 262 | else if (262 isMacosxVersionLT(10, 6)262 ) |
1257 | 10 | CmdArgs.push_back("-lcrt1.10.5.o"); |
1258 | 252 | else if (252 isMacosxVersionLT(10, 8)252 ) |
1259 | 49 | CmdArgs.push_back("-lcrt1.10.6.o"); |
1260 | 316 | |
1261 | 316 | // darwin_crt2 spec is empty. |
1262 | 316 | } |
1263 | 4.10k | } |
1264 | 4.10k | } |
1265 | 4.10k | } |
1266 | 4.10k | } |
1267 | 4.11k | |
1268 | 4.11k | if (!isTargetIPhoneOS() && 4.11k Args.hasArg(options::OPT_shared_libgcc)342 && |
1269 | 0 | !isTargetWatchOS() && |
1270 | 0 | isMacosxVersionLT(10, 5)0 ) {0 |
1271 | 0 | const char *Str = Args.MakeArgString(GetFilePath("crt3.o")); |
1272 | 0 | CmdArgs.push_back(Str); |
1273 | 0 | } |
1274 | 4.11k | } |
1275 | | |
1276 | 0 | bool Darwin::SupportsObjCGC() const { return isTargetMacOS(); } |
1277 | | |
1278 | 28 | void Darwin::CheckObjCARC() const { |
1279 | 28 | if (isTargetIOSBased() || 28 isTargetWatchOSBased()25 || |
1280 | 24 | (isTargetMacOS() && 24 !isMacosxVersionLT(10, 6)24 )) |
1281 | 25 | return; |
1282 | 3 | getDriver().Diag(diag::err_arc_unsupported_on_toolchain); |
1283 | 3 | } |
1284 | | |
1285 | 19.1k | SanitizerMask Darwin::getSupportedSanitizers() const { |
1286 | 19.1k | const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; |
1287 | 19.1k | SanitizerMask Res = ToolChain::getSupportedSanitizers(); |
1288 | 19.1k | Res |= SanitizerKind::Address; |
1289 | 19.1k | if (isTargetMacOS()19.1k ) {2.55k |
1290 | 2.55k | if (!isMacosxVersionLT(10, 9)) |
1291 | 2.25k | Res |= SanitizerKind::Vptr; |
1292 | 2.55k | Res |= SanitizerKind::SafeStack; |
1293 | 2.55k | if (IsX86_64) |
1294 | 2.42k | Res |= SanitizerKind::Thread; |
1295 | 16.5k | } else if (16.5k isTargetIOSSimulator() || 16.5k isTargetTvOSSimulator()16.5k ) {25 |
1296 | 25 | if (IsX86_64) |
1297 | 15 | Res |= SanitizerKind::Thread; |
1298 | 25 | } |
1299 | 19.1k | return Res; |
1300 | 19.1k | } |
1301 | | |
1302 | 28 | void Darwin::printVerboseInfo(raw_ostream &OS) const { |
1303 | 28 | CudaInstallation.print(OS); |
1304 | 28 | } |
1305 | | |
1306 | | /// Generic_GCC - A tool chain using the 'gcc' command to perform |
1307 | | /// all subcommands; this relies on gcc translating the majority of |
1308 | | /// command line options. |
1309 | | |
1310 | | /// \brief Parse a GCCVersion object out of a string of text. |
1311 | | /// |
1312 | | /// This is the primary means of forming GCCVersion objects. |
1313 | | /*static*/ |
1314 | 3.16k | Generic_GCC::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) { |
1315 | 3.16k | const GCCVersion BadVersion = {VersionText.str(), -1, -1, -1, "", "", ""}; |
1316 | 3.16k | std::pair<StringRef, StringRef> First = VersionText.split('.'); |
1317 | 3.16k | std::pair<StringRef, StringRef> Second = First.second.split('.'); |
1318 | 3.16k | |
1319 | 3.16k | GCCVersion GoodVersion = {VersionText.str(), -1, -1, -1, "", "", ""}; |
1320 | 3.16k | if (First.first.getAsInteger(10, GoodVersion.Major) || 3.16k GoodVersion.Major < 03.16k ) |
1321 | 0 | return BadVersion; |
1322 | 3.16k | GoodVersion.MajorStr = First.first.str(); |
1323 | 3.16k | if (First.second.empty()) |
1324 | 1 | return GoodVersion; |
1325 | 3.15k | if (3.15k Second.first.getAsInteger(10, GoodVersion.Minor) || 3.15k GoodVersion.Minor < 03.15k ) |
1326 | 0 | return BadVersion; |
1327 | 3.15k | GoodVersion.MinorStr = Second.first.str(); |
1328 | 3.15k | |
1329 | 3.15k | // First look for a number prefix and parse that if present. Otherwise just |
1330 | 3.15k | // stash the entire patch string in the suffix, and leave the number |
1331 | 3.15k | // unspecified. This covers versions strings such as: |
1332 | 3.15k | // 5 (handled above) |
1333 | 3.15k | // 4.4 |
1334 | 3.15k | // 4.4.0 |
1335 | 3.15k | // 4.4.x |
1336 | 3.15k | // 4.4.2-rc4 |
1337 | 3.15k | // 4.4.x-patched |
1338 | 3.15k | // And retains any patch number it finds. |
1339 | 3.15k | StringRef PatchText = GoodVersion.PatchSuffix = Second.second.str(); |
1340 | 3.15k | if (!PatchText.empty()3.15k ) {3.03k |
1341 | 3.03k | if (size_t EndNumber3.03k = PatchText.find_first_not_of("0123456789")) {3.03k |
1342 | 3.03k | // Try to parse the number and any suffix. |
1343 | 3.03k | if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) || |
1344 | 3.03k | GoodVersion.Patch < 0) |
1345 | 0 | return BadVersion; |
1346 | 3.03k | GoodVersion.PatchSuffix = PatchText.substr(EndNumber); |
1347 | 3.03k | } |
1348 | 3.03k | } |
1349 | 3.15k | |
1350 | 3.15k | return GoodVersion; |
1351 | 3.15k | } |
1352 | | |
1353 | | /// \brief Less-than for GCCVersion, implementing a Strict Weak Ordering. |
1354 | | bool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor, |
1355 | | int RHSPatch, |
1356 | 2.89k | StringRef RHSPatchSuffix) const { |
1357 | 2.89k | if (Major != RHSMajor) |
1358 | 1.95k | return Major < RHSMajor; |
1359 | 942 | if (942 Minor != RHSMinor942 ) |
1360 | 821 | return Minor < RHSMinor; |
1361 | 121 | if (121 Patch != RHSPatch121 ) {22 |
1362 | 22 | // Note that versions without a specified patch sort higher than those with |
1363 | 22 | // a patch. |
1364 | 22 | if (RHSPatch == -1) |
1365 | 3 | return true; |
1366 | 19 | if (19 Patch == -119 ) |
1367 | 11 | return false; |
1368 | 19 | |
1369 | 19 | // Otherwise just sort on the patch itself. |
1370 | 8 | return Patch < RHSPatch; |
1371 | 19 | } |
1372 | 99 | if (99 PatchSuffix != RHSPatchSuffix99 ) {1 |
1373 | 1 | // Sort empty suffixes higher. |
1374 | 1 | if (RHSPatchSuffix.empty()) |
1375 | 0 | return true; |
1376 | 1 | if (1 PatchSuffix.empty()1 ) |
1377 | 1 | return false; |
1378 | 1 | |
1379 | 1 | // Provide a lexicographic sort to make this a total ordering. |
1380 | 0 | return PatchSuffix < RHSPatchSuffix; |
1381 | 1 | } |
1382 | 99 | |
1383 | 99 | // The versions are equal. |
1384 | 98 | return false; |
1385 | 99 | } |
1386 | | |
1387 | 2.15k | static llvm::StringRef getGCCToolchainDir(const ArgList &Args) { |
1388 | 2.15k | const Arg *A = Args.getLastArg(options::OPT_gcc_toolchain); |
1389 | 2.15k | if (A) |
1390 | 368 | return A->getValue(); |
1391 | 1.79k | return 1.79k GCC_INSTALL_PREFIX1.79k ; |
1392 | 2.15k | } |
1393 | | |
1394 | | /// \brief Initialize a GCCInstallationDetector from the driver. |
1395 | | /// |
1396 | | /// This performs all of the autodetection and sets up the various paths. |
1397 | | /// Once constructed, a GCCInstallationDetector is essentially immutable. |
1398 | | /// |
1399 | | /// FIXME: We shouldn't need an explicit TargetTriple parameter here, and |
1400 | | /// should instead pull the target out of the driver. This is currently |
1401 | | /// necessary because the driver doesn't store the final version of the target |
1402 | | /// triple. |
1403 | | void Generic_GCC::GCCInstallationDetector::init( |
1404 | | const llvm::Triple &TargetTriple, const ArgList &Args, |
1405 | 2.15k | ArrayRef<std::string> ExtraTripleAliases) { |
1406 | 2.15k | llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit() |
1407 | 1.14k | ? TargetTriple.get64BitArchVariant() |
1408 | 1.01k | : TargetTriple.get32BitArchVariant(); |
1409 | 2.15k | // The library directories which may contain GCC installations. |
1410 | 2.15k | SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs; |
1411 | 2.15k | // The compatible GCC triples for this particular architecture. |
1412 | 2.15k | SmallVector<StringRef, 16> CandidateTripleAliases; |
1413 | 2.15k | SmallVector<StringRef, 16> CandidateBiarchTripleAliases; |
1414 | 2.15k | CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs, |
1415 | 2.15k | CandidateTripleAliases, CandidateBiarchLibDirs, |
1416 | 2.15k | CandidateBiarchTripleAliases); |
1417 | 2.15k | |
1418 | 2.15k | // Compute the set of prefixes for our search. |
1419 | 2.15k | SmallVector<std::string, 8> Prefixes(D.PrefixDirs.begin(), |
1420 | 2.15k | D.PrefixDirs.end()); |
1421 | 2.15k | |
1422 | 2.15k | StringRef GCCToolchainDir = getGCCToolchainDir(Args); |
1423 | 2.15k | if (GCCToolchainDir != ""2.15k ) {180 |
1424 | 180 | if (GCCToolchainDir.back() == '/') |
1425 | 0 | GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the / |
1426 | 180 | |
1427 | 180 | Prefixes.push_back(GCCToolchainDir); |
1428 | 1.97k | } else { |
1429 | 1.97k | // If we have a SysRoot, try that first. |
1430 | 1.97k | if (!D.SysRoot.empty()1.97k ) {290 |
1431 | 290 | Prefixes.push_back(D.SysRoot); |
1432 | 290 | Prefixes.push_back(D.SysRoot + "/usr"); |
1433 | 290 | } |
1434 | 1.97k | |
1435 | 1.97k | // Then look for gcc installed alongside clang. |
1436 | 1.97k | Prefixes.push_back(D.InstalledDir + "/.."); |
1437 | 1.97k | |
1438 | 1.97k | // Then look for distribution supplied gcc installations. |
1439 | 1.97k | if (D.SysRoot.empty()1.97k ) {1.68k |
1440 | 1.68k | // Look for RHEL devtoolsets. |
1441 | 1.68k | Prefixes.push_back("/opt/rh/devtoolset-6/root/usr"); |
1442 | 1.68k | Prefixes.push_back("/opt/rh/devtoolset-4/root/usr"); |
1443 | 1.68k | Prefixes.push_back("/opt/rh/devtoolset-3/root/usr"); |
1444 | 1.68k | Prefixes.push_back("/opt/rh/devtoolset-2/root/usr"); |
1445 | 1.68k | // And finally in /usr. |
1446 | 1.68k | Prefixes.push_back("/usr"); |
1447 | 1.68k | } |
1448 | 1.97k | } |
1449 | 2.15k | |
1450 | 2.15k | // Try to respect gcc-config on Gentoo. However, do that only |
1451 | 2.15k | // if --gcc-toolchain is not provided or equal to the Gentoo install |
1452 | 2.15k | // in /usr. This avoids accidentally enforcing the system GCC version |
1453 | 2.15k | // when using a custom toolchain. |
1454 | 2.15k | if (GCCToolchainDir == "" || 2.15k GCCToolchainDir == D.SysRoot + "/usr"180 ) {1.97k |
1455 | 20 | for (StringRef CandidateTriple : ExtraTripleAliases) { |
1456 | 20 | if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple)) |
1457 | 0 | return; |
1458 | 20 | } |
1459 | 14.9k | for (StringRef CandidateTriple : CandidateTripleAliases) 1.97k {14.9k |
1460 | 14.9k | if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple)) |
1461 | 4 | return; |
1462 | 14.9k | } |
1463 | 14.2k | for (StringRef CandidateTriple : CandidateBiarchTripleAliases) 1.97k {14.2k |
1464 | 14.2k | if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple, true)) |
1465 | 2 | return; |
1466 | 14.2k | } |
1467 | 1.97k | } |
1468 | 2.15k | |
1469 | 2.15k | // Loop over the various components which exist and select the best GCC |
1470 | 2.15k | // installation available. GCC installs are ranked by version number. |
1471 | 2.15k | Version = GCCVersion::Parse("0.0.0"); |
1472 | 11.1k | for (const std::string &Prefix : Prefixes) { |
1473 | 11.1k | if (!D.getVFS().exists(Prefix)) |
1474 | 6.79k | continue; |
1475 | 7.26k | for (StringRef Suffix : CandidateLibDirs) 4.40k {7.26k |
1476 | 7.26k | const std::string LibDir = Prefix + Suffix.str(); |
1477 | 7.26k | if (!D.getVFS().exists(LibDir)) |
1478 | 3.09k | continue; |
1479 | 4.16k | for (StringRef Candidate : ExtraTripleAliases) // Try these first. |
1480 | 24 | ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate); |
1481 | 4.16k | for (StringRef Candidate : CandidateTripleAliases) |
1482 | 32.3k | ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate); |
1483 | 4.16k | } |
1484 | 6.27k | for (StringRef Suffix : CandidateBiarchLibDirs) { |
1485 | 6.27k | const std::string LibDir = Prefix + Suffix.str(); |
1486 | 6.27k | if (!D.getVFS().exists(LibDir)) |
1487 | 3.16k | continue; |
1488 | 3.10k | for (StringRef Candidate : CandidateBiarchTripleAliases) |
1489 | 29.7k | ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, |
1490 | 29.7k | /*NeedsBiarchSuffix=*/ true); |
1491 | 3.10k | } |
1492 | 4.40k | } |
1493 | 2.15k | } |
1494 | | |
1495 | 58 | void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const { |
1496 | 58 | for (const auto &InstallPath : CandidateGCCInstallPaths) |
1497 | 4 | OS << "Found candidate GCC installation: " << InstallPath << "\n"; |
1498 | 58 | |
1499 | 58 | if (!GCCInstallPath.empty()) |
1500 | 3 | OS << "Selected GCC installation: " << GCCInstallPath << "\n"; |
1501 | 58 | |
1502 | 58 | for (const auto &Multilib : Multilibs) |
1503 | 3 | OS << "Candidate multilib: " << Multilib << "\n"; |
1504 | 58 | |
1505 | 58 | if (Multilibs.size() != 0 || 58 !SelectedMultilib.isDefault()55 ) |
1506 | 3 | OS << "Selected multilib: " << SelectedMultilib << "\n"; |
1507 | 58 | } |
1508 | | |
1509 | 355 | bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const { |
1510 | 355 | if (BiarchSibling.hasValue()355 ) {34 |
1511 | 34 | M = BiarchSibling.getValue(); |
1512 | 34 | return true; |
1513 | 34 | } |
1514 | 321 | return false; |
1515 | 355 | } |
1516 | | |
1517 | | /*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples( |
1518 | | const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple, |
1519 | | SmallVectorImpl<StringRef> &LibDirs, |
1520 | | SmallVectorImpl<StringRef> &TripleAliases, |
1521 | | SmallVectorImpl<StringRef> &BiarchLibDirs, |
1522 | 2.15k | SmallVectorImpl<StringRef> &BiarchTripleAliases) { |
1523 | 2.15k | // Declare a bunch of static data sets that we'll select between below. These |
1524 | 2.15k | // are specifically designed to always refer to string literals to avoid any |
1525 | 2.15k | // lifetime or initialization issues. |
1526 | 2.15k | static const char *const AArch64LibDirs[] = {"/lib64", "/lib"}; |
1527 | 2.15k | static const char *const AArch64Triples[] = { |
1528 | 2.15k | "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-linux-android", |
1529 | 2.15k | "aarch64-redhat-linux", "aarch64-suse-linux"}; |
1530 | 2.15k | static const char *const AArch64beLibDirs[] = {"/lib"}; |
1531 | 2.15k | static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu", |
1532 | 2.15k | "aarch64_be-linux-gnu"}; |
1533 | 2.15k | |
1534 | 2.15k | static const char *const ARMLibDirs[] = {"/lib"}; |
1535 | 2.15k | static const char *const ARMTriples[] = {"arm-linux-gnueabi", |
1536 | 2.15k | "arm-linux-androideabi"}; |
1537 | 2.15k | static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf", |
1538 | 2.15k | "armv7hl-redhat-linux-gnueabi"}; |
1539 | 2.15k | static const char *const ARMebLibDirs[] = {"/lib"}; |
1540 | 2.15k | static const char *const ARMebTriples[] = {"armeb-linux-gnueabi", |
1541 | 2.15k | "armeb-linux-androideabi"}; |
1542 | 2.15k | static const char *const ARMebHFTriples[] = { |
1543 | 2.15k | "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"}; |
1544 | 2.15k | |
1545 | 2.15k | static const char *const X86_64LibDirs[] = {"/lib64", "/lib"}; |
1546 | 2.15k | static const char *const X86_64Triples[] = { |
1547 | 2.15k | "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", |
1548 | 2.15k | "x86_64-pc-linux-gnu", "x86_64-redhat-linux6E", |
1549 | 2.15k | "x86_64-redhat-linux", "x86_64-suse-linux", |
1550 | 2.15k | "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", |
1551 | 2.15k | "x86_64-slackware-linux", "x86_64-linux-android", |
1552 | 2.15k | "x86_64-unknown-linux"}; |
1553 | 2.15k | static const char *const X32LibDirs[] = {"/libx32"}; |
1554 | 2.15k | static const char *const X86LibDirs[] = {"/lib32", "/lib"}; |
1555 | 2.15k | static const char *const X86Triples[] = { |
1556 | 2.15k | "i686-linux-gnu", "i686-pc-linux-gnu", "i486-linux-gnu", |
1557 | 2.15k | "i386-linux-gnu", "i386-redhat-linux6E", "i686-redhat-linux", |
1558 | 2.15k | "i586-redhat-linux", "i386-redhat-linux", "i586-suse-linux", |
1559 | 2.15k | "i486-slackware-linux", "i686-montavista-linux", "i686-linux-android", |
1560 | 2.15k | "i586-linux-gnu"}; |
1561 | 2.15k | |
1562 | 2.15k | static const char *const MIPSLibDirs[] = {"/lib"}; |
1563 | 2.15k | static const char *const MIPSTriples[] = {"mips-linux-gnu", "mips-mti-linux", |
1564 | 2.15k | "mips-mti-linux-gnu", |
1565 | 2.15k | "mips-img-linux-gnu"}; |
1566 | 2.15k | static const char *const MIPSELLibDirs[] = {"/lib"}; |
1567 | 2.15k | static const char *const MIPSELTriples[] = {"mipsel-linux-gnu", |
1568 | 2.15k | "mips-img-linux-gnu"}; |
1569 | 2.15k | |
1570 | 2.15k | static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"}; |
1571 | 2.15k | static const char *const MIPS64Triples[] = { |
1572 | 2.15k | "mips64-linux-gnu", "mips-mti-linux-gnu", "mips-img-linux-gnu", |
1573 | 2.15k | "mips64-linux-gnuabi64"}; |
1574 | 2.15k | static const char *const MIPS64ELLibDirs[] = {"/lib64", "/lib"}; |
1575 | 2.15k | static const char *const MIPS64ELTriples[] = { |
1576 | 2.15k | "mips64el-linux-gnu", "mips-mti-linux-gnu", "mips-img-linux-gnu", |
1577 | 2.15k | "mips64el-linux-gnuabi64"}; |
1578 | 2.15k | |
1579 | 2.15k | static const char *const MIPSELAndroidLibDirs[] = {"/lib", "/libr2", |
1580 | 2.15k | "/libr6"}; |
1581 | 2.15k | static const char *const MIPSELAndroidTriples[] = {"mipsel-linux-android"}; |
1582 | 2.15k | static const char *const MIPS64ELAndroidLibDirs[] = {"/lib64", "/lib", |
1583 | 2.15k | "/libr2", "/libr6"}; |
1584 | 2.15k | static const char *const MIPS64ELAndroidTriples[] = { |
1585 | 2.15k | "mips64el-linux-android"}; |
1586 | 2.15k | |
1587 | 2.15k | static const char *const PPCLibDirs[] = {"/lib32", "/lib"}; |
1588 | 2.15k | static const char *const PPCTriples[] = { |
1589 | 2.15k | "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe", |
1590 | 2.15k | "powerpc-suse-linux", "powerpc-montavista-linuxspe"}; |
1591 | 2.15k | static const char *const PPC64LibDirs[] = {"/lib64", "/lib"}; |
1592 | 2.15k | static const char *const PPC64Triples[] = { |
1593 | 2.15k | "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu", |
1594 | 2.15k | "powerpc64-suse-linux", "ppc64-redhat-linux"}; |
1595 | 2.15k | static const char *const PPC64LELibDirs[] = {"/lib64", "/lib"}; |
1596 | 2.15k | static const char *const PPC64LETriples[] = { |
1597 | 2.15k | "powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu", |
1598 | 2.15k | "powerpc64le-suse-linux", "ppc64le-redhat-linux"}; |
1599 | 2.15k | |
1600 | 2.15k | static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"}; |
1601 | 2.15k | static const char *const SPARCv8Triples[] = {"sparc-linux-gnu", |
1602 | 2.15k | "sparcv8-linux-gnu"}; |
1603 | 2.15k | static const char *const SPARCv9LibDirs[] = {"/lib64", "/lib"}; |
1604 | 2.15k | static const char *const SPARCv9Triples[] = {"sparc64-linux-gnu", |
1605 | 2.15k | "sparcv9-linux-gnu"}; |
1606 | 2.15k | |
1607 | 2.15k | static const char *const SystemZLibDirs[] = {"/lib64", "/lib"}; |
1608 | 2.15k | static const char *const SystemZTriples[] = { |
1609 | 2.15k | "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu", |
1610 | 2.15k | "s390x-suse-linux", "s390x-redhat-linux"}; |
1611 | 2.15k | |
1612 | 2.15k | // Solaris. |
1613 | 2.15k | static const char *const SolarisSPARCLibDirs[] = {"/gcc"}; |
1614 | 2.15k | static const char *const SolarisSPARCTriples[] = {"sparc-sun-solaris2.11", |
1615 | 2.15k | "i386-pc-solaris2.11"}; |
1616 | 2.15k | |
1617 | 2.15k | using std::begin; |
1618 | 2.15k | using std::end; |
1619 | 2.15k | |
1620 | 2.15k | if (TargetTriple.getOS() == llvm::Triple::Solaris2.15k ) {8 |
1621 | 8 | LibDirs.append(begin(SolarisSPARCLibDirs), end(SolarisSPARCLibDirs)); |
1622 | 8 | TripleAliases.append(begin(SolarisSPARCTriples), end(SolarisSPARCTriples)); |
1623 | 8 | return; |
1624 | 8 | } |
1625 | 2.15k | |
1626 | 2.15k | switch (TargetTriple.getArch()) { |
1627 | 71 | case llvm::Triple::aarch64: |
1628 | 71 | LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs)); |
1629 | 71 | TripleAliases.append(begin(AArch64Triples), end(AArch64Triples)); |
1630 | 71 | BiarchLibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs)); |
1631 | 71 | BiarchTripleAliases.append(begin(AArch64Triples), end(AArch64Triples)); |
1632 | 71 | break; |
1633 | 1 | case llvm::Triple::aarch64_be: |
1634 | 1 | LibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs)); |
1635 | 1 | TripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples)); |
1636 | 1 | BiarchLibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs)); |
1637 | 1 | BiarchTripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples)); |
1638 | 1 | break; |
1639 | 345 | case llvm::Triple::arm: |
1640 | 345 | case llvm::Triple::thumb: |
1641 | 345 | LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs)); |
1642 | 345 | if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF345 ) {18 |
1643 | 18 | TripleAliases.append(begin(ARMHFTriples), end(ARMHFTriples)); |
1644 | 327 | } else { |
1645 | 327 | TripleAliases.append(begin(ARMTriples), end(ARMTriples)); |
1646 | 327 | } |
1647 | 345 | break; |
1648 | 43 | case llvm::Triple::armeb: |
1649 | 43 | case llvm::Triple::thumbeb: |
1650 | 43 | LibDirs.append(begin(ARMebLibDirs), end(ARMebLibDirs)); |
1651 | 43 | if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF43 ) {2 |
1652 | 2 | TripleAliases.append(begin(ARMebHFTriples), end(ARMebHFTriples)); |
1653 | 41 | } else { |
1654 | 41 | TripleAliases.append(begin(ARMebTriples), end(ARMebTriples)); |
1655 | 41 | } |
1656 | 43 | break; |
1657 | 548 | case llvm::Triple::x86_64: |
1658 | 548 | LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); |
1659 | 548 | TripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); |
1660 | 548 | // x32 is always available when x86_64 is available, so adding it as |
1661 | 548 | // secondary arch with x86_64 triples |
1662 | 548 | if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32548 ) {10 |
1663 | 10 | BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs)); |
1664 | 10 | BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); |
1665 | 538 | } else { |
1666 | 538 | BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs)); |
1667 | 538 | BiarchTripleAliases.append(begin(X86Triples), end(X86Triples)); |
1668 | 538 | } |
1669 | 548 | break; |
1670 | 280 | case llvm::Triple::x86: |
1671 | 280 | LibDirs.append(begin(X86LibDirs), end(X86LibDirs)); |
1672 | 280 | // MCU toolchain is 32 bit only and its triple alias is TargetTriple |
1673 | 280 | // itself, which will be appended below. |
1674 | 280 | if (!TargetTriple.isOSIAMCU()280 ) {271 |
1675 | 271 | TripleAliases.append(begin(X86Triples), end(X86Triples)); |
1676 | 271 | BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); |
1677 | 271 | BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); |
1678 | 271 | } |
1679 | 280 | break; |
1680 | 275 | case llvm::Triple::mips: |
1681 | 275 | LibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs)); |
1682 | 275 | TripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); |
1683 | 275 | BiarchLibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs)); |
1684 | 275 | BiarchTripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples)); |
1685 | 275 | break; |
1686 | 97 | case llvm::Triple::mipsel: |
1687 | 97 | if (TargetTriple.isAndroid()97 ) {18 |
1688 | 18 | LibDirs.append(begin(MIPSELAndroidLibDirs), end(MIPSELAndroidLibDirs)); |
1689 | 18 | TripleAliases.append(begin(MIPSELAndroidTriples), |
1690 | 18 | end(MIPSELAndroidTriples)); |
1691 | 18 | BiarchLibDirs.append(begin(MIPS64ELAndroidLibDirs), |
1692 | 18 | end(MIPS64ELAndroidLibDirs)); |
1693 | 18 | BiarchTripleAliases.append(begin(MIPS64ELAndroidTriples), |
1694 | 18 | end(MIPS64ELAndroidTriples)); |
1695 | 18 | |
1696 | 79 | } else { |
1697 | 79 | LibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs)); |
1698 | 79 | TripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples)); |
1699 | 79 | TripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); |
1700 | 79 | BiarchLibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs)); |
1701 | 79 | BiarchTripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples)); |
1702 | 79 | } |
1703 | 97 | break; |
1704 | 82 | case llvm::Triple::mips64: |
1705 | 82 | LibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs)); |
1706 | 82 | TripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples)); |
1707 | 82 | BiarchLibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs)); |
1708 | 82 | BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); |
1709 | 82 | break; |
1710 | 70 | case llvm::Triple::mips64el: |
1711 | 70 | if (TargetTriple.isAndroid()70 ) {11 |
1712 | 11 | LibDirs.append(begin(MIPS64ELAndroidLibDirs), |
1713 | 11 | end(MIPS64ELAndroidLibDirs)); |
1714 | 11 | TripleAliases.append(begin(MIPS64ELAndroidTriples), |
1715 | 11 | end(MIPS64ELAndroidTriples)); |
1716 | 11 | BiarchLibDirs.append(begin(MIPSELAndroidLibDirs), |
1717 | 11 | end(MIPSELAndroidLibDirs)); |
1718 | 11 | BiarchTripleAliases.append(begin(MIPSELAndroidTriples), |
1719 | 11 | end(MIPSELAndroidTriples)); |
1720 | 11 | |
1721 | 59 | } else { |
1722 | 59 | LibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs)); |
1723 | 59 | TripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples)); |
1724 | 59 | BiarchLibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs)); |
1725 | 59 | BiarchTripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples)); |
1726 | 59 | BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); |
1727 | 59 | } |
1728 | 70 | break; |
1729 | 17 | case llvm::Triple::ppc: |
1730 | 17 | LibDirs.append(begin(PPCLibDirs), end(PPCLibDirs)); |
1731 | 17 | TripleAliases.append(begin(PPCTriples), end(PPCTriples)); |
1732 | 17 | BiarchLibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs)); |
1733 | 17 | BiarchTripleAliases.append(begin(PPC64Triples), end(PPC64Triples)); |
1734 | 17 | break; |
1735 | 101 | case llvm::Triple::ppc64: |
1736 | 101 | LibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs)); |
1737 | 101 | TripleAliases.append(begin(PPC64Triples), end(PPC64Triples)); |
1738 | 101 | BiarchLibDirs.append(begin(PPCLibDirs), end(PPCLibDirs)); |
1739 | 101 | BiarchTripleAliases.append(begin(PPCTriples), end(PPCTriples)); |
1740 | 101 | break; |
1741 | 87 | case llvm::Triple::ppc64le: |
1742 | 87 | LibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs)); |
1743 | 87 | TripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples)); |
1744 | 87 | break; |
1745 | 32 | case llvm::Triple::sparc: |
1746 | 32 | case llvm::Triple::sparcel: |
1747 | 32 | LibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs)); |
1748 | 32 | TripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples)); |
1749 | 32 | BiarchLibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs)); |
1750 | 32 | BiarchTripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples)); |
1751 | 32 | break; |
1752 | 17 | case llvm::Triple::sparcv9: |
1753 | 17 | LibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs)); |
1754 | 17 | TripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples)); |
1755 | 17 | BiarchLibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs)); |
1756 | 17 | BiarchTripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples)); |
1757 | 17 | break; |
1758 | 30 | case llvm::Triple::systemz: |
1759 | 30 | LibDirs.append(begin(SystemZLibDirs), end(SystemZLibDirs)); |
1760 | 30 | TripleAliases.append(begin(SystemZTriples), end(SystemZTriples)); |
1761 | 30 | break; |
1762 | 55 | default: |
1763 | 55 | // By default, just rely on the standard lib directories and the original |
1764 | 55 | // triple. |
1765 | 55 | break; |
1766 | 2.15k | } |
1767 | 2.15k | |
1768 | 2.15k | // Always append the drivers target triple to the end, in case it doesn't |
1769 | 2.15k | // match any of our aliases. |
1770 | 2.15k | TripleAliases.push_back(TargetTriple.str()); |
1771 | 2.15k | |
1772 | 2.15k | // Also include the multiarch variant if it's different. |
1773 | 2.15k | if (TargetTriple.str() != BiarchTriple.str()) |
1774 | 2.15k | BiarchTripleAliases.push_back(BiarchTriple.str()); |
1775 | 2.15k | } |
1776 | | |
1777 | | // Parses the contents of version.txt in an CUDA installation. It should |
1778 | | // contain one line of the from e.g. "CUDA Version 7.5.2". |
1779 | 20 | static CudaVersion ParseCudaVersionFile(llvm::StringRef V) { |
1780 | 20 | if (!V.startswith("CUDA Version ")) |
1781 | 0 | return CudaVersion::UNKNOWN; |
1782 | 20 | V = V.substr(strlen("CUDA Version ")); |
1783 | 20 | int Major = -1, Minor = -1; |
1784 | 20 | auto First = V.split('.'); |
1785 | 20 | auto Second = First.second.split('.'); |
1786 | 20 | if (First.first.getAsInteger(10, Major) || |
1787 | 20 | Second.first.getAsInteger(10, Minor)) |
1788 | 0 | return CudaVersion::UNKNOWN; |
1789 | 20 | |
1790 | 20 | if (20 Major == 7 && 20 Minor == 00 ) {0 |
1791 | 0 | // This doesn't appear to ever happen -- version.txt doesn't exist in the |
1792 | 0 | // CUDA 7 installs I've seen. But no harm in checking. |
1793 | 0 | return CudaVersion::CUDA_70; |
1794 | 0 | } |
1795 | 20 | if (20 Major == 7 && 20 Minor == 50 ) |
1796 | 0 | return CudaVersion::CUDA_75; |
1797 | 20 | if (20 Major == 8 && 20 Minor == 020 ) |
1798 | 20 | return CudaVersion::CUDA_80; |
1799 | 0 | return CudaVersion::UNKNOWN; |
1800 | 20 | } |
1801 | | |
1802 | | CudaInstallationDetector::CudaInstallationDetector( |
1803 | | const Driver &D, const llvm::Triple &HostTriple, |
1804 | | const llvm::opt::ArgList &Args) |
1805 | 25.3k | : D(D) { |
1806 | 25.3k | SmallVector<std::string, 4> CudaPathCandidates; |
1807 | 25.3k | |
1808 | 25.3k | // In decreasing order so we prefer newer versions to older versions. |
1809 | 25.3k | std::initializer_list<const char *> Versions = {"8.0", "7.5", "7.0"}; |
1810 | 25.3k | |
1811 | 25.3k | if (Args.hasArg(options::OPT_cuda_path_EQ)25.3k ) {44 |
1812 | 44 | CudaPathCandidates.push_back( |
1813 | 44 | Args.getLastArgValue(options::OPT_cuda_path_EQ)); |
1814 | 25.3k | } else if (25.3k HostTriple.isOSWindows()25.3k ) {591 |
1815 | 591 | for (const char *Ver : Versions) |
1816 | 1.77k | CudaPathCandidates.push_back( |
1817 | 1.77k | D.SysRoot + "/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v" + |
1818 | 1.77k | Ver); |
1819 | 24.7k | } else { |
1820 | 24.7k | CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda"); |
1821 | 24.7k | for (const char *Ver : Versions) |
1822 | 74.2k | CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-" + Ver); |
1823 | 24.7k | } |
1824 | 25.3k | |
1825 | 100k | for (const auto &CudaPath : CudaPathCandidates) { |
1826 | 100k | if (CudaPath.empty() || 100k !D.getVFS().exists(CudaPath)100k ) |
1827 | 100k | continue; |
1828 | 100k | |
1829 | 61 | InstallPath = CudaPath; |
1830 | 61 | BinPath = CudaPath + "/bin"; |
1831 | 61 | IncludePath = InstallPath + "/include"; |
1832 | 61 | LibDevicePath = InstallPath + "/nvvm/libdevice"; |
1833 | 61 | |
1834 | 61 | auto &FS = D.getVFS(); |
1835 | 61 | if (!(FS.exists(IncludePath) && 61 FS.exists(BinPath)61 && |
1836 | 61 | FS.exists(LibDevicePath))) |
1837 | 0 | continue; |
1838 | 61 | |
1839 | 61 | // On Linux, we have both lib and lib64 directories, and we need to choose |
1840 | 61 | // based on our triple. On MacOS, we have only a lib directory. |
1841 | 61 | // |
1842 | 61 | // It's sufficient for our purposes to be flexible: If both lib and lib64 |
1843 | 61 | // exist, we choose whichever one matches our triple. Otherwise, if only |
1844 | 61 | // lib exists, we use it. |
1845 | 61 | if (61 HostTriple.isArch64Bit() && 61 FS.exists(InstallPath + "/lib64")22 ) |
1846 | 22 | LibPath = InstallPath + "/lib64"; |
1847 | 39 | else if (39 FS.exists(InstallPath + "/lib")39 ) |
1848 | 39 | LibPath = InstallPath + "/lib"; |
1849 | 39 | else |
1850 | 0 | continue; |
1851 | 61 | |
1852 | 61 | llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> VersionFile = |
1853 | 61 | FS.getBufferForFile(InstallPath + "/version.txt"); |
1854 | 61 | if (!VersionFile61 ) {41 |
1855 | 41 | // CUDA 7.0 doesn't have a version.txt, so guess that's our version if |
1856 | 41 | // version.txt isn't present. |
1857 | 41 | Version = CudaVersion::CUDA_70; |
1858 | 20 | } else { |
1859 | 20 | Version = ParseCudaVersionFile((*VersionFile)->getBuffer()); |
1860 | 20 | } |
1861 | 61 | |
1862 | 61 | std::error_code EC; |
1863 | 61 | for (llvm::sys::fs::directory_iterator LI(LibDevicePath, EC), LE; |
1864 | 223 | !EC && 223 LI != LE223 ; LI = LI.increment(EC)162 ) {162 |
1865 | 162 | StringRef FilePath = LI->path(); |
1866 | 162 | StringRef FileName = llvm::sys::path::filename(FilePath); |
1867 | 162 | // Process all bitcode filenames that look like libdevice.compute_XX.YY.bc |
1868 | 162 | const StringRef LibDeviceName = "libdevice."; |
1869 | 162 | if (!(FileName.startswith(LibDeviceName) && 162 FileName.endswith(".bc")162 )) |
1870 | 0 | continue; |
1871 | 162 | StringRef GpuArch = FileName.slice( |
1872 | 162 | LibDeviceName.size(), FileName.find('.', LibDeviceName.size())); |
1873 | 162 | LibDeviceMap[GpuArch] = FilePath.str(); |
1874 | 162 | // Insert map entries for specifc devices with this compute |
1875 | 162 | // capability. NVCC's choice of the libdevice library version is |
1876 | 162 | // rather peculiar and depends on the CUDA version. |
1877 | 162 | if (GpuArch == "compute_20"162 ) {20 |
1878 | 20 | LibDeviceMap["sm_20"] = FilePath; |
1879 | 20 | LibDeviceMap["sm_21"] = FilePath; |
1880 | 20 | LibDeviceMap["sm_32"] = FilePath; |
1881 | 142 | } else if (142 GpuArch == "compute_30"142 ) {61 |
1882 | 61 | LibDeviceMap["sm_30"] = FilePath; |
1883 | 61 | if (Version < CudaVersion::CUDA_8061 ) {41 |
1884 | 41 | LibDeviceMap["sm_50"] = FilePath; |
1885 | 41 | LibDeviceMap["sm_52"] = FilePath; |
1886 | 41 | LibDeviceMap["sm_53"] = FilePath; |
1887 | 41 | } |
1888 | 61 | LibDeviceMap["sm_60"] = FilePath; |
1889 | 61 | LibDeviceMap["sm_61"] = FilePath; |
1890 | 61 | LibDeviceMap["sm_62"] = FilePath; |
1891 | 81 | } else if (81 GpuArch == "compute_35"81 ) {61 |
1892 | 61 | LibDeviceMap["sm_35"] = FilePath; |
1893 | 61 | LibDeviceMap["sm_37"] = FilePath; |
1894 | 20 | } else if (20 GpuArch == "compute_50"20 ) {20 |
1895 | 20 | if (Version >= CudaVersion::CUDA_8020 ) {20 |
1896 | 20 | LibDeviceMap["sm_50"] = FilePath; |
1897 | 20 | LibDeviceMap["sm_52"] = FilePath; |
1898 | 20 | LibDeviceMap["sm_53"] = FilePath; |
1899 | 20 | } |
1900 | 20 | } |
1901 | 162 | } |
1902 | 61 | |
1903 | 61 | IsValid = true; |
1904 | 61 | break; |
1905 | 61 | } |
1906 | 25.3k | } |
1907 | | |
1908 | | void CudaInstallationDetector::AddCudaIncludeArgs( |
1909 | 233 | const ArgList &DriverArgs, ArgStringList &CC1Args) const { |
1910 | 233 | if (!DriverArgs.hasArg(options::OPT_nobuiltininc)233 ) {233 |
1911 | 233 | // Add cuda_wrappers/* to our system include path. This lets us wrap |
1912 | 233 | // standard library headers. |
1913 | 233 | SmallString<128> P(D.ResourceDir); |
1914 | 233 | llvm::sys::path::append(P, "include"); |
1915 | 233 | llvm::sys::path::append(P, "cuda_wrappers"); |
1916 | 233 | CC1Args.push_back("-internal-isystem"); |
1917 | 233 | CC1Args.push_back(DriverArgs.MakeArgString(P)); |
1918 | 233 | } |
1919 | 233 | |
1920 | 233 | if (DriverArgs.hasArg(options::OPT_nocudainc)) |
1921 | 38 | return; |
1922 | 233 | |
1923 | 195 | if (195 !isValid()195 ) {147 |
1924 | 147 | D.Diag(diag::err_drv_no_cuda_installation); |
1925 | 147 | return; |
1926 | 147 | } |
1927 | 195 | |
1928 | 48 | CC1Args.push_back("-internal-isystem"); |
1929 | 48 | CC1Args.push_back(DriverArgs.MakeArgString(getIncludePath())); |
1930 | 48 | CC1Args.push_back("-include"); |
1931 | 48 | CC1Args.push_back("__clang_cuda_runtime_wrapper.h"); |
1932 | 48 | } |
1933 | | |
1934 | | void CudaInstallationDetector::CheckCudaVersionSupportsArch( |
1935 | 201 | CudaArch Arch) const { |
1936 | 201 | if (Arch == CudaArch::UNKNOWN || 201 Version == CudaVersion::UNKNOWN201 || |
1937 | 50 | ArchsWithVersionTooLowErrors.count(Arch) > 0) |
1938 | 155 | return; |
1939 | 201 | |
1940 | 46 | auto RequiredVersion = MinVersionForCudaArch(Arch); |
1941 | 46 | if (Version < RequiredVersion46 ) {6 |
1942 | 6 | ArchsWithVersionTooLowErrors.insert(Arch); |
1943 | 6 | D.Diag(diag::err_drv_cuda_version_too_low) |
1944 | 6 | << InstallPath << CudaArchToString(Arch) << CudaVersionToString(Version) |
1945 | 6 | << CudaVersionToString(RequiredVersion); |
1946 | 6 | } |
1947 | 46 | } |
1948 | | |
1949 | 100 | void CudaInstallationDetector::print(raw_ostream &OS) const { |
1950 | 100 | if (isValid()) |
1951 | 32 | OS << "Found CUDA installation: " << InstallPath << ", version " |
1952 | 32 | << CudaVersionToString(Version) << "\n"; |
1953 | 100 | } |
1954 | | |
1955 | | namespace { |
1956 | | // Filter to remove Multilibs that don't exist as a suffix to Path |
1957 | | class FilterNonExistent { |
1958 | | StringRef Base, File; |
1959 | | vfs::FileSystem &VFS; |
1960 | | |
1961 | | public: |
1962 | | FilterNonExistent(StringRef Base, StringRef File, vfs::FileSystem &VFS) |
1963 | 383 | : Base(Base), File(File), VFS(VFS) {} |
1964 | 22.9k | bool operator()(const Multilib &M) { |
1965 | 22.9k | return !VFS.exists(Base + M.gccSuffix() + File); |
1966 | 22.9k | } |
1967 | | }; |
1968 | | } // end anonymous namespace |
1969 | | |
1970 | | static void addMultilibFlag(bool Enabled, const char *const Flag, |
1971 | 3.93k | std::vector<std::string> &Flags) { |
1972 | 3.93k | if (Enabled) |
1973 | 1.14k | Flags.push_back(std::string("+") + Flag); |
1974 | 3.93k | else |
1975 | 2.79k | Flags.push_back(std::string("-") + Flag); |
1976 | 3.93k | } |
1977 | | |
1978 | 381 | static bool isArmOrThumbArch(llvm::Triple::ArchType Arch) { |
1979 | 356 | return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb; |
1980 | 381 | } |
1981 | | |
1982 | 4.97k | static bool isMipsArch(llvm::Triple::ArchType Arch) { |
1983 | 4.26k | return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel || |
1984 | 3.89k | Arch == llvm::Triple::mips643.89k || Arch == llvm::Triple::mips64el3.64k ; |
1985 | 4.97k | } |
1986 | | |
1987 | 187 | static bool isMips32(llvm::Triple::ArchType Arch) { |
1988 | 131 | return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel; |
1989 | 187 | } |
1990 | | |
1991 | 187 | static bool isMips64(llvm::Triple::ArchType Arch) { |
1992 | 154 | return Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el; |
1993 | 187 | } |
1994 | | |
1995 | 374 | static bool isMipsEL(llvm::Triple::ArchType Arch) { |
1996 | 248 | return Arch == llvm::Triple::mipsel || Arch == llvm::Triple::mips64el; |
1997 | 374 | } |
1998 | | |
1999 | 187 | static bool isMips16(const ArgList &Args) { |
2000 | 187 | Arg *A = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16); |
2001 | 24 | return A && A->getOption().matches(options::OPT_mips16); |
2002 | 187 | } |
2003 | | |
2004 | 187 | static bool isMicroMips(const ArgList &Args) { |
2005 | 187 | Arg *A = Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips); |
2006 | 20 | return A && A->getOption().matches(options::OPT_mmicromips); |
2007 | 187 | } |
2008 | | |
2009 | | namespace { |
2010 | | struct DetectedMultilibs { |
2011 | | /// The set of multilibs that the detected installation supports. |
2012 | | MultilibSet Multilibs; |
2013 | | |
2014 | | /// The primary multilib appropriate for the given flags. |
2015 | | Multilib SelectedMultilib; |
2016 | | |
2017 | | /// On Biarch systems, this corresponds to the default multilib when |
2018 | | /// targeting the non-default multilib. Otherwise, it is empty. |
2019 | | llvm::Optional<Multilib> BiarchSibling; |
2020 | | }; |
2021 | | } // end anonymous namespace |
2022 | | |
2023 | 3.95k | static Multilib makeMultilib(StringRef commonSuffix) { |
2024 | 3.95k | return Multilib(commonSuffix, commonSuffix, commonSuffix); |
2025 | 3.95k | } |
2026 | | |
2027 | | static bool findMipsCsMultilibs(const Multilib::flags_list &Flags, |
2028 | | FilterNonExistent &NonExistent, |
2029 | 39 | DetectedMultilibs &Result) { |
2030 | 39 | // Check for Code Sourcery toolchain multilibs |
2031 | 39 | MultilibSet CSMipsMultilibs; |
2032 | 39 | { |
2033 | 39 | auto MArchMips16 = makeMultilib("/mips16").flag("+m32").flag("+mips16"); |
2034 | 39 | |
2035 | 39 | auto MArchMicroMips = |
2036 | 39 | makeMultilib("/micromips").flag("+m32").flag("+mmicromips"); |
2037 | 39 | |
2038 | 39 | auto MArchDefault = makeMultilib("").flag("-mips16").flag("-mmicromips"); |
2039 | 39 | |
2040 | 39 | auto UCLibc = makeMultilib("/uclibc").flag("+muclibc"); |
2041 | 39 | |
2042 | 39 | auto SoftFloat = makeMultilib("/soft-float").flag("+msoft-float"); |
2043 | 39 | |
2044 | 39 | auto Nan2008 = makeMultilib("/nan2008").flag("+mnan=2008"); |
2045 | 39 | |
2046 | 39 | auto DefaultFloat = |
2047 | 39 | makeMultilib("").flag("-msoft-float").flag("-mnan=2008"); |
2048 | 39 | |
2049 | 39 | auto BigEndian = makeMultilib("").flag("+EB").flag("-EL"); |
2050 | 39 | |
2051 | 39 | auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB"); |
2052 | 39 | |
2053 | 39 | // Note that this one's osSuffix is "" |
2054 | 39 | auto MAbi64 = makeMultilib("") |
2055 | 39 | .gccSuffix("/64") |
2056 | 39 | .includeSuffix("/64") |
2057 | 39 | .flag("+mabi=n64") |
2058 | 39 | .flag("-mabi=n32") |
2059 | 39 | .flag("-m32"); |
2060 | 39 | |
2061 | 39 | CSMipsMultilibs = |
2062 | 39 | MultilibSet() |
2063 | 39 | .Either(MArchMips16, MArchMicroMips, MArchDefault) |
2064 | 39 | .Maybe(UCLibc) |
2065 | 39 | .Either(SoftFloat, Nan2008, DefaultFloat) |
2066 | 39 | .FilterOut("/micromips/nan2008") |
2067 | 39 | .FilterOut("/mips16/nan2008") |
2068 | 39 | .Either(BigEndian, LittleEndian) |
2069 | 39 | .Maybe(MAbi64) |
2070 | 39 | .FilterOut("/mips16.*/64") |
2071 | 39 | .FilterOut("/micromips.*/64") |
2072 | 39 | .FilterOut(NonExistent) |
2073 | 25 | .setIncludeDirsCallback([](const Multilib &M) { |
2074 | 25 | std::vector<std::string> Dirs({"/include"}); |
2075 | 25 | if (StringRef(M.includeSuffix()).startswith("/uclibc")) |
2076 | 6 | Dirs.push_back( |
2077 | 6 | "/../../../../mips-linux-gnu/libc/uclibc/usr/include"); |
2078 | 25 | else |
2079 | 19 | Dirs.push_back("/../../../../mips-linux-gnu/libc/usr/include"); |
2080 | 25 | return Dirs; |
2081 | 25 | }); |
2082 | 39 | } |
2083 | 39 | |
2084 | 39 | MultilibSet DebianMipsMultilibs; |
2085 | 39 | { |
2086 | 39 | Multilib MAbiN32 = |
2087 | 39 | Multilib().gccSuffix("/n32").includeSuffix("/n32").flag("+mabi=n32"); |
2088 | 39 | |
2089 | 39 | Multilib M64 = Multilib() |
2090 | 39 | .gccSuffix("/64") |
2091 | 39 | .includeSuffix("/64") |
2092 | 39 | .flag("+m64") |
2093 | 39 | .flag("-m32") |
2094 | 39 | .flag("-mabi=n32"); |
2095 | 39 | |
2096 | 39 | Multilib M32 = Multilib().flag("-m64").flag("+m32").flag("-mabi=n32"); |
2097 | 39 | |
2098 | 39 | DebianMipsMultilibs = |
2099 | 39 | MultilibSet().Either(M32, M64, MAbiN32).FilterOut(NonExistent); |
2100 | 39 | } |
2101 | 39 | |
2102 | 39 | // Sort candidates. Toolchain that best meets the directories tree goes first. |
2103 | 39 | // Then select the first toolchains matches command line flags. |
2104 | 39 | MultilibSet *Candidates[] = {&CSMipsMultilibs, &DebianMipsMultilibs}; |
2105 | 39 | if (CSMipsMultilibs.size() < DebianMipsMultilibs.size()) |
2106 | 9 | std::iter_swap(Candidates, Candidates + 1); |
2107 | 44 | for (const MultilibSet *Candidate : Candidates) { |
2108 | 44 | if (Candidate->select(Flags, Result.SelectedMultilib)44 ) {35 |
2109 | 35 | if (Candidate == &DebianMipsMultilibs) |
2110 | 10 | Result.BiarchSibling = Multilib(); |
2111 | 35 | Result.Multilibs = *Candidate; |
2112 | 35 | return true; |
2113 | 35 | } |
2114 | 44 | } |
2115 | 4 | return false; |
2116 | 39 | } |
2117 | | |
2118 | | static bool findMipsAndroidMultilibs(vfs::FileSystem &VFS, StringRef Path, |
2119 | | const Multilib::flags_list &Flags, |
2120 | | FilterNonExistent &NonExistent, |
2121 | 8 | DetectedMultilibs &Result) { |
2122 | 8 | |
2123 | 8 | MultilibSet AndroidMipsMultilibs = |
2124 | 8 | MultilibSet() |
2125 | 8 | .Maybe(Multilib("/mips-r2").flag("+march=mips32r2")) |
2126 | 8 | .Maybe(Multilib("/mips-r6").flag("+march=mips32r6")) |
2127 | 8 | .FilterOut(NonExistent); |
2128 | 8 | |
2129 | 8 | MultilibSet AndroidMipselMultilibs = |
2130 | 8 | MultilibSet() |
2131 | 8 | .Either(Multilib().flag("+march=mips32"), |
2132 | 8 | Multilib("/mips-r2", "", "/mips-r2").flag("+march=mips32r2"), |
2133 | 8 | Multilib("/mips-r6", "", "/mips-r6").flag("+march=mips32r6")) |
2134 | 8 | .FilterOut(NonExistent); |
2135 | 8 | |
2136 | 8 | MultilibSet AndroidMips64elMultilibs = |
2137 | 8 | MultilibSet() |
2138 | 8 | .Either( |
2139 | 8 | Multilib().flag("+march=mips64r6"), |
2140 | 8 | Multilib("/32/mips-r1", "", "/mips-r1").flag("+march=mips32"), |
2141 | 8 | Multilib("/32/mips-r2", "", "/mips-r2").flag("+march=mips32r2"), |
2142 | 8 | Multilib("/32/mips-r6", "", "/mips-r6").flag("+march=mips32r6")) |
2143 | 8 | .FilterOut(NonExistent); |
2144 | 8 | |
2145 | 8 | MultilibSet *MS = &AndroidMipsMultilibs; |
2146 | 8 | if (VFS.exists(Path + "/mips-r6")) |
2147 | 3 | MS = &AndroidMipselMultilibs; |
2148 | 5 | else if (5 VFS.exists(Path + "/32")5 ) |
2149 | 2 | MS = &AndroidMips64elMultilibs; |
2150 | 8 | if (MS->select(Flags, Result.SelectedMultilib)8 ) {8 |
2151 | 8 | Result.Multilibs = *MS; |
2152 | 8 | return true; |
2153 | 8 | } |
2154 | 0 | return false; |
2155 | 8 | } |
2156 | | |
2157 | | static bool findMipsMuslMultilibs(const Multilib::flags_list &Flags, |
2158 | | FilterNonExistent &NonExistent, |
2159 | 2 | DetectedMultilibs &Result) { |
2160 | 2 | // Musl toolchain multilibs |
2161 | 2 | MultilibSet MuslMipsMultilibs; |
2162 | 2 | { |
2163 | 2 | auto MArchMipsR2 = makeMultilib("") |
2164 | 2 | .osSuffix("/mips-r2-hard-musl") |
2165 | 2 | .flag("+EB") |
2166 | 2 | .flag("-EL") |
2167 | 2 | .flag("+march=mips32r2"); |
2168 | 2 | |
2169 | 2 | auto MArchMipselR2 = makeMultilib("/mipsel-r2-hard-musl") |
2170 | 2 | .flag("-EB") |
2171 | 2 | .flag("+EL") |
2172 | 2 | .flag("+march=mips32r2"); |
2173 | 2 | |
2174 | 2 | MuslMipsMultilibs = MultilibSet().Either(MArchMipsR2, MArchMipselR2); |
2175 | 2 | |
2176 | 2 | // Specify the callback that computes the include directories. |
2177 | 2 | MuslMipsMultilibs.setIncludeDirsCallback([](const Multilib &M) { |
2178 | 2 | return std::vector<std::string>( |
2179 | 2 | {"/../sysroot" + M.osSuffix() + "/usr/include"}); |
2180 | 2 | }); |
2181 | 2 | } |
2182 | 2 | if (MuslMipsMultilibs.select(Flags, Result.SelectedMultilib)2 ) {2 |
2183 | 2 | Result.Multilibs = MuslMipsMultilibs; |
2184 | 2 | return true; |
2185 | 2 | } |
2186 | 0 | return false; |
2187 | 2 | } |
2188 | | |
2189 | | static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags, |
2190 | | FilterNonExistent &NonExistent, |
2191 | 120 | DetectedMultilibs &Result) { |
2192 | 120 | // CodeScape MTI toolchain v1.2 and early. |
2193 | 120 | MultilibSet MtiMipsMultilibsV1; |
2194 | 120 | { |
2195 | 120 | auto MArchMips32 = makeMultilib("/mips32") |
2196 | 120 | .flag("+m32") |
2197 | 120 | .flag("-m64") |
2198 | 120 | .flag("-mmicromips") |
2199 | 120 | .flag("+march=mips32"); |
2200 | 120 | |
2201 | 120 | auto MArchMicroMips = makeMultilib("/micromips") |
2202 | 120 | .flag("+m32") |
2203 | 120 | .flag("-m64") |
2204 | 120 | .flag("+mmicromips"); |
2205 | 120 | |
2206 | 120 | auto MArchMips64r2 = makeMultilib("/mips64r2") |
2207 | 120 | .flag("-m32") |
2208 | 120 | .flag("+m64") |
2209 | 120 | .flag("+march=mips64r2"); |
2210 | 120 | |
2211 | 120 | auto MArchMips64 = makeMultilib("/mips64").flag("-m32").flag("+m64").flag( |
2212 | 120 | "-march=mips64r2"); |
2213 | 120 | |
2214 | 120 | auto MArchDefault = makeMultilib("") |
2215 | 120 | .flag("+m32") |
2216 | 120 | .flag("-m64") |
2217 | 120 | .flag("-mmicromips") |
2218 | 120 | .flag("+march=mips32r2"); |
2219 | 120 | |
2220 | 120 | auto Mips16 = makeMultilib("/mips16").flag("+mips16"); |
2221 | 120 | |
2222 | 120 | auto UCLibc = makeMultilib("/uclibc").flag("+muclibc"); |
2223 | 120 | |
2224 | 120 | auto MAbi64 = |
2225 | 120 | makeMultilib("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32"); |
2226 | 120 | |
2227 | 120 | auto BigEndian = makeMultilib("").flag("+EB").flag("-EL"); |
2228 | 120 | |
2229 | 120 | auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB"); |
2230 | 120 | |
2231 | 120 | auto SoftFloat = makeMultilib("/sof").flag("+msoft-float"); |
2232 | 120 | |
2233 | 120 | auto Nan2008 = makeMultilib("/nan2008").flag("+mnan=2008"); |
2234 | 120 | |
2235 | 120 | MtiMipsMultilibsV1 = |
2236 | 120 | MultilibSet() |
2237 | 120 | .Either(MArchMips32, MArchMicroMips, MArchMips64r2, MArchMips64, |
2238 | 120 | MArchDefault) |
2239 | 120 | .Maybe(UCLibc) |
2240 | 120 | .Maybe(Mips16) |
2241 | 120 | .FilterOut("/mips64/mips16") |
2242 | 120 | .FilterOut("/mips64r2/mips16") |
2243 | 120 | .FilterOut("/micromips/mips16") |
2244 | 120 | .Maybe(MAbi64) |
2245 | 120 | .FilterOut("/micromips/64") |
2246 | 120 | .FilterOut("/mips32/64") |
2247 | 120 | .FilterOut("^/64") |
2248 | 120 | .FilterOut("/mips16/64") |
2249 | 120 | .Either(BigEndian, LittleEndian) |
2250 | 120 | .Maybe(SoftFloat) |
2251 | 120 | .Maybe(Nan2008) |
2252 | 120 | .FilterOut(".*sof/nan2008") |
2253 | 120 | .FilterOut(NonExistent) |
2254 | 104 | .setIncludeDirsCallback([](const Multilib &M) { |
2255 | 104 | std::vector<std::string> Dirs({"/include"}); |
2256 | 104 | if (StringRef(M.includeSuffix()).startswith("/uclibc")) |
2257 | 6 | Dirs.push_back("/../../../../sysroot/uclibc/usr/include"); |
2258 | 104 | else |
2259 | 98 | Dirs.push_back("/../../../../sysroot/usr/include"); |
2260 | 104 | return Dirs; |
2261 | 104 | }); |
2262 | 120 | } |
2263 | 120 | |
2264 | 120 | // CodeScape IMG toolchain starting from v1.3. |
2265 | 120 | MultilibSet MtiMipsMultilibsV2; |
2266 | 120 | { |
2267 | 120 | auto BeHard = makeMultilib("/mips-r2-hard") |
2268 | 120 | .flag("+EB") |
2269 | 120 | .flag("-msoft-float") |
2270 | 120 | .flag("-mnan=2008") |
2271 | 120 | .flag("-muclibc"); |
2272 | 120 | auto BeSoft = makeMultilib("/mips-r2-soft") |
2273 | 120 | .flag("+EB") |
2274 | 120 | .flag("+msoft-float") |
2275 | 120 | .flag("-mnan=2008"); |
2276 | 120 | auto ElHard = makeMultilib("/mipsel-r2-hard") |
2277 | 120 | .flag("+EL") |
2278 | 120 | .flag("-msoft-float") |
2279 | 120 | .flag("-mnan=2008") |
2280 | 120 | .flag("-muclibc"); |
2281 | 120 | auto ElSoft = makeMultilib("/mipsel-r2-soft") |
2282 | 120 | .flag("+EL") |
2283 | 120 | .flag("+msoft-float") |
2284 | 120 | .flag("-mnan=2008") |
2285 | 120 | .flag("-mmicromips"); |
2286 | 120 | auto BeHardNan = makeMultilib("/mips-r2-hard-nan2008") |
2287 | 120 | .flag("+EB") |
2288 | 120 | .flag("-msoft-float") |
2289 | 120 | .flag("+mnan=2008") |
2290 | 120 | .flag("-muclibc"); |
2291 | 120 | auto ElHardNan = makeMultilib("/mipsel-r2-hard-nan2008") |
2292 | 120 | .flag("+EL") |
2293 | 120 | .flag("-msoft-float") |
2294 | 120 | .flag("+mnan=2008") |
2295 | 120 | .flag("-muclibc") |
2296 | 120 | .flag("-mmicromips"); |
2297 | 120 | auto BeHardNanUclibc = makeMultilib("/mips-r2-hard-nan2008-uclibc") |
2298 | 120 | .flag("+EB") |
2299 | 120 | .flag("-msoft-float") |
2300 | 120 | .flag("+mnan=2008") |
2301 | 120 | .flag("+muclibc"); |
2302 | 120 | auto ElHardNanUclibc = makeMultilib("/mipsel-r2-hard-nan2008-uclibc") |
2303 | 120 | .flag("+EL") |
2304 | 120 | .flag("-msoft-float") |
2305 | 120 | .flag("+mnan=2008") |
2306 | 120 | .flag("+muclibc"); |
2307 | 120 | auto BeHardUclibc = makeMultilib("/mips-r2-hard-uclibc") |
2308 | 120 | .flag("+EB") |
2309 | 120 | .flag("-msoft-float") |
2310 | 120 | .flag("-mnan=2008") |
2311 | 120 | .flag("+muclibc"); |
2312 | 120 | auto ElHardUclibc = makeMultilib("/mipsel-r2-hard-uclibc") |
2313 | 120 | .flag("+EL") |
2314 | 120 | .flag("-msoft-float") |
2315 | 120 | .flag("-mnan=2008") |
2316 | 120 | .flag("+muclibc"); |
2317 | 120 | auto ElMicroHardNan = makeMultilib("/micromipsel-r2-hard-nan2008") |
2318 | 120 | .flag("+EL") |
2319 | 120 | .flag("-msoft-float") |
2320 | 120 | .flag("+mnan=2008") |
2321 | 120 | .flag("+mmicromips"); |
2322 | 120 | auto ElMicroSoft = makeMultilib("/micromipsel-r2-soft") |
2323 | 120 | .flag("+EL") |
2324 | 120 | .flag("+msoft-float") |
2325 | 120 | .flag("-mnan=2008") |
2326 | 120 | .flag("+mmicromips"); |
2327 | 120 | |
2328 | 120 | auto O32 = |
2329 | 120 | makeMultilib("/lib").osSuffix("").flag("-mabi=n32").flag("-mabi=n64"); |
2330 | 120 | auto N32 = |
2331 | 120 | makeMultilib("/lib32").osSuffix("").flag("+mabi=n32").flag("-mabi=n64"); |
2332 | 120 | auto N64 = |
2333 | 120 | makeMultilib("/lib64").osSuffix("").flag("-mabi=n32").flag("+mabi=n64"); |
2334 | 120 | |
2335 | 120 | MtiMipsMultilibsV2 = |
2336 | 120 | MultilibSet() |
2337 | 120 | .Either({BeHard, BeSoft, ElHard, ElSoft, BeHardNan, ElHardNan, |
2338 | 120 | BeHardNanUclibc, ElHardNanUclibc, BeHardUclibc, |
2339 | 120 | ElHardUclibc, ElMicroHardNan, ElMicroSoft}) |
2340 | 120 | .Either(O32, N32, N64) |
2341 | 120 | .FilterOut(NonExistent) |
2342 | 16 | .setIncludeDirsCallback([](const Multilib &M) { |
2343 | 16 | return std::vector<std::string>({"/../../../../sysroot" + |
2344 | 16 | M.includeSuffix() + |
2345 | 16 | "/../usr/include"}); |
2346 | 16 | }) |
2347 | 16 | .setFilePathsCallback([](const Multilib &M) { |
2348 | 16 | return std::vector<std::string>( |
2349 | 16 | {"/../../../../mips-mti-linux-gnu/lib" + M.gccSuffix()}); |
2350 | 16 | }); |
2351 | 120 | } |
2352 | 136 | for (auto Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) { |
2353 | 136 | if (Candidate->select(Flags, Result.SelectedMultilib)136 ) {120 |
2354 | 120 | Result.Multilibs = *Candidate; |
2355 | 120 | return true; |
2356 | 120 | } |
2357 | 136 | } |
2358 | 0 | return false; |
2359 | 120 | } |
2360 | | |
2361 | | static bool findMipsImgMultilibs(const Multilib::flags_list &Flags, |
2362 | | FilterNonExistent &NonExistent, |
2363 | 18 | DetectedMultilibs &Result) { |
2364 | 18 | // CodeScape IMG toolchain v1.2 and early. |
2365 | 18 | MultilibSet ImgMultilibsV1; |
2366 | 18 | { |
2367 | 18 | auto Mips64r6 = makeMultilib("/mips64r6").flag("+m64").flag("-m32"); |
2368 | 18 | |
2369 | 18 | auto LittleEndian = makeMultilib("/el").flag("+EL").flag("-EB"); |
2370 | 18 | |
2371 | 18 | auto MAbi64 = |
2372 | 18 | makeMultilib("/64").flag("+mabi=n64").flag("-mabi=n32").flag("-m32"); |
2373 | 18 | |
2374 | 18 | ImgMultilibsV1 = |
2375 | 18 | MultilibSet() |
2376 | 18 | .Maybe(Mips64r6) |
2377 | 18 | .Maybe(MAbi64) |
2378 | 18 | .Maybe(LittleEndian) |
2379 | 18 | .FilterOut(NonExistent) |
2380 | 6 | .setIncludeDirsCallback([](const Multilib &M) { |
2381 | 6 | return std::vector<std::string>( |
2382 | 6 | {"/include", "/../../../../sysroot/usr/include"}); |
2383 | 6 | }); |
2384 | 18 | } |
2385 | 18 | |
2386 | 18 | // CodeScape IMG toolchain starting from v1.3. |
2387 | 18 | MultilibSet ImgMultilibsV2; |
2388 | 18 | { |
2389 | 18 | auto BeHard = makeMultilib("/mips-r6-hard") |
2390 | 18 | .flag("+EB") |
2391 | 18 | .flag("-msoft-float") |
2392 | 18 | .flag("-mmicromips"); |
2393 | 18 | auto BeSoft = makeMultilib("/mips-r6-soft") |
2394 | 18 | .flag("+EB") |
2395 | 18 | .flag("+msoft-float") |
2396 | 18 | .flag("-mmicromips"); |
2397 | 18 | auto ElHard = makeMultilib("/mipsel-r6-hard") |
2398 | 18 | .flag("+EL") |
2399 | 18 | .flag("-msoft-float") |
2400 | 18 | .flag("-mmicromips"); |
2401 | 18 | auto ElSoft = makeMultilib("/mipsel-r6-soft") |
2402 | 18 | .flag("+EL") |
2403 | 18 | .flag("+msoft-float") |
2404 | 18 | .flag("-mmicromips"); |
2405 | 18 | auto BeMicroHard = makeMultilib("/micromips-r6-hard") |
2406 | 18 | .flag("+EB") |
2407 | 18 | .flag("-msoft-float") |
2408 | 18 | .flag("+mmicromips"); |
2409 | 18 | auto BeMicroSoft = makeMultilib("/micromips-r6-soft") |
2410 | 18 | .flag("+EB") |
2411 | 18 | .flag("+msoft-float") |
2412 | 18 | .flag("+mmicromips"); |
2413 | 18 | auto ElMicroHard = makeMultilib("/micromipsel-r6-hard") |
2414 | 18 | .flag("+EL") |
2415 | 18 | .flag("-msoft-float") |
2416 | 18 | .flag("+mmicromips"); |
2417 | 18 | auto ElMicroSoft = makeMultilib("/micromipsel-r6-soft") |
2418 | 18 | .flag("+EL") |
2419 | 18 | .flag("+msoft-float") |
2420 | 18 | .flag("+mmicromips"); |
2421 | 18 | |
2422 | 18 | auto O32 = |
2423 | 18 | makeMultilib("/lib").osSuffix("").flag("-mabi=n32").flag("-mabi=n64"); |
2424 | 18 | auto N32 = |
2425 | 18 | makeMultilib("/lib32").osSuffix("").flag("+mabi=n32").flag("-mabi=n64"); |
2426 | 18 | auto N64 = |
2427 | 18 | makeMultilib("/lib64").osSuffix("").flag("-mabi=n32").flag("+mabi=n64"); |
2428 | 18 | |
2429 | 18 | ImgMultilibsV2 = |
2430 | 18 | MultilibSet() |
2431 | 18 | .Either({BeHard, BeSoft, ElHard, ElSoft, BeMicroHard, BeMicroSoft, |
2432 | 18 | ElMicroHard, ElMicroSoft}) |
2433 | 18 | .Either(O32, N32, N64) |
2434 | 18 | .FilterOut(NonExistent) |
2435 | 12 | .setIncludeDirsCallback([](const Multilib &M) { |
2436 | 12 | return std::vector<std::string>({"/../../../../sysroot" + |
2437 | 12 | M.includeSuffix() + |
2438 | 12 | "/../usr/include"}); |
2439 | 12 | }) |
2440 | 12 | .setFilePathsCallback([](const Multilib &M) { |
2441 | 12 | return std::vector<std::string>( |
2442 | 12 | {"/../../../../mips-img-linux-gnu/lib" + M.gccSuffix()}); |
2443 | 12 | }); |
2444 | 18 | } |
2445 | 30 | for (auto Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) { |
2446 | 30 | if (Candidate->select(Flags, Result.SelectedMultilib)30 ) {18 |
2447 | 18 | Result.Multilibs = *Candidate; |
2448 | 18 | return true; |
2449 | 18 | } |
2450 | 30 | } |
2451 | 0 | return false; |
2452 | 18 | } |
2453 | | |
2454 | | static bool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple, |
2455 | | StringRef Path, const ArgList &Args, |
2456 | 187 | DetectedMultilibs &Result) { |
2457 | 187 | FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); |
2458 | 187 | |
2459 | 187 | StringRef CPUName; |
2460 | 187 | StringRef ABIName; |
2461 | 187 | tools::mips::getMipsCPUAndABI(Args, TargetTriple, CPUName, ABIName); |
2462 | 187 | |
2463 | 187 | llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); |
2464 | 187 | |
2465 | 187 | Multilib::flags_list Flags; |
2466 | 187 | addMultilibFlag(isMips32(TargetArch), "m32", Flags); |
2467 | 187 | addMultilibFlag(isMips64(TargetArch), "m64", Flags); |
2468 | 187 | addMultilibFlag(isMips16(Args), "mips16", Flags); |
2469 | 187 | addMultilibFlag(CPUName == "mips32", "march=mips32", Flags); |
2470 | 106 | addMultilibFlag(CPUName == "mips32r2" || CPUName == "mips32r3" || |
2471 | 105 | CPUName == "mips32r5"105 || CPUName == "p5600"104 , |
2472 | 187 | "march=mips32r2", Flags); |
2473 | 187 | addMultilibFlag(CPUName == "mips32r6", "march=mips32r6", Flags); |
2474 | 187 | addMultilibFlag(CPUName == "mips64", "march=mips64", Flags); |
2475 | 147 | addMultilibFlag(CPUName == "mips64r2" || CPUName == "mips64r3" || |
2476 | 146 | CPUName == "mips64r5"146 || CPUName == "octeon"145 , |
2477 | 187 | "march=mips64r2", Flags); |
2478 | 187 | addMultilibFlag(CPUName == "mips64r6", "march=mips64r6", Flags); |
2479 | 187 | addMultilibFlag(isMicroMips(Args), "mmicromips", Flags); |
2480 | 187 | addMultilibFlag(tools::mips::isUCLibc(Args), "muclibc", Flags); |
2481 | 187 | addMultilibFlag(tools::mips::isNaN2008(Args, TargetTriple), "mnan=2008", |
2482 | 187 | Flags); |
2483 | 187 | addMultilibFlag(ABIName == "n32", "mabi=n32", Flags); |
2484 | 187 | addMultilibFlag(ABIName == "n64", "mabi=n64", Flags); |
2485 | 187 | addMultilibFlag(isSoftFloatABI(Args), "msoft-float", Flags); |
2486 | 187 | addMultilibFlag(!isSoftFloatABI(Args), "mhard-float", Flags); |
2487 | 187 | addMultilibFlag(isMipsEL(TargetArch), "EL", Flags); |
2488 | 187 | addMultilibFlag(!isMipsEL(TargetArch), "EB", Flags); |
2489 | 187 | |
2490 | 187 | if (TargetTriple.isAndroid()) |
2491 | 8 | return findMipsAndroidMultilibs(D.getVFS(), Path, Flags, NonExistent, |
2492 | 8 | Result); |
2493 | 187 | |
2494 | 179 | if (179 TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&179 |
2495 | 122 | TargetTriple.getOS() == llvm::Triple::Linux && |
2496 | 122 | TargetTriple.getEnvironment() == llvm::Triple::UnknownEnvironment) |
2497 | 2 | return findMipsMuslMultilibs(Flags, NonExistent, Result); |
2498 | 179 | |
2499 | 177 | if (177 TargetTriple.getVendor() == llvm::Triple::MipsTechnologies &&177 |
2500 | 120 | TargetTriple.getOS() == llvm::Triple::Linux && |
2501 | 120 | TargetTriple.getEnvironment() == llvm::Triple::GNU) |
2502 | 120 | return findMipsMtiMultilibs(Flags, NonExistent, Result); |
2503 | 177 | |
2504 | 57 | if (57 TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies &&57 |
2505 | 18 | TargetTriple.getOS() == llvm::Triple::Linux && |
2506 | 18 | TargetTriple.getEnvironment() == llvm::Triple::GNU) |
2507 | 18 | return findMipsImgMultilibs(Flags, NonExistent, Result); |
2508 | 57 | |
2509 | 39 | if (39 findMipsCsMultilibs(Flags, NonExistent, Result)39 ) |
2510 | 35 | return true; |
2511 | 39 | |
2512 | 39 | // Fallback to the regular toolchain-tree structure. |
2513 | 4 | Multilib Default; |
2514 | 4 | Result.Multilibs.push_back(Default); |
2515 | 4 | Result.Multilibs.FilterOut(NonExistent); |
2516 | 4 | |
2517 | 4 | if (Result.Multilibs.select(Flags, Result.SelectedMultilib)4 ) {4 |
2518 | 4 | Result.BiarchSibling = Multilib(); |
2519 | 4 | return true; |
2520 | 4 | } |
2521 | 4 | |
2522 | 0 | return false; |
2523 | 4 | } |
2524 | | |
2525 | | static void findAndroidArmMultilibs(const Driver &D, |
2526 | | const llvm::Triple &TargetTriple, |
2527 | | StringRef Path, const ArgList &Args, |
2528 | 16 | DetectedMultilibs &Result) { |
2529 | 16 | // Find multilibs with subdirectories like armv7-a, thumb, armv7-a/thumb. |
2530 | 16 | FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); |
2531 | 16 | Multilib ArmV7Multilib = makeMultilib("/armv7-a") |
2532 | 16 | .flag("+armv7") |
2533 | 16 | .flag("-thumb"); |
2534 | 16 | Multilib ThumbMultilib = makeMultilib("/thumb") |
2535 | 16 | .flag("-armv7") |
2536 | 16 | .flag("+thumb"); |
2537 | 16 | Multilib ArmV7ThumbMultilib = makeMultilib("/armv7-a/thumb") |
2538 | 16 | .flag("+armv7") |
2539 | 16 | .flag("+thumb"); |
2540 | 16 | Multilib DefaultMultilib = makeMultilib("") |
2541 | 16 | .flag("-armv7") |
2542 | 16 | .flag("-thumb"); |
2543 | 16 | MultilibSet AndroidArmMultilibs = |
2544 | 16 | MultilibSet() |
2545 | 16 | .Either(ThumbMultilib, ArmV7Multilib, |
2546 | 16 | ArmV7ThumbMultilib, DefaultMultilib) |
2547 | 16 | .FilterOut(NonExistent); |
2548 | 16 | |
2549 | 16 | Multilib::flags_list Flags; |
2550 | 16 | llvm::StringRef Arch = Args.getLastArgValue(options::OPT_march_EQ); |
2551 | 16 | bool IsArmArch = TargetTriple.getArch() == llvm::Triple::arm; |
2552 | 16 | bool IsThumbArch = TargetTriple.getArch() == llvm::Triple::thumb; |
2553 | 16 | bool IsV7SubArch = TargetTriple.getSubArch() == llvm::Triple::ARMSubArch_v7; |
2554 | 16 | bool IsThumbMode = IsThumbArch || |
2555 | 16 | Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, false) || |
2556 | 13 | (IsArmArch && 13 llvm::ARM::parseArchISA(Arch) == llvm::ARM::IK_THUMB13 ); |
2557 | 0 | bool IsArmV7Mode = (IsArmArch || IsThumbArch) && |
2558 | 16 | (llvm::ARM::parseArchVersion(Arch) == 7 || |
2559 | 12 | (IsArmArch && 12 Arch == ""12 && IsV7SubArch12 )); |
2560 | 16 | addMultilibFlag(IsArmV7Mode, "armv7", Flags); |
2561 | 16 | addMultilibFlag(IsThumbMode, "thumb", Flags); |
2562 | 16 | |
2563 | 16 | if (AndroidArmMultilibs.select(Flags, Result.SelectedMultilib)) |
2564 | 16 | Result.Multilibs = AndroidArmMultilibs; |
2565 | 16 | } |
2566 | | |
2567 | | static bool findBiarchMultilibs(const Driver &D, |
2568 | | const llvm::Triple &TargetTriple, |
2569 | | StringRef Path, const ArgList &Args, |
2570 | | bool NeedsBiarchSuffix, |
2571 | 180 | DetectedMultilibs &Result) { |
2572 | 180 | // Some versions of SUSE and Fedora on ppc64 put 32-bit libs |
2573 | 180 | // in what would normally be GCCInstallPath and put the 64-bit |
2574 | 180 | // libs in a subdirectory named 64. The simple logic we follow is that |
2575 | 180 | // *if* there is a subdirectory of the right name with crtbegin.o in it, |
2576 | 180 | // we use that. If not, and if not a biarch triple alias, we look for |
2577 | 180 | // crtbegin.o without the subdirectory. |
2578 | 180 | |
2579 | 180 | Multilib Default; |
2580 | 180 | Multilib Alt64 = Multilib() |
2581 | 180 | .gccSuffix("/64") |
2582 | 180 | .includeSuffix("/64") |
2583 | 180 | .flag("-m32") |
2584 | 180 | .flag("+m64") |
2585 | 180 | .flag("-mx32"); |
2586 | 180 | Multilib Alt32 = Multilib() |
2587 | 180 | .gccSuffix("/32") |
2588 | 180 | .includeSuffix("/32") |
2589 | 180 | .flag("+m32") |
2590 | 180 | .flag("-m64") |
2591 | 180 | .flag("-mx32"); |
2592 | 180 | Multilib Altx32 = Multilib() |
2593 | 180 | .gccSuffix("/x32") |
2594 | 180 | .includeSuffix("/x32") |
2595 | 180 | .flag("-m32") |
2596 | 180 | .flag("-m64") |
2597 | 180 | .flag("+mx32"); |
2598 | 180 | |
2599 | 180 | // GCC toolchain for IAMCU doesn't have crtbegin.o, so look for libgcc.a. |
2600 | 180 | FilterNonExistent NonExistent( |
2601 | 180 | Path, TargetTriple.isOSIAMCU() ? "/libgcc.a"0 : "/crtbegin.o"180 , D.getVFS()); |
2602 | 180 | |
2603 | 180 | // Determine default multilib from: 32, 64, x32 |
2604 | 180 | // Also handle cases such as 64 on 32, 32 on 64, etc. |
2605 | 180 | enum { UNKNOWN, WANT32, WANT64, WANTX32 } Want = UNKNOWN; |
2606 | 180 | const bool IsX32 = TargetTriple.getEnvironment() == llvm::Triple::GNUX32; |
2607 | 180 | if (TargetTriple.isArch32Bit() && 180 !NonExistent(Alt32)87 ) |
2608 | 8 | Want = WANT64; |
2609 | 172 | else if (172 TargetTriple.isArch64Bit() && 172 IsX3293 && !NonExistent(Altx32)11 ) |
2610 | 7 | Want = WANT64; |
2611 | 165 | else if (165 TargetTriple.isArch64Bit() && 165 !IsX3286 && !NonExistent(Alt64)82 ) |
2612 | 5 | Want = WANT32; |
2613 | 160 | else { |
2614 | 160 | if (TargetTriple.isArch32Bit()) |
2615 | 79 | Want = NeedsBiarchSuffix ? 79 WANT644 : WANT3275 ; |
2616 | 81 | else if (81 IsX3281 ) |
2617 | 4 | Want = NeedsBiarchSuffix ? 4 WANT640 : WANTX324 ; |
2618 | 81 | else |
2619 | 77 | Want = NeedsBiarchSuffix ? 77 WANT321 : WANT6476 ; |
2620 | 160 | } |
2621 | 180 | |
2622 | 180 | if (Want == WANT32) |
2623 | 81 | Default.flag("+m32").flag("-m64").flag("-mx32"); |
2624 | 99 | else if (99 Want == WANT6499 ) |
2625 | 95 | Default.flag("-m32").flag("+m64").flag("-mx32"); |
2626 | 4 | else if (4 Want == WANTX324 ) |
2627 | 4 | Default.flag("-m32").flag("-m64").flag("+mx32"); |
2628 | 4 | else |
2629 | 0 | return false; |
2630 | 180 | |
2631 | 180 | Result.Multilibs.push_back(Default); |
2632 | 180 | Result.Multilibs.push_back(Alt64); |
2633 | 180 | Result.Multilibs.push_back(Alt32); |
2634 | 180 | Result.Multilibs.push_back(Altx32); |
2635 | 180 | |
2636 | 180 | Result.Multilibs.FilterOut(NonExistent); |
2637 | 180 | |
2638 | 180 | Multilib::flags_list Flags; |
2639 | 93 | addMultilibFlag(TargetTriple.isArch64Bit() && !IsX32, "m64", Flags); |
2640 | 180 | addMultilibFlag(TargetTriple.isArch32Bit(), "m32", Flags); |
2641 | 93 | addMultilibFlag(TargetTriple.isArch64Bit() && IsX32, "mx32", Flags); |
2642 | 180 | |
2643 | 180 | if (!Result.Multilibs.select(Flags, Result.SelectedMultilib)) |
2644 | 9 | return false; |
2645 | 180 | |
2646 | 171 | if (171 Result.SelectedMultilib == Alt64 || 171 Result.SelectedMultilib == Alt32166 || |
2647 | 158 | Result.SelectedMultilib == Altx32) |
2648 | 20 | Result.BiarchSibling = Default; |
2649 | 171 | |
2650 | 171 | return true; |
2651 | 180 | } |
2652 | | |
2653 | | void Generic_GCC::GCCInstallationDetector::scanLibDirForGCCTripleSolaris( |
2654 | | const llvm::Triple &TargetArch, const llvm::opt::ArgList &Args, |
2655 | | const std::string &LibDir, StringRef CandidateTriple, |
2656 | 6 | bool NeedsBiarchSuffix) { |
2657 | 6 | // Solaris is a special case. The GCC installation is under |
2658 | 6 | // /usr/gcc/<major>.<minor>/lib/gcc/<triple>/<major>.<minor>.<patch>/, so we |
2659 | 6 | // need to iterate twice. |
2660 | 6 | std::error_code EC; |
2661 | 6 | for (vfs::directory_iterator LI = D.getVFS().dir_begin(LibDir, EC), LE; |
2662 | 12 | !EC && 12 LI != LE12 ; LI = LI.increment(EC)6 ) {6 |
2663 | 6 | StringRef VersionText = llvm::sys::path::filename(LI->getName()); |
2664 | 6 | GCCVersion CandidateVersion = GCCVersion::Parse(VersionText); |
2665 | 6 | |
2666 | 6 | if (CandidateVersion.Major != -1) // Filter obviously bad entries. |
2667 | 6 | if (6 !CandidateGCCInstallPaths.insert(LI->getName()).second6 ) |
2668 | 3 | continue; // Saw this path before; no need to look at it again. |
2669 | 3 | if (3 CandidateVersion.isOlderThan(4, 1, 1)3 ) |
2670 | 0 | continue; |
2671 | 3 | if (3 CandidateVersion <= Version3 ) |
2672 | 0 | continue; |
2673 | 3 | |
2674 | 3 | GCCInstallPath = |
2675 | 3 | LibDir + "/" + VersionText.str() + "/lib/gcc/" + CandidateTriple.str(); |
2676 | 3 | if (!D.getVFS().exists(GCCInstallPath)) |
2677 | 0 | continue; |
2678 | 3 | |
2679 | 3 | // If we make it here there has to be at least one GCC version, let's just |
2680 | 3 | // use the latest one. |
2681 | 3 | std::error_code EEC; |
2682 | 3 | for (vfs::directory_iterator |
2683 | 3 | LLI = D.getVFS().dir_begin(GCCInstallPath, EEC), |
2684 | 3 | LLE; |
2685 | 6 | !EEC && 6 LLI != LLE6 ; LLI = LLI.increment(EEC)3 ) {3 |
2686 | 3 | |
2687 | 3 | StringRef SubVersionText = llvm::sys::path::filename(LLI->getName()); |
2688 | 3 | GCCVersion CandidateSubVersion = GCCVersion::Parse(SubVersionText); |
2689 | 3 | |
2690 | 3 | if (CandidateSubVersion > Version) |
2691 | 3 | Version = CandidateSubVersion; |
2692 | 3 | } |
2693 | 3 | |
2694 | 3 | GCCTriple.setTriple(CandidateTriple); |
2695 | 3 | |
2696 | 3 | GCCInstallPath += "/" + Version.Text; |
2697 | 3 | GCCParentLibPath = GCCInstallPath + "/../../../../"; |
2698 | 3 | |
2699 | 3 | IsValid = true; |
2700 | 3 | } |
2701 | 6 | } |
2702 | | |
2703 | | bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs( |
2704 | | const llvm::Triple &TargetTriple, const ArgList &Args, |
2705 | 381 | StringRef Path, bool NeedsBiarchSuffix) { |
2706 | 381 | llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); |
2707 | 381 | DetectedMultilibs Detected; |
2708 | 381 | |
2709 | 381 | // Android standalone toolchain could have multilibs for ARM and Thumb. |
2710 | 381 | // Debian mips multilibs behave more like the rest of the biarch ones, |
2711 | 381 | // so handle them there |
2712 | 381 | if (isArmOrThumbArch(TargetArch) && 381 TargetTriple.isAndroid()25 ) {16 |
2713 | 16 | // It should also work without multilibs in a simplified toolchain. |
2714 | 16 | findAndroidArmMultilibs(D, TargetTriple, Path, Args, Detected); |
2715 | 365 | } else if (365 isMipsArch(TargetArch)365 ) {185 |
2716 | 185 | if (!findMIPSMultilibs(D, TargetTriple, Path, Args, Detected)) |
2717 | 0 | return false; |
2718 | 180 | } else if (180 !findBiarchMultilibs(D, TargetTriple, Path, Args,180 |
2719 | 9 | NeedsBiarchSuffix, Detected)) { |
2720 | 9 | return false; |
2721 | 9 | } |
2722 | 381 | |
2723 | 372 | Multilibs = Detected.Multilibs; |
2724 | 372 | SelectedMultilib = Detected.SelectedMultilib; |
2725 | 372 | BiarchSibling = Detected.BiarchSibling; |
2726 | 372 | |
2727 | 372 | return true; |
2728 | 381 | } |
2729 | | |
2730 | | void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( |
2731 | | const llvm::Triple &TargetTriple, const ArgList &Args, |
2732 | | const std::string &LibDir, StringRef CandidateTriple, |
2733 | 62.0k | bool NeedsBiarchSuffix) { |
2734 | 62.0k | if (TargetTriple.getOS() == llvm::Triple::Solaris62.0k ) {6 |
2735 | 6 | scanLibDirForGCCTripleSolaris(TargetTriple, Args, LibDir, CandidateTriple, |
2736 | 6 | NeedsBiarchSuffix); |
2737 | 6 | return; |
2738 | 6 | } |
2739 | 62.0k | |
2740 | 62.0k | llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); |
2741 | 62.0k | // Locations relative to the system lib directory where GCC's triple-specific |
2742 | 62.0k | // directories might reside. |
2743 | 62.0k | struct GCCLibSuffix { |
2744 | 62.0k | // Path from system lib directory to GCC triple-specific directory. |
2745 | 62.0k | std::string LibSuffix; |
2746 | 62.0k | // Path from GCC triple-specific directory back to system lib directory. |
2747 | 62.0k | // This is one '..' component per component in LibSuffix. |
2748 | 62.0k | StringRef ReversePath; |
2749 | 62.0k | // Whether this library suffix is relevant for the triple. |
2750 | 62.0k | bool Active; |
2751 | 62.0k | } Suffixes[] = { |
2752 | 62.0k | // This is the normal place. |
2753 | 62.0k | {"gcc/" + CandidateTriple.str(), "../..", true}, |
2754 | 62.0k | |
2755 | 62.0k | // Debian puts cross-compilers in gcc-cross. |
2756 | 62.0k | {"gcc-cross/" + CandidateTriple.str(), "../..", true}, |
2757 | 62.0k | |
2758 | 62.0k | // The Freescale PPC SDK has the gcc libraries in |
2759 | 62.0k | // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well. Only do |
2760 | 62.0k | // this on Freescale triples, though, since some systems put a *lot* of |
2761 | 62.0k | // files in that location, not just GCC installation data. |
2762 | 62.0k | {CandidateTriple.str(), "..", |
2763 | 62.0k | TargetTriple.getVendor() == llvm::Triple::Freescale}, |
2764 | 62.0k | |
2765 | 62.0k | // Natively multiarch systems sometimes put the GCC triple-specific |
2766 | 62.0k | // directory within their multiarch lib directory, resulting in the |
2767 | 62.0k | // triple appearing twice. |
2768 | 62.0k | {CandidateTriple.str() + "/gcc/" + CandidateTriple.str(), "../../..", true}, |
2769 | 62.0k | |
2770 | 62.0k | // Deal with cases (on Ubuntu) where the system architecture could be i386 |
2771 | 62.0k | // but the GCC target architecture could be (say) i686. |
2772 | 62.0k | // FIXME: It may be worthwhile to generalize this and look for a second |
2773 | 62.0k | // triple. |
2774 | 62.0k | {"i386-linux-gnu/gcc/" + CandidateTriple.str(), "../../..", |
2775 | 62.0k | TargetArch == llvm::Triple::x86} |
2776 | 62.0k | }; |
2777 | 62.0k | |
2778 | 310k | for (auto &Suffix : Suffixes) { |
2779 | 310k | if (!Suffix.Active) |
2780 | 109k | continue; |
2781 | 310k | |
2782 | 201k | StringRef LibSuffix = Suffix.LibSuffix; |
2783 | 201k | std::error_code EC; |
2784 | 201k | for (vfs::directory_iterator |
2785 | 201k | LI = D.getVFS().dir_begin(LibDir + "/" + LibSuffix, EC), |
2786 | 201k | LE; |
2787 | 202k | !EC && 202k LI != LE1.59k ; LI = LI.increment(EC)805 ) {805 |
2788 | 805 | StringRef VersionText = llvm::sys::path::filename(LI->getName()); |
2789 | 805 | GCCVersion CandidateVersion = GCCVersion::Parse(VersionText); |
2790 | 805 | if (CandidateVersion.Major != -1) // Filter obviously bad entries. |
2791 | 805 | if (805 !CandidateGCCInstallPaths.insert(LI->getName()).second805 ) |
2792 | 327 | continue; // Saw this path before; no need to look at it again. |
2793 | 478 | if (478 CandidateVersion.isOlderThan(4, 1, 1)478 ) |
2794 | 0 | continue; |
2795 | 478 | if (478 CandidateVersion <= Version478 ) |
2796 | 103 | continue; |
2797 | 478 | |
2798 | 375 | if (375 !ScanGCCForMultilibs(TargetTriple, Args, LI->getName(),375 |
2799 | 375 | NeedsBiarchSuffix)) |
2800 | 9 | continue; |
2801 | 375 | |
2802 | 366 | Version = CandidateVersion; |
2803 | 366 | GCCTriple.setTriple(CandidateTriple); |
2804 | 366 | // FIXME: We hack together the directory name here instead of |
2805 | 366 | // using LI to ensure stable path separators across Windows and |
2806 | 366 | // Linux. |
2807 | 366 | GCCInstallPath = (LibDir + "/" + LibSuffix + "/" + VersionText).str(); |
2808 | 366 | GCCParentLibPath = (GCCInstallPath + "/../" + Suffix.ReversePath).str(); |
2809 | 366 | IsValid = true; |
2810 | 366 | } |
2811 | 201k | } |
2812 | 62.0k | } |
2813 | | |
2814 | | bool Generic_GCC::GCCInstallationDetector::ScanGentooGccConfig( |
2815 | | const llvm::Triple &TargetTriple, const ArgList &Args, |
2816 | 29.2k | StringRef CandidateTriple, bool NeedsBiarchSuffix) { |
2817 | 29.2k | llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File = |
2818 | 29.2k | D.getVFS().getBufferForFile(D.SysRoot + "/etc/env.d/gcc/config-" + |
2819 | 29.2k | CandidateTriple.str()); |
2820 | 29.2k | if (File29.2k ) {6 |
2821 | 6 | SmallVector<StringRef, 2> Lines; |
2822 | 6 | File.get()->getBuffer().split(Lines, "\n"); |
2823 | 6 | for (StringRef Line : Lines) { |
2824 | 6 | // CURRENT=triple-version |
2825 | 6 | if (Line.consume_front("CURRENT=")6 ) {6 |
2826 | 6 | const std::pair<StringRef, StringRef> ActiveVersion = |
2827 | 6 | Line.rsplit('-'); |
2828 | 6 | // Note: Strictly speaking, we should be reading |
2829 | 6 | // /etc/env.d/gcc/${CURRENT} now. However, the file doesn't |
2830 | 6 | // contain anything new or especially useful to us. |
2831 | 6 | const std::string GentooPath = D.SysRoot + "/usr/lib/gcc/" + |
2832 | 6 | ActiveVersion.first.str() + "/" + |
2833 | 6 | ActiveVersion.second.str(); |
2834 | 6 | if (D.getVFS().exists(GentooPath + "/crtbegin.o")6 ) {6 |
2835 | 6 | if (!ScanGCCForMultilibs(TargetTriple, Args, GentooPath, |
2836 | 6 | NeedsBiarchSuffix)) |
2837 | 0 | return false; |
2838 | 6 | |
2839 | 6 | Version = GCCVersion::Parse(ActiveVersion.second); |
2840 | 6 | GCCInstallPath = GentooPath; |
2841 | 6 | GCCParentLibPath = GentooPath + "/../../.."; |
2842 | 6 | GCCTriple.setTriple(ActiveVersion.first); |
2843 | 6 | IsValid = true; |
2844 | 6 | return true; |
2845 | 6 | } |
2846 | 6 | } |
2847 | 6 | } |
2848 | 6 | } |
2849 | 29.2k | |
2850 | 29.2k | return false; |
2851 | 29.2k | } |
2852 | | |
2853 | | Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple &Triple, |
2854 | | const ArgList &Args) |
2855 | | : ToolChain(D, Triple, Args), GCCInstallation(D), |
2856 | 5.38k | CudaInstallation(D, Triple, Args) { |
2857 | 5.38k | getProgramPaths().push_back(getDriver().getInstalledDir()); |
2858 | 5.38k | if (getDriver().getInstalledDir() != getDriver().Dir) |
2859 | 3.12k | getProgramPaths().push_back(getDriver().Dir); |
2860 | 5.38k | } |
2861 | | |
2862 | 5.38k | Generic_GCC::~Generic_GCC() {} |
2863 | | |
2864 | 1.84k | Tool *Generic_GCC::getTool(Action::ActionClass AC) const { |
2865 | 1.84k | switch (AC) { |
2866 | 0 | case Action::PreprocessJobClass: |
2867 | 0 | if (!Preprocess) |
2868 | 0 | Preprocess.reset(new tools::gcc::Preprocessor(*this)); |
2869 | 0 | return Preprocess.get(); |
2870 | 6 | case Action::CompileJobClass: |
2871 | 6 | if (!Compile) |
2872 | 6 | Compile.reset(new tools::gcc::Compiler(*this)); |
2873 | 6 | return Compile.get(); |
2874 | 1.83k | default: |
2875 | 1.83k | return ToolChain::getTool(AC); |
2876 | 1.84k | } |
2877 | 1.84k | } |
2878 | | |
2879 | 35 | Tool *Generic_GCC::buildAssembler() const { |
2880 | 35 | return new tools::gnutools::Assembler(*this); |
2881 | 35 | } |
2882 | | |
2883 | 120 | Tool *Generic_GCC::buildLinker() const { return new tools::gcc::Linker(*this); } |
2884 | | |
2885 | 58 | void Generic_GCC::printVerboseInfo(raw_ostream &OS) const { |
2886 | 58 | // Print the information about how we detected the GCC installation. |
2887 | 58 | GCCInstallation.print(OS); |
2888 | 58 | CudaInstallation.print(OS); |
2889 | 58 | } |
2890 | | |
2891 | 4.93k | bool Generic_GCC::IsUnwindTablesDefault() const { |
2892 | 4.93k | return getArch() == llvm::Triple::x86_64; |
2893 | 4.93k | } |
2894 | | |
2895 | 5.62k | bool Generic_GCC::isPICDefault() const { |
2896 | 5.62k | switch (getArch()) { |
2897 | 698 | case llvm::Triple::x86_64: |
2898 | 698 | return getTriple().isOSWindows(); |
2899 | 202 | case llvm::Triple::ppc64: |
2900 | 202 | case llvm::Triple::ppc64le: |
2901 | 202 | return !getTriple().isOSBinFormatMachO() && !getTriple().isMacOSX(); |
2902 | 402 | case llvm::Triple::mips64: |
2903 | 402 | case llvm::Triple::mips64el: |
2904 | 402 | return true; |
2905 | 4.32k | default: |
2906 | 4.32k | return false; |
2907 | 5.62k | } |
2908 | 5.62k | } |
2909 | | |
2910 | 3.15k | bool Generic_GCC::isPIEDefault() const { return false; } |
2911 | | |
2912 | 5.85k | bool Generic_GCC::isPICDefaultForced() const { |
2913 | 841 | return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows(); |
2914 | 5.85k | } |
2915 | | |
2916 | 19.1k | bool Generic_GCC::IsIntegratedAssemblerDefault() const { |
2917 | 19.1k | switch (getTriple().getArch()) { |
2918 | 16.6k | case llvm::Triple::x86: |
2919 | 16.6k | case llvm::Triple::x86_64: |
2920 | 16.6k | case llvm::Triple::aarch64: |
2921 | 16.6k | case llvm::Triple::aarch64_be: |
2922 | 16.6k | case llvm::Triple::arm: |
2923 | 16.6k | case llvm::Triple::armeb: |
2924 | 16.6k | case llvm::Triple::avr: |
2925 | 16.6k | case llvm::Triple::bpfel: |
2926 | 16.6k | case llvm::Triple::bpfeb: |
2927 | 16.6k | case llvm::Triple::thumb: |
2928 | 16.6k | case llvm::Triple::thumbeb: |
2929 | 16.6k | case llvm::Triple::ppc: |
2930 | 16.6k | case llvm::Triple::ppc64: |
2931 | 16.6k | case llvm::Triple::ppc64le: |
2932 | 16.6k | case llvm::Triple::systemz: |
2933 | 16.6k | case llvm::Triple::mips: |
2934 | 16.6k | case llvm::Triple::mipsel: |
2935 | 16.6k | return true; |
2936 | 1.25k | case llvm::Triple::mips64: |
2937 | 1.25k | case llvm::Triple::mips64el: |
2938 | 1.25k | // Enabled for Debian mips64/mips64el only. Other targets are unable to |
2939 | 1.25k | // distinguish N32 from N64. |
2940 | 1.25k | if (getTriple().getEnvironment() == llvm::Triple::GNUABI64) |
2941 | 16 | return true; |
2942 | 1.23k | return false; |
2943 | 1.24k | default: |
2944 | 1.24k | return false; |
2945 | 19.1k | } |
2946 | 19.1k | } |
2947 | | |
2948 | | void Generic_GCC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, |
2949 | 2.37k | ArgStringList &CC1Args) const { |
2950 | 2.37k | if (DriverArgs.hasArg(options::OPT_nostdlibinc) || |
2951 | 2.37k | DriverArgs.hasArg(options::OPT_nostdincxx)) |
2952 | 2 | return; |
2953 | 2.37k | |
2954 | 2.37k | switch (GetCXXStdlibType(DriverArgs)) { |
2955 | 56 | case ToolChain::CST_Libcxx: { |
2956 | 56 | std::string Path = findLibCxxIncludePath(); |
2957 | 56 | if (!Path.empty()) |
2958 | 53 | addSystemInclude(DriverArgs, CC1Args, Path); |
2959 | 56 | break; |
2960 | 56 | } |
2961 | 56 | |
2962 | 2.31k | case ToolChain::CST_Libstdcxx: |
2963 | 2.31k | addLibStdCxxIncludePaths(DriverArgs, CC1Args); |
2964 | 2.31k | break; |
2965 | 2.37k | } |
2966 | 2.37k | } |
2967 | | |
2968 | 3 | std::string Generic_GCC::findLibCxxIncludePath() const { |
2969 | 3 | // FIXME: The Linux behavior would probaby be a better approach here. |
2970 | 3 | return getDriver().SysRoot + "/usr/include/c++/v1"; |
2971 | 3 | } |
2972 | | |
2973 | | void |
2974 | | Generic_GCC::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, |
2975 | 1.59k | llvm::opt::ArgStringList &CC1Args) const { |
2976 | 1.59k | // By default, we don't assume we know where libstdc++ might be installed. |
2977 | 1.59k | // FIXME: If we have a valid GCCInstallation, use it. |
2978 | 1.59k | } |
2979 | | |
2980 | | /// \brief Helper to add the variant paths of a libstdc++ installation. |
2981 | | bool Generic_GCC::addLibStdCXXIncludePaths( |
2982 | | Twine Base, Twine Suffix, StringRef GCCTriple, StringRef GCCMultiarchTriple, |
2983 | | StringRef TargetMultiarchTriple, Twine IncludeSuffix, |
2984 | 959 | const ArgList &DriverArgs, ArgStringList &CC1Args) const { |
2985 | 959 | if (!getVFS().exists(Base + Suffix)) |
2986 | 736 | return false; |
2987 | 959 | |
2988 | 223 | addSystemInclude(DriverArgs, CC1Args, Base + Suffix); |
2989 | 223 | |
2990 | 223 | // The vanilla GCC layout of libstdc++ headers uses a triple subdirectory. If |
2991 | 223 | // that path exists or we have neither a GCC nor target multiarch triple, use |
2992 | 223 | // this vanilla search path. |
2993 | 223 | if ((GCCMultiarchTriple.empty() && 223 TargetMultiarchTriple.empty()181 ) || |
2994 | 206 | getVFS().exists(Base + Suffix + "/" + GCCTriple + IncludeSuffix)42 ) {206 |
2995 | 206 | addSystemInclude(DriverArgs, CC1Args, |
2996 | 206 | Base + Suffix + "/" + GCCTriple + IncludeSuffix); |
2997 | 17 | } else { |
2998 | 17 | // Otherwise try to use multiarch naming schemes which have normalized the |
2999 | 17 | // triples and put the triple before the suffix. |
3000 | 17 | // |
3001 | 17 | // GCC surprisingly uses *both* the GCC triple with a multilib suffix and |
3002 | 17 | // the target triple, so we support that here. |
3003 | 17 | addSystemInclude(DriverArgs, CC1Args, |
3004 | 17 | Base + "/" + GCCMultiarchTriple + Suffix + IncludeSuffix); |
3005 | 17 | addSystemInclude(DriverArgs, CC1Args, |
3006 | 17 | Base + "/" + TargetMultiarchTriple + Suffix); |
3007 | 17 | } |
3008 | 223 | |
3009 | 223 | addSystemInclude(DriverArgs, CC1Args, Base + Suffix + "/backward"); |
3010 | 223 | return true; |
3011 | 959 | } |
3012 | | |
3013 | | llvm::opt::DerivedArgList * |
3014 | | Generic_GCC::TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef, |
3015 | 5.48k | Action::OffloadKind DeviceOffloadKind) const { |
3016 | 5.48k | |
3017 | 5.48k | // If this tool chain is used for an OpenMP offloading device we have to make |
3018 | 5.48k | // sure we always generate a shared library regardless of the commands the |
3019 | 5.48k | // user passed to the host. This is required because the runtime library |
3020 | 5.48k | // is required to load the device image dynamically at run time. |
3021 | 5.48k | if (DeviceOffloadKind == Action::OFK_OpenMP5.48k ) {24 |
3022 | 24 | DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); |
3023 | 24 | const OptTable &Opts = getDriver().getOpts(); |
3024 | 24 | |
3025 | 24 | // Request the shared library. Given that these options are decided |
3026 | 24 | // implicitly, they do not refer to any base argument. |
3027 | 24 | DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_shared)); |
3028 | 24 | DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_fPIC)); |
3029 | 24 | |
3030 | 24 | // Filter all the arguments we don't care passing to the offloading |
3031 | 24 | // toolchain as they can mess up with the creation of a shared library. |
3032 | 232 | for (auto *A : Args) { |
3033 | 232 | switch ((options::ID)A->getOption().getID()) { |
3034 | 232 | default: |
3035 | 232 | DAL->append(A); |
3036 | 232 | break; |
3037 | 0 | case options::OPT_shared: |
3038 | 0 | case options::OPT_dynamic: |
3039 | 0 | case options::OPT_static: |
3040 | 0 | case options::OPT_fPIC: |
3041 | 0 | case options::OPT_fno_PIC: |
3042 | 0 | case options::OPT_fpic: |
3043 | 0 | case options::OPT_fno_pic: |
3044 | 0 | case options::OPT_fPIE: |
3045 | 0 | case options::OPT_fno_PIE: |
3046 | 0 | case options::OPT_fpie: |
3047 | 0 | case options::OPT_fno_pie: |
3048 | 0 | break; |
3049 | 232 | } |
3050 | 232 | } |
3051 | 24 | return DAL; |
3052 | 24 | } |
3053 | 5.46k | return nullptr; |
3054 | 5.48k | } |
3055 | | |
3056 | | void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs, |
3057 | 5.16k | ArgStringList &CC1Args) const { |
3058 | 5.16k | const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion(); |
3059 | 5.16k | bool UseInitArrayDefault = |
3060 | 5.16k | getTriple().getArch() == llvm::Triple::aarch64 || |
3061 | 4.86k | getTriple().getArch() == llvm::Triple::aarch64_be || |
3062 | 4.77k | (getTriple().getOS() == llvm::Triple::Linux && |
3063 | 1.92k | (!V.isOlderThan(4, 7, 0) || 1.92k getTriple().isAndroid()1.72k )) || |
3064 | 4.49k | getTriple().getOS() == llvm::Triple::NaCl || |
3065 | 4.47k | (getTriple().getVendor() == llvm::Triple::MipsTechnologies && |
3066 | 12 | !getTriple().hasEnvironment()); |
3067 | 5.16k | |
3068 | 5.16k | if (DriverArgs.hasFlag(options::OPT_fuse_init_array, |
3069 | 5.16k | options::OPT_fno_use_init_array, UseInitArrayDefault)) |
3070 | 699 | CC1Args.push_back("-fuse-init-array"); |
3071 | 5.16k | } |
3072 | | |
3073 | | /// Mips Toolchain |
3074 | | MipsLLVMToolChain::MipsLLVMToolChain(const Driver &D, |
3075 | | const llvm::Triple &Triple, |
3076 | | const ArgList &Args) |
3077 | 2 | : Linux(D, Triple, Args) { |
3078 | 2 | // Select the correct multilib according to the given arguments. |
3079 | 2 | DetectedMultilibs Result; |
3080 | 2 | findMIPSMultilibs(D, Triple, "", Args, Result); |
3081 | 2 | Multilibs = Result.Multilibs; |
3082 | 2 | SelectedMultilib = Result.SelectedMultilib; |
3083 | 2 | |
3084 | 2 | // Find out the library suffix based on the ABI. |
3085 | 2 | LibSuffix = tools::mips::getMipsABILibSuffix(Args, Triple); |
3086 | 2 | getFilePaths().clear(); |
3087 | 2 | getFilePaths().push_back(computeSysRoot() + "/usr/lib" + LibSuffix); |
3088 | 2 | } |
3089 | | |
3090 | | void MipsLLVMToolChain::AddClangSystemIncludeArgs( |
3091 | 2 | const ArgList &DriverArgs, ArgStringList &CC1Args) const { |
3092 | 2 | if (DriverArgs.hasArg(options::OPT_nostdinc)) |
3093 | 0 | return; |
3094 | 2 | |
3095 | 2 | const Driver &D = getDriver(); |
3096 | 2 | |
3097 | 2 | if (!DriverArgs.hasArg(options::OPT_nobuiltininc)2 ) {2 |
3098 | 2 | SmallString<128> P(D.ResourceDir); |
3099 | 2 | llvm::sys::path::append(P, "include"); |
3100 | 2 | addSystemInclude(DriverArgs, CC1Args, P); |
3101 | 2 | } |
3102 | 2 | |
3103 | 2 | if (DriverArgs.hasArg(options::OPT_nostdlibinc)) |
3104 | 0 | return; |
3105 | 2 | |
3106 | 2 | const auto &Callback = Multilibs.includeDirsCallback(); |
3107 | 2 | if (Callback2 ) {2 |
3108 | 2 | for (const auto &Path : Callback(SelectedMultilib)) |
3109 | 2 | addExternCSystemIncludeIfExists(DriverArgs, CC1Args, |
3110 | 2 | D.getInstalledDir() + Path); |
3111 | 2 | } |
3112 | 2 | } |
3113 | | |
3114 | 2 | Tool *MipsLLVMToolChain::buildLinker() const { |
3115 | 2 | return new tools::gnutools::Linker(*this); |
3116 | 2 | } |
3117 | | |
3118 | 2 | std::string MipsLLVMToolChain::computeSysRoot() const { |
3119 | 2 | if (!getDriver().SysRoot.empty()) |
3120 | 2 | return getDriver().SysRoot + SelectedMultilib.osSuffix(); |
3121 | 2 | |
3122 | 0 | const std::string InstalledDir(getDriver().getInstalledDir()); |
3123 | 0 | std::string SysRootPath = |
3124 | 0 | InstalledDir + "/../sysroot" + SelectedMultilib.osSuffix(); |
3125 | 0 | if (llvm::sys::fs::exists(SysRootPath)) |
3126 | 0 | return SysRootPath; |
3127 | 0 |
|
3128 | 0 | return std::string(); |
3129 | 0 | } |
3130 | | |
3131 | | ToolChain::CXXStdlibType |
3132 | 0 | MipsLLVMToolChain::GetCXXStdlibType(const ArgList &Args) const { |
3133 | 0 | Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); |
3134 | 0 | if (A0 ) {0 |
3135 | 0 | StringRef Value = A->getValue(); |
3136 | 0 | if (Value != "libc++") |
3137 | 0 | getDriver().Diag(diag::err_drv_invalid_stdlib_name) |
3138 | 0 | << A->getAsString(Args); |
3139 | 0 | } |
3140 | 0 |
|
3141 | 0 | return ToolChain::CST_Libcxx; |
3142 | 0 | } |
3143 | | |
3144 | 0 | std::string MipsLLVMToolChain::findLibCxxIncludePath() const { |
3145 | 0 | if (const auto &Callback0 = Multilibs.includeDirsCallback()) {0 |
3146 | 0 | for (std::string Path : Callback(SelectedMultilib)) { |
3147 | 0 | Path = getDriver().getInstalledDir() + Path + "/c++/v1"; |
3148 | 0 | if (llvm::sys::fs::exists(Path)0 ) {0 |
3149 | 0 | return Path; |
3150 | 0 | } |
3151 | 0 | } |
3152 | 0 | } |
3153 | 0 | return ""; |
3154 | 0 | } |
3155 | | |
3156 | | void MipsLLVMToolChain::AddCXXStdlibLibArgs(const ArgList &Args, |
3157 | 0 | ArgStringList &CmdArgs) const { |
3158 | 0 | assert((GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) && |
3159 | 0 | "Only -lc++ (aka libxx) is suported in this toolchain."); |
3160 | 0 |
|
3161 | 0 | CmdArgs.push_back("-lc++"); |
3162 | 0 | CmdArgs.push_back("-lc++abi"); |
3163 | 0 | CmdArgs.push_back("-lunwind"); |
3164 | 0 | } |
3165 | | |
3166 | | std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args, |
3167 | | StringRef Component, |
3168 | 4 | bool Shared) const { |
3169 | 4 | SmallString<128> Path(getDriver().ResourceDir); |
3170 | 4 | llvm::sys::path::append(Path, SelectedMultilib.osSuffix(), "lib" + LibSuffix, |
3171 | 4 | getOS()); |
3172 | 4 | llvm::sys::path::append(Path, Twine("libclang_rt." + Component + "-" + |
3173 | 4 | "mips" + (Shared ? ".so"0 : ".a"4 ))); |
3174 | 4 | return Path.str(); |
3175 | 4 | } |
3176 | | |
3177 | | /// Hexagon Toolchain |
3178 | | |
3179 | | std::string HexagonToolChain::getHexagonTargetDir( |
3180 | | const std::string &InstalledDir, |
3181 | 147 | const SmallVectorImpl<std::string> &PrefixDirs) const { |
3182 | 147 | std::string InstallRelDir; |
3183 | 147 | const Driver &D = getDriver(); |
3184 | 147 | |
3185 | 147 | // Locate the rest of the toolchain ... |
3186 | 147 | for (auto &I : PrefixDirs) |
3187 | 0 | if (0 D.getVFS().exists(I)0 ) |
3188 | 0 | return I; |
3189 | 147 | |
3190 | 147 | if (147 getVFS().exists(InstallRelDir = InstalledDir + "/../target")147 ) |
3191 | 128 | return InstallRelDir; |
3192 | 147 | |
3193 | 19 | return InstalledDir; |
3194 | 147 | } |
3195 | | |
3196 | | Optional<unsigned> HexagonToolChain::getSmallDataThreshold( |
3197 | 113 | const ArgList &Args) { |
3198 | 113 | StringRef Gn = ""; |
3199 | 113 | if (Arg *A113 = Args.getLastArg(options::OPT_G)) {12 |
3200 | 12 | Gn = A->getValue(); |
3201 | 101 | } else if (101 Args.getLastArg(options::OPT_shared, options::OPT_fpic,101 |
3202 | 15 | options::OPT_fPIC)) { |
3203 | 15 | Gn = "0"; |
3204 | 15 | } |
3205 | 113 | |
3206 | 113 | unsigned G; |
3207 | 113 | if (!Gn.getAsInteger(10, G)) |
3208 | 27 | return G; |
3209 | 113 | |
3210 | 86 | return None; |
3211 | 113 | } |
3212 | | |
3213 | | void HexagonToolChain::getHexagonLibraryPaths(const ArgList &Args, |
3214 | 36 | ToolChain::path_list &LibPaths) const { |
3215 | 36 | const Driver &D = getDriver(); |
3216 | 36 | |
3217 | 36 | //---------------------------------------------------------------------------- |
3218 | 36 | // -L Args |
3219 | 36 | //---------------------------------------------------------------------------- |
3220 | 36 | for (Arg *A : Args.filtered(options::OPT_L)) |
3221 | 3 | for (const char *Value : A->getValues()) |
3222 | 3 | LibPaths.push_back(Value); |
3223 | 36 | |
3224 | 36 | //---------------------------------------------------------------------------- |
3225 | 36 | // Other standard paths |
3226 | 36 | //---------------------------------------------------------------------------- |
3227 | 36 | std::vector<std::string> RootDirs; |
3228 | 36 | std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(), |
3229 | 36 | std::back_inserter(RootDirs)); |
3230 | 36 | |
3231 | 36 | std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(), |
3232 | 36 | D.PrefixDirs); |
3233 | 36 | if (std::find(RootDirs.begin(), RootDirs.end(), TargetDir) == RootDirs.end()) |
3234 | 36 | RootDirs.push_back(TargetDir); |
3235 | 36 | |
3236 | 36 | bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC); |
3237 | 36 | // Assume G0 with -shared. |
3238 | 36 | bool HasG0 = Args.hasArg(options::OPT_shared); |
3239 | 36 | if (auto G = getSmallDataThreshold(Args)) |
3240 | 8 | HasG0 = G.getValue() == 0; |
3241 | 36 | |
3242 | 36 | const std::string CpuVer = GetTargetCPUVersion(Args).str(); |
3243 | 36 | for (auto &Dir : RootDirs) { |
3244 | 36 | std::string LibDir = Dir + "/hexagon/lib"; |
3245 | 36 | std::string LibDirCpu = LibDir + '/' + CpuVer; |
3246 | 36 | if (HasG036 ) {5 |
3247 | 5 | if (HasPIC) |
3248 | 2 | LibPaths.push_back(LibDirCpu + "/G0/pic"); |
3249 | 5 | LibPaths.push_back(LibDirCpu + "/G0"); |
3250 | 5 | } |
3251 | 36 | LibPaths.push_back(LibDirCpu); |
3252 | 36 | LibPaths.push_back(LibDir); |
3253 | 36 | } |
3254 | 36 | } |
3255 | | |
3256 | | HexagonToolChain::HexagonToolChain(const Driver &D, const llvm::Triple &Triple, |
3257 | | const llvm::opt::ArgList &Args) |
3258 | 36 | : Linux(D, Triple, Args) { |
3259 | 36 | const std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(), |
3260 | 36 | D.PrefixDirs); |
3261 | 36 | |
3262 | 36 | // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to |
3263 | 36 | // program paths |
3264 | 36 | const std::string BinDir(TargetDir + "/bin"); |
3265 | 36 | if (D.getVFS().exists(BinDir)) |
3266 | 0 | getProgramPaths().push_back(BinDir); |
3267 | 36 | |
3268 | 36 | ToolChain::path_list &LibPaths = getFilePaths(); |
3269 | 36 | |
3270 | 36 | // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets |
3271 | 36 | // 'elf' OS type, so the Linux paths are not appropriate. When we actually |
3272 | 36 | // support 'linux' we'll need to fix this up |
3273 | 36 | LibPaths.clear(); |
3274 | 36 | getHexagonLibraryPaths(Args, LibPaths); |
3275 | 36 | } |
3276 | | |
3277 | 36 | HexagonToolChain::~HexagonToolChain() {} |
3278 | | |
3279 | 5 | Tool *HexagonToolChain::buildAssembler() const { |
3280 | 5 | return new tools::hexagon::Assembler(*this); |
3281 | 5 | } |
3282 | | |
3283 | 36 | Tool *HexagonToolChain::buildLinker() const { |
3284 | 36 | return new tools::hexagon::Linker(*this); |
3285 | 36 | } |
3286 | | |
3287 | | void HexagonToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
3288 | 36 | ArgStringList &CC1Args) const { |
3289 | 36 | if (DriverArgs.hasArg(options::OPT_nostdinc) || |
3290 | 35 | DriverArgs.hasArg(options::OPT_nostdlibinc)) |
3291 | 3 | return; |
3292 | 36 | |
3293 | 33 | const Driver &D = getDriver(); |
3294 | 33 | std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(), |
3295 | 33 | D.PrefixDirs); |
3296 | 33 | addExternCSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include"); |
3297 | 33 | } |
3298 | | |
3299 | | |
3300 | | void HexagonToolChain::addLibStdCxxIncludePaths( |
3301 | | const llvm::opt::ArgList &DriverArgs, |
3302 | 6 | llvm::opt::ArgStringList &CC1Args) const { |
3303 | 6 | const Driver &D = getDriver(); |
3304 | 6 | std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs); |
3305 | 6 | addLibStdCXXIncludePaths(TargetDir, "/hexagon/include/c++", "", "", "", "", |
3306 | 6 | DriverArgs, CC1Args); |
3307 | 6 | } |
3308 | | |
3309 | | ToolChain::CXXStdlibType |
3310 | 12 | HexagonToolChain::GetCXXStdlibType(const ArgList &Args) const { |
3311 | 12 | Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); |
3312 | 12 | if (!A) |
3313 | 12 | return ToolChain::CST_Libstdcxx; |
3314 | 12 | |
3315 | 0 | StringRef Value = A->getValue(); |
3316 | 0 | if (Value != "libstdc++") |
3317 | 0 | getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args); |
3318 | 0 |
|
3319 | 0 | return ToolChain::CST_Libstdcxx; |
3320 | 12 | } |
3321 | | |
3322 | | // |
3323 | | // Returns the default CPU for Hexagon. This is the default compilation target |
3324 | | // if no Hexagon processor is selected at the command-line. |
3325 | | // |
3326 | 31 | const StringRef HexagonToolChain::GetDefaultCPU() { |
3327 | 31 | return "hexagonv60"; |
3328 | 31 | } |
3329 | | |
3330 | 113 | const StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) { |
3331 | 113 | Arg *CpuArg = nullptr; |
3332 | 113 | if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ, options::OPT_march_EQ)) |
3333 | 82 | CpuArg = A; |
3334 | 113 | |
3335 | 82 | StringRef CPU = CpuArg ? CpuArg->getValue()82 : GetDefaultCPU()31 ; |
3336 | 113 | if (CPU.startswith("hexagon")) |
3337 | 113 | return CPU.substr(sizeof("hexagon") - 1); |
3338 | 0 | return CPU; |
3339 | 113 | } |
3340 | | // End Hexagon |
3341 | | |
3342 | | /// AMDGPU Toolchain |
3343 | | AMDGPUToolChain::AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple, |
3344 | | const ArgList &Args) |
3345 | 2 | : Generic_ELF(D, Triple, Args) { } |
3346 | | |
3347 | 2 | Tool *AMDGPUToolChain::buildLinker() const { |
3348 | 2 | return new tools::amdgpu::Linker(*this); |
3349 | 2 | } |
3350 | | // End AMDGPU |
3351 | | |
3352 | | /// NaCl Toolchain |
3353 | | NaClToolChain::NaClToolChain(const Driver &D, const llvm::Triple &Triple, |
3354 | | const ArgList &Args) |
3355 | 22 | : Generic_ELF(D, Triple, Args) { |
3356 | 22 | |
3357 | 22 | // Remove paths added by Generic_GCC. NaCl Toolchain cannot use the |
3358 | 22 | // default paths, and must instead only use the paths provided |
3359 | 22 | // with this toolchain based on architecture. |
3360 | 22 | path_list &file_paths = getFilePaths(); |
3361 | 22 | path_list &prog_paths = getProgramPaths(); |
3362 | 22 | |
3363 | 22 | file_paths.clear(); |
3364 | 22 | prog_paths.clear(); |
3365 | 22 | |
3366 | 22 | // Path for library files (libc.a, ...) |
3367 | 22 | std::string FilePath(getDriver().Dir + "/../"); |
3368 | 22 | |
3369 | 22 | // Path for tools (clang, ld, etc..) |
3370 | 22 | std::string ProgPath(getDriver().Dir + "/../"); |
3371 | 22 | |
3372 | 22 | // Path for toolchain libraries (libgcc.a, ...) |
3373 | 22 | std::string ToolPath(getDriver().ResourceDir + "/lib/"); |
3374 | 22 | |
3375 | 22 | switch (Triple.getArch()) { |
3376 | 2 | case llvm::Triple::x86: |
3377 | 2 | file_paths.push_back(FilePath + "x86_64-nacl/lib32"); |
3378 | 2 | file_paths.push_back(FilePath + "i686-nacl/usr/lib"); |
3379 | 2 | prog_paths.push_back(ProgPath + "x86_64-nacl/bin"); |
3380 | 2 | file_paths.push_back(ToolPath + "i686-nacl"); |
3381 | 2 | break; |
3382 | 5 | case llvm::Triple::x86_64: |
3383 | 5 | file_paths.push_back(FilePath + "x86_64-nacl/lib"); |
3384 | 5 | file_paths.push_back(FilePath + "x86_64-nacl/usr/lib"); |
3385 | 5 | prog_paths.push_back(ProgPath + "x86_64-nacl/bin"); |
3386 | 5 | file_paths.push_back(ToolPath + "x86_64-nacl"); |
3387 | 5 | break; |
3388 | 5 | case llvm::Triple::arm: |
3389 | 5 | file_paths.push_back(FilePath + "arm-nacl/lib"); |
3390 | 5 | file_paths.push_back(FilePath + "arm-nacl/usr/lib"); |
3391 | 5 | prog_paths.push_back(ProgPath + "arm-nacl/bin"); |
3392 | 5 | file_paths.push_back(ToolPath + "arm-nacl"); |
3393 | 5 | break; |
3394 | 5 | case llvm::Triple::mipsel: |
3395 | 5 | file_paths.push_back(FilePath + "mipsel-nacl/lib"); |
3396 | 5 | file_paths.push_back(FilePath + "mipsel-nacl/usr/lib"); |
3397 | 5 | prog_paths.push_back(ProgPath + "bin"); |
3398 | 5 | file_paths.push_back(ToolPath + "mipsel-nacl"); |
3399 | 5 | break; |
3400 | 5 | default: |
3401 | 5 | break; |
3402 | 22 | } |
3403 | 22 | |
3404 | 22 | NaClArmMacrosPath = GetFilePath("nacl-arm-macros.s"); |
3405 | 22 | } |
3406 | | |
3407 | | void NaClToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
3408 | 22 | ArgStringList &CC1Args) const { |
3409 | 22 | const Driver &D = getDriver(); |
3410 | 22 | if (DriverArgs.hasArg(options::OPT_nostdinc)) |
3411 | 0 | return; |
3412 | 22 | |
3413 | 22 | if (22 !DriverArgs.hasArg(options::OPT_nobuiltininc)22 ) {22 |
3414 | 22 | SmallString<128> P(D.ResourceDir); |
3415 | 22 | llvm::sys::path::append(P, "include"); |
3416 | 22 | addSystemInclude(DriverArgs, CC1Args, P.str()); |
3417 | 22 | } |
3418 | 22 | |
3419 | 22 | if (DriverArgs.hasArg(options::OPT_nostdlibinc)) |
3420 | 0 | return; |
3421 | 22 | |
3422 | 22 | SmallString<128> P(D.Dir + "/../"); |
3423 | 22 | switch (getTriple().getArch()) { |
3424 | 2 | case llvm::Triple::x86: |
3425 | 2 | // x86 is special because multilib style uses x86_64-nacl/include for libc |
3426 | 2 | // headers but the SDK wants i686-nacl/usr/include. The other architectures |
3427 | 2 | // have the same substring. |
3428 | 2 | llvm::sys::path::append(P, "i686-nacl/usr/include"); |
3429 | 2 | addSystemInclude(DriverArgs, CC1Args, P.str()); |
3430 | 2 | llvm::sys::path::remove_filename(P); |
3431 | 2 | llvm::sys::path::remove_filename(P); |
3432 | 2 | llvm::sys::path::remove_filename(P); |
3433 | 2 | llvm::sys::path::append(P, "x86_64-nacl/include"); |
3434 | 2 | addSystemInclude(DriverArgs, CC1Args, P.str()); |
3435 | 2 | return; |
3436 | 5 | case llvm::Triple::arm: |
3437 | 5 | llvm::sys::path::append(P, "arm-nacl/usr/include"); |
3438 | 5 | break; |
3439 | 5 | case llvm::Triple::x86_64: |
3440 | 5 | llvm::sys::path::append(P, "x86_64-nacl/usr/include"); |
3441 | 5 | break; |
3442 | 5 | case llvm::Triple::mipsel: |
3443 | 5 | llvm::sys::path::append(P, "mipsel-nacl/usr/include"); |
3444 | 5 | break; |
3445 | 5 | default: |
3446 | 5 | return; |
3447 | 22 | } |
3448 | 22 | |
3449 | 15 | addSystemInclude(DriverArgs, CC1Args, P.str()); |
3450 | 15 | llvm::sys::path::remove_filename(P); |
3451 | 15 | llvm::sys::path::remove_filename(P); |
3452 | 15 | llvm::sys::path::append(P, "include"); |
3453 | 15 | addSystemInclude(DriverArgs, CC1Args, P.str()); |
3454 | 15 | } |
3455 | | |
3456 | | void NaClToolChain::AddCXXStdlibLibArgs(const ArgList &Args, |
3457 | 4 | ArgStringList &CmdArgs) const { |
3458 | 4 | // Check for -stdlib= flags. We only support libc++ but this consumes the arg |
3459 | 4 | // if the value is libc++, and emits an error for other values. |
3460 | 4 | GetCXXStdlibType(Args); |
3461 | 4 | CmdArgs.push_back("-lc++"); |
3462 | 4 | } |
3463 | | |
3464 | 13 | std::string NaClToolChain::findLibCxxIncludePath() const { |
3465 | 13 | const Driver &D = getDriver(); |
3466 | 13 | |
3467 | 13 | SmallString<128> P(D.Dir + "/../"); |
3468 | 13 | switch (getTriple().getArch()) { |
3469 | 1 | case llvm::Triple::arm: |
3470 | 1 | llvm::sys::path::append(P, "arm-nacl/include/c++/v1"); |
3471 | 1 | return P.str(); |
3472 | 1 | case llvm::Triple::x86: |
3473 | 1 | llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1"); |
3474 | 1 | return P.str(); |
3475 | 4 | case llvm::Triple::x86_64: |
3476 | 4 | llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1"); |
3477 | 4 | return P.str(); |
3478 | 4 | case llvm::Triple::mipsel: |
3479 | 4 | llvm::sys::path::append(P, "mipsel-nacl/include/c++/v1"); |
3480 | 4 | return P.str(); |
3481 | 3 | default: |
3482 | 3 | return ""; |
3483 | 13 | } |
3484 | 13 | } |
3485 | | |
3486 | | ToolChain::CXXStdlibType |
3487 | 17 | NaClToolChain::GetCXXStdlibType(const ArgList &Args) const { |
3488 | 17 | if (Arg *A17 = Args.getLastArg(options::OPT_stdlib_EQ)) {0 |
3489 | 0 | StringRef Value = A->getValue(); |
3490 | 0 | if (Value == "libc++") |
3491 | 0 | return ToolChain::CST_Libcxx; |
3492 | 0 | getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args); |
3493 | 0 | } |
3494 | 17 | |
3495 | 17 | return ToolChain::CST_Libcxx; |
3496 | 17 | } |
3497 | | |
3498 | | std::string |
3499 | | NaClToolChain::ComputeEffectiveClangTriple(const ArgList &Args, |
3500 | 48 | types::ID InputType) const { |
3501 | 48 | llvm::Triple TheTriple(ComputeLLVMTriple(Args, InputType)); |
3502 | 48 | if (TheTriple.getArch() == llvm::Triple::arm && |
3503 | 15 | TheTriple.getEnvironment() == llvm::Triple::UnknownEnvironment) |
3504 | 3 | TheTriple.setEnvironment(llvm::Triple::GNUEABIHF); |
3505 | 48 | return TheTriple.getTriple(); |
3506 | 48 | } |
3507 | | |
3508 | 13 | Tool *NaClToolChain::buildLinker() const { |
3509 | 13 | return new tools::nacltools::Linker(*this); |
3510 | 13 | } |
3511 | | |
3512 | 13 | Tool *NaClToolChain::buildAssembler() const { |
3513 | 13 | if (getTriple().getArch() == llvm::Triple::arm) |
3514 | 5 | return new tools::nacltools::AssemblerARM(*this); |
3515 | 8 | return new tools::gnutools::Assembler(*this); |
3516 | 13 | } |
3517 | | // End NaCl |
3518 | | |
3519 | | /// TCEToolChain - A tool chain using the llvm bitcode tools to perform |
3520 | | /// all subcommands. See http://tce.cs.tut.fi for our peculiar target. |
3521 | | /// Currently does not support anything else but compilation. |
3522 | | |
3523 | | TCEToolChain::TCEToolChain(const Driver &D, const llvm::Triple &Triple, |
3524 | | const ArgList &Args) |
3525 | 0 | : ToolChain(D, Triple, Args) { |
3526 | 0 | // Path mangling to find libexec |
3527 | 0 | std::string Path(getDriver().Dir); |
3528 | 0 |
|
3529 | 0 | Path += "/../libexec"; |
3530 | 0 | getProgramPaths().push_back(Path); |
3531 | 0 | } |
3532 | | |
3533 | 0 | TCEToolChain::~TCEToolChain() {} |
3534 | | |
3535 | 0 | bool TCEToolChain::IsMathErrnoDefault() const { return true; } |
3536 | | |
3537 | 0 | bool TCEToolChain::isPICDefault() const { return false; } |
3538 | | |
3539 | 0 | bool TCEToolChain::isPIEDefault() const { return false; } |
3540 | | |
3541 | 0 | bool TCEToolChain::isPICDefaultForced() const { return false; } |
3542 | | |
3543 | | TCELEToolChain::TCELEToolChain(const Driver &D, const llvm::Triple& Triple, |
3544 | | const ArgList &Args) |
3545 | 0 | : TCEToolChain(D, Triple, Args) { |
3546 | 0 | } |
3547 | | |
3548 | 0 | TCELEToolChain::~TCELEToolChain() {} |
3549 | | |
3550 | | // CloudABI - CloudABI tool chain which can call ld(1) directly. |
3551 | | |
3552 | | CloudABI::CloudABI(const Driver &D, const llvm::Triple &Triple, |
3553 | | const ArgList &Args) |
3554 | 14 | : Generic_ELF(D, Triple, Args) { |
3555 | 14 | SmallString<128> P(getDriver().Dir); |
3556 | 14 | llvm::sys::path::append(P, "..", getTriple().str(), "lib"); |
3557 | 14 | getFilePaths().push_back(P.str()); |
3558 | 14 | } |
3559 | | |
3560 | 3 | std::string CloudABI::findLibCxxIncludePath() const { |
3561 | 3 | SmallString<128> P(getDriver().Dir); |
3562 | 3 | llvm::sys::path::append(P, "..", getTriple().str(), "include/c++/v1"); |
3563 | 3 | return P.str(); |
3564 | 3 | } |
3565 | | |
3566 | | void CloudABI::AddCXXStdlibLibArgs(const ArgList &Args, |
3567 | 3 | ArgStringList &CmdArgs) const { |
3568 | 3 | CmdArgs.push_back("-lc++"); |
3569 | 3 | CmdArgs.push_back("-lc++abi"); |
3570 | 3 | CmdArgs.push_back("-lunwind"); |
3571 | 3 | } |
3572 | | |
3573 | 8 | Tool *CloudABI::buildLinker() const { |
3574 | 8 | return new tools::cloudabi::Linker(*this); |
3575 | 8 | } |
3576 | | |
3577 | 22 | bool CloudABI::isPIEDefault() const { |
3578 | 22 | // Only enable PIE on architectures that support PC-relative |
3579 | 22 | // addressing. PC-relative addressing is required, as the process |
3580 | 22 | // startup code must be able to relocate itself. |
3581 | 22 | switch (getTriple().getArch()) { |
3582 | 16 | case llvm::Triple::aarch64: |
3583 | 16 | case llvm::Triple::x86_64: |
3584 | 16 | return true; |
3585 | 6 | default: |
3586 | 6 | return false; |
3587 | 22 | } |
3588 | 22 | } |
3589 | | |
3590 | 14 | SanitizerMask CloudABI::getSupportedSanitizers() const { |
3591 | 14 | SanitizerMask Res = ToolChain::getSupportedSanitizers(); |
3592 | 14 | Res |= SanitizerKind::SafeStack; |
3593 | 14 | return Res; |
3594 | 14 | } |
3595 | | |
3596 | 14 | SanitizerMask CloudABI::getDefaultSanitizers() const { |
3597 | 14 | return SanitizerKind::SafeStack; |
3598 | 14 | } |
3599 | | |
3600 | | /// Haiku - Haiku tool chain which can call as(1) and ld(1) directly. |
3601 | | |
3602 | | Haiku::Haiku(const Driver &D, const llvm::Triple& Triple, const ArgList &Args) |
3603 | 0 | : Generic_ELF(D, Triple, Args) { |
3604 | 0 |
|
3605 | 0 | } |
3606 | | |
3607 | 0 | std::string Haiku::findLibCxxIncludePath() const { |
3608 | 0 | return getDriver().SysRoot + "/system/develop/headers/c++/v1"; |
3609 | 0 | } |
3610 | | |
3611 | | void Haiku::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, |
3612 | 0 | llvm::opt::ArgStringList &CC1Args) const { |
3613 | 0 | addLibStdCXXIncludePaths(getDriver().SysRoot, "/system/develop/headers/c++", |
3614 | 0 | getTriple().str(), "", "", "", DriverArgs, CC1Args); |
3615 | 0 | } |
3616 | | |
3617 | | /// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly. |
3618 | | |
3619 | | OpenBSD::OpenBSD(const Driver &D, const llvm::Triple &Triple, |
3620 | | const ArgList &Args) |
3621 | 53 | : Generic_ELF(D, Triple, Args) { |
3622 | 53 | getFilePaths().push_back(getDriver().Dir + "/../lib"); |
3623 | 53 | getFilePaths().push_back("/usr/lib"); |
3624 | 53 | } |
3625 | | |
3626 | 16 | Tool *OpenBSD::buildAssembler() const { |
3627 | 16 | return new tools::openbsd::Assembler(*this); |
3628 | 16 | } |
3629 | | |
3630 | 23 | Tool *OpenBSD::buildLinker() const { return new tools::openbsd::Linker(*this); } |
3631 | | |
3632 | | /// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly. |
3633 | | |
3634 | | Bitrig::Bitrig(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) |
3635 | 10 | : Generic_ELF(D, Triple, Args) { |
3636 | 10 | getFilePaths().push_back(getDriver().Dir + "/../lib"); |
3637 | 10 | getFilePaths().push_back("/usr/lib"); |
3638 | 10 | } |
3639 | | |
3640 | 0 | Tool *Bitrig::buildAssembler() const { |
3641 | 0 | return new tools::bitrig::Assembler(*this); |
3642 | 0 | } |
3643 | | |
3644 | 6 | Tool *Bitrig::buildLinker() const { return new tools::bitrig::Linker(*this); } |
3645 | | |
3646 | 2 | ToolChain::CXXStdlibType Bitrig::GetDefaultCXXStdlibType() const { |
3647 | 2 | return ToolChain::CST_Libcxx; |
3648 | 2 | } |
3649 | | |
3650 | | void Bitrig::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, |
3651 | 1 | llvm::opt::ArgStringList &CC1Args) const { |
3652 | 1 | std::string Triple = getTriple().str(); |
3653 | 1 | if (StringRef(Triple).startswith("amd64")) |
3654 | 1 | Triple = "x86_64" + Triple.substr(5); |
3655 | 1 | addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/c++/stdc++", |
3656 | 1 | Triple, "", "", "", DriverArgs, CC1Args); |
3657 | 1 | } |
3658 | | |
3659 | | void Bitrig::AddCXXStdlibLibArgs(const ArgList &Args, |
3660 | 2 | ArgStringList &CmdArgs) const { |
3661 | 2 | switch (GetCXXStdlibType(Args)) { |
3662 | 1 | case ToolChain::CST_Libcxx: |
3663 | 1 | CmdArgs.push_back("-lc++"); |
3664 | 1 | CmdArgs.push_back("-lc++abi"); |
3665 | 1 | CmdArgs.push_back("-lpthread"); |
3666 | 1 | break; |
3667 | 1 | case ToolChain::CST_Libstdcxx: |
3668 | 1 | CmdArgs.push_back("-lstdc++"); |
3669 | 1 | break; |
3670 | 2 | } |
3671 | 2 | } |
3672 | | |
3673 | | /// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. |
3674 | | |
3675 | | FreeBSD::FreeBSD(const Driver &D, const llvm::Triple &Triple, |
3676 | | const ArgList &Args) |
3677 | 78 | : Generic_ELF(D, Triple, Args) { |
3678 | 78 | |
3679 | 78 | // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall |
3680 | 78 | // back to '/usr/lib' if it doesn't exist. |
3681 | 78 | if ((Triple.getArch() == llvm::Triple::x86 || |
3682 | 68 | Triple.getArch() == llvm::Triple::ppc) && |
3683 | 12 | D.getVFS().exists(getDriver().SysRoot + "/usr/lib32/crt1.o")) |
3684 | 5 | getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32"); |
3685 | 78 | else |
3686 | 73 | getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); |
3687 | 78 | } |
3688 | | |
3689 | 9 | ToolChain::CXXStdlibType FreeBSD::GetDefaultCXXStdlibType() const { |
3690 | 9 | if (getTriple().getOSMajorVersion() >= 10) |
3691 | 4 | return ToolChain::CST_Libcxx; |
3692 | 5 | return ToolChain::CST_Libstdcxx; |
3693 | 9 | } |
3694 | | |
3695 | | void FreeBSD::addLibStdCxxIncludePaths( |
3696 | | const llvm::opt::ArgList &DriverArgs, |
3697 | 3 | llvm::opt::ArgStringList &CC1Args) const { |
3698 | 3 | addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/c++/4.2", "", "", |
3699 | 3 | "", "", DriverArgs, CC1Args); |
3700 | 3 | } |
3701 | | |
3702 | | void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args, |
3703 | 4 | ArgStringList &CmdArgs) const { |
3704 | 4 | CXXStdlibType Type = GetCXXStdlibType(Args); |
3705 | 4 | bool Profiling = Args.hasArg(options::OPT_pg); |
3706 | 4 | |
3707 | 4 | switch (Type) { |
3708 | 2 | case ToolChain::CST_Libcxx: |
3709 | 1 | CmdArgs.push_back(Profiling ? "-lc++_p"1 : "-lc++"1 ); |
3710 | 2 | break; |
3711 | 2 | |
3712 | 2 | case ToolChain::CST_Libstdcxx: |
3713 | 1 | CmdArgs.push_back(Profiling ? "-lstdc++_p"1 : "-lstdc++"1 ); |
3714 | 2 | break; |
3715 | 4 | } |
3716 | 4 | } |
3717 | | |
3718 | 25 | Tool *FreeBSD::buildAssembler() const { |
3719 | 25 | return new tools::freebsd::Assembler(*this); |
3720 | 25 | } |
3721 | | |
3722 | 42 | Tool *FreeBSD::buildLinker() const { return new tools::freebsd::Linker(*this); } |
3723 | | |
3724 | 78 | bool FreeBSD::UseSjLjExceptions(const ArgList &Args) const { |
3725 | 78 | // FreeBSD uses SjLj exceptions on ARM oabi. |
3726 | 78 | switch (getTriple().getEnvironment()) { |
3727 | 6 | case llvm::Triple::GNUEABIHF: |
3728 | 6 | case llvm::Triple::GNUEABI: |
3729 | 6 | case llvm::Triple::EABI: |
3730 | 6 | return false; |
3731 | 6 | |
3732 | 72 | default: |
3733 | 72 | return (getTriple().getArch() == llvm::Triple::arm || |
3734 | 70 | getTriple().getArch() == llvm::Triple::thumb); |
3735 | 78 | } |
3736 | 78 | } |
3737 | | |
3738 | 42 | bool FreeBSD::HasNativeLLVMSupport() const { return true; } |
3739 | | |
3740 | 139 | bool FreeBSD::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); } |
3741 | | |
3742 | 77 | SanitizerMask FreeBSD::getSupportedSanitizers() const { |
3743 | 77 | const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; |
3744 | 77 | const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; |
3745 | 77 | const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 || |
3746 | 72 | getTriple().getArch() == llvm::Triple::mips64el; |
3747 | 77 | SanitizerMask Res = ToolChain::getSupportedSanitizers(); |
3748 | 77 | Res |= SanitizerKind::Address; |
3749 | 77 | Res |= SanitizerKind::Vptr; |
3750 | 77 | if (IsX86_64 || 77 IsMIPS6446 ) {39 |
3751 | 39 | Res |= SanitizerKind::Leak; |
3752 | 39 | Res |= SanitizerKind::Thread; |
3753 | 39 | } |
3754 | 77 | if (IsX86 || 77 IsX86_6468 ) {40 |
3755 | 40 | Res |= SanitizerKind::SafeStack; |
3756 | 40 | } |
3757 | 77 | return Res; |
3758 | 77 | } |
3759 | | |
3760 | | /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. |
3761 | | |
3762 | | NetBSD::NetBSD(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) |
3763 | 146 | : Generic_ELF(D, Triple, Args) { |
3764 | 146 | if (getDriver().UseStdLib146 ) {143 |
3765 | 143 | // When targeting a 32-bit platform, try the special directory used on |
3766 | 143 | // 64-bit hosts, and only fall back to the main library directory if that |
3767 | 143 | // doesn't work. |
3768 | 143 | // FIXME: It'd be nicer to test if this directory exists, but I'm not sure |
3769 | 143 | // what all logic is needed to emulate the '=' prefix here. |
3770 | 143 | switch (Triple.getArch()) { |
3771 | 2 | case llvm::Triple::x86: |
3772 | 2 | getFilePaths().push_back("=/usr/lib/i386"); |
3773 | 2 | break; |
3774 | 29 | case llvm::Triple::arm: |
3775 | 29 | case llvm::Triple::armeb: |
3776 | 29 | case llvm::Triple::thumb: |
3777 | 29 | case llvm::Triple::thumbeb: |
3778 | 29 | switch (Triple.getEnvironment()) { |
3779 | 22 | case llvm::Triple::EABI: |
3780 | 22 | case llvm::Triple::GNUEABI: |
3781 | 22 | getFilePaths().push_back("=/usr/lib/eabi"); |
3782 | 22 | break; |
3783 | 5 | case llvm::Triple::EABIHF: |
3784 | 5 | case llvm::Triple::GNUEABIHF: |
3785 | 5 | getFilePaths().push_back("=/usr/lib/eabihf"); |
3786 | 5 | break; |
3787 | 2 | default: |
3788 | 2 | getFilePaths().push_back("=/usr/lib/oabi"); |
3789 | 2 | break; |
3790 | 29 | } |
3791 | 29 | break; |
3792 | 2 | case llvm::Triple::mips64: |
3793 | 2 | case llvm::Triple::mips64el: |
3794 | 2 | if (tools::mips::hasMipsAbiArg(Args, "o32")) |
3795 | 0 | getFilePaths().push_back("=/usr/lib/o32"); |
3796 | 2 | else if (2 tools::mips::hasMipsAbiArg(Args, "64")2 ) |
3797 | 0 | getFilePaths().push_back("=/usr/lib/64"); |
3798 | 2 | break; |
3799 | 4 | case llvm::Triple::ppc: |
3800 | 4 | getFilePaths().push_back("=/usr/lib/powerpc"); |
3801 | 4 | break; |
3802 | 27 | case llvm::Triple::sparc: |
3803 | 27 | getFilePaths().push_back("=/usr/lib/sparc"); |
3804 | 27 | break; |
3805 | 79 | default: |
3806 | 79 | break; |
3807 | 143 | } |
3808 | 143 | |
3809 | 143 | getFilePaths().push_back("=/usr/lib"); |
3810 | 143 | } |
3811 | 146 | } |
3812 | | |
3813 | 67 | Tool *NetBSD::buildAssembler() const { |
3814 | 67 | return new tools::netbsd::Assembler(*this); |
3815 | 67 | } |
3816 | | |
3817 | 128 | Tool *NetBSD::buildLinker() const { return new tools::netbsd::Linker(*this); } |
3818 | | |
3819 | 68 | ToolChain::CXXStdlibType NetBSD::GetDefaultCXXStdlibType() const { |
3820 | 68 | unsigned Major, Minor, Micro; |
3821 | 68 | getTriple().getOSVersion(Major, Minor, Micro); |
3822 | 68 | if (Major >= 7 || 68 Major == 044 ) {52 |
3823 | 52 | switch (getArch()) { |
3824 | 52 | case llvm::Triple::aarch64: |
3825 | 52 | case llvm::Triple::aarch64_be: |
3826 | 52 | case llvm::Triple::arm: |
3827 | 52 | case llvm::Triple::armeb: |
3828 | 52 | case llvm::Triple::thumb: |
3829 | 52 | case llvm::Triple::thumbeb: |
3830 | 52 | case llvm::Triple::ppc: |
3831 | 52 | case llvm::Triple::ppc64: |
3832 | 52 | case llvm::Triple::ppc64le: |
3833 | 52 | case llvm::Triple::sparc: |
3834 | 52 | case llvm::Triple::sparcv9: |
3835 | 52 | case llvm::Triple::x86: |
3836 | 52 | case llvm::Triple::x86_64: |
3837 | 52 | return ToolChain::CST_Libcxx; |
3838 | 0 | default: |
3839 | 0 | break; |
3840 | 52 | } |
3841 | 52 | } |
3842 | 16 | return ToolChain::CST_Libstdcxx; |
3843 | 68 | } |
3844 | | |
3845 | 26 | std::string NetBSD::findLibCxxIncludePath() const { |
3846 | 26 | return getDriver().SysRoot + "/usr/include/c++/"; |
3847 | 26 | } |
3848 | | |
3849 | | void NetBSD::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, |
3850 | 8 | llvm::opt::ArgStringList &CC1Args) const { |
3851 | 8 | addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/g++", "", "", "", |
3852 | 8 | "", DriverArgs, CC1Args); |
3853 | 8 | } |
3854 | | |
3855 | | /// Minix - Minix tool chain which can call as(1) and ld(1) directly. |
3856 | | |
3857 | | Minix::Minix(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) |
3858 | 0 | : Generic_ELF(D, Triple, Args) { |
3859 | 0 | getFilePaths().push_back(getDriver().Dir + "/../lib"); |
3860 | 0 | getFilePaths().push_back("/usr/lib"); |
3861 | 0 | } |
3862 | | |
3863 | 0 | Tool *Minix::buildAssembler() const { |
3864 | 0 | return new tools::minix::Assembler(*this); |
3865 | 0 | } |
3866 | | |
3867 | 0 | Tool *Minix::buildLinker() const { return new tools::minix::Linker(*this); } |
3868 | | |
3869 | | static void addPathIfExists(const Driver &D, const Twine &Path, |
3870 | 19.8k | ToolChain::path_list &Paths) { |
3871 | 19.8k | if (D.getVFS().exists(Path)) |
3872 | 6.64k | Paths.push_back(Path.str()); |
3873 | 19.8k | } |
3874 | | |
3875 | | /// Solaris - Solaris tool chain which can call as(1) and ld(1) directly. |
3876 | | |
3877 | | Solaris::Solaris(const Driver &D, const llvm::Triple &Triple, |
3878 | | const ArgList &Args) |
3879 | 8 | : Generic_GCC(D, Triple, Args) { |
3880 | 8 | |
3881 | 8 | GCCInstallation.init(Triple, Args); |
3882 | 8 | |
3883 | 8 | path_list &Paths = getFilePaths(); |
3884 | 8 | if (GCCInstallation.isValid()) |
3885 | 3 | addPathIfExists(D, GCCInstallation.getInstallPath(), Paths); |
3886 | 8 | |
3887 | 8 | addPathIfExists(D, getDriver().getInstalledDir(), Paths); |
3888 | 8 | if (getDriver().getInstalledDir() != getDriver().Dir) |
3889 | 5 | addPathIfExists(D, getDriver().Dir, Paths); |
3890 | 8 | |
3891 | 8 | addPathIfExists(D, getDriver().SysRoot + getDriver().Dir + "/../lib", Paths); |
3892 | 8 | |
3893 | 8 | std::string LibPath = "/usr/lib/"; |
3894 | 8 | switch (Triple.getArch()) { |
3895 | 8 | case llvm::Triple::x86: |
3896 | 8 | case llvm::Triple::sparc: |
3897 | 8 | break; |
3898 | 0 | case llvm::Triple::x86_64: |
3899 | 0 | LibPath += "amd64/"; |
3900 | 0 | break; |
3901 | 0 | case llvm::Triple::sparcv9: |
3902 | 0 | LibPath += "sparcv9/"; |
3903 | 0 | break; |
3904 | 0 | default: |
3905 | 0 | llvm_unreachable("Unsupported architecture"); |
3906 | 8 | } |
3907 | 8 | |
3908 | 8 | addPathIfExists(D, getDriver().SysRoot + LibPath, Paths); |
3909 | 8 | } |
3910 | | |
3911 | 0 | Tool *Solaris::buildAssembler() const { |
3912 | 0 | return new tools::solaris::Assembler(*this); |
3913 | 0 | } |
3914 | | |
3915 | 4 | Tool *Solaris::buildLinker() const { return new tools::solaris::Linker(*this); } |
3916 | | |
3917 | | void Solaris::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, |
3918 | 2 | ArgStringList &CC1Args) const { |
3919 | 2 | if (DriverArgs.hasArg(options::OPT_nostdlibinc) || |
3920 | 2 | DriverArgs.hasArg(options::OPT_nostdincxx)) |
3921 | 0 | return; |
3922 | 2 | |
3923 | 2 | // Include the support directory for things like xlocale and fudged system |
3924 | 2 | // headers. |
3925 | 2 | // FIXME: This is a weird mix of libc++ and libstdc++. We should also be |
3926 | 2 | // checking the value of -stdlib= here and adding the includes for libc++ |
3927 | 2 | // rather than libstdc++ if it's requested. |
3928 | 2 | addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/v1/support/solaris"); |
3929 | 2 | |
3930 | 2 | if (GCCInstallation.isValid()2 ) {1 |
3931 | 1 | GCCVersion Version = GCCInstallation.getVersion(); |
3932 | 1 | addSystemInclude(DriverArgs, CC1Args, |
3933 | 1 | getDriver().SysRoot + "/usr/gcc/" + |
3934 | 1 | Version.MajorStr + "." + |
3935 | 1 | Version.MinorStr + |
3936 | 1 | "/include/c++/" + Version.Text); |
3937 | 1 | addSystemInclude(DriverArgs, CC1Args, |
3938 | 1 | getDriver().SysRoot + "/usr/gcc/" + Version.MajorStr + |
3939 | 1 | "." + Version.MinorStr + "/include/c++/" + |
3940 | 1 | Version.Text + "/" + |
3941 | 1 | GCCInstallation.getTriple().str()); |
3942 | 1 | } |
3943 | 2 | } |
3944 | | |
3945 | | /// \brief Get our best guess at the multiarch triple for a target. |
3946 | | /// |
3947 | | /// Debian-based systems are starting to use a multiarch setup where they use |
3948 | | /// a target-triple directory in the library and header search paths. |
3949 | | /// Unfortunately, this triple does not align with the vanilla target triple, |
3950 | | /// so we provide a rough mapping here. |
3951 | | static std::string getMultiarchTriple(const Driver &D, |
3952 | | const llvm::Triple &TargetTriple, |
3953 | 2.57k | StringRef SysRoot) { |
3954 | 2.57k | llvm::Triple::EnvironmentType TargetEnvironment = |
3955 | 2.57k | TargetTriple.getEnvironment(); |
3956 | 2.57k | |
3957 | 2.57k | // For most architectures, just use whatever we have rather than trying to be |
3958 | 2.57k | // clever. |
3959 | 2.57k | switch (TargetTriple.getArch()) { |
3960 | 50 | default: |
3961 | 50 | break; |
3962 | 50 | |
3963 | 50 | // We use the existence of '/lib/<triple>' as a directory to detect some |
3964 | 50 | // common linux triples that don't quite match the Clang triple for both |
3965 | 50 | // 32-bit and 64-bit targets. Multiarch fixes its install triples to these |
3966 | 50 | // regardless of what the actual target triple is. |
3967 | 367 | case llvm::Triple::arm: |
3968 | 367 | case llvm::Triple::thumb: |
3969 | 367 | if (TargetEnvironment == llvm::Triple::GNUEABIHF367 ) {19 |
3970 | 19 | if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabihf")) |
3971 | 2 | return "arm-linux-gnueabihf"; |
3972 | 348 | } else { |
3973 | 348 | if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabi")) |
3974 | 1 | return "arm-linux-gnueabi"; |
3975 | 348 | } |
3976 | 364 | break; |
3977 | 43 | case llvm::Triple::armeb: |
3978 | 43 | case llvm::Triple::thumbeb: |
3979 | 43 | if (TargetEnvironment == llvm::Triple::GNUEABIHF43 ) {2 |
3980 | 2 | if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabihf")) |
3981 | 0 | return "armeb-linux-gnueabihf"; |
3982 | 41 | } else { |
3983 | 41 | if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabi")) |
3984 | 0 | return "armeb-linux-gnueabi"; |
3985 | 41 | } |
3986 | 43 | break; |
3987 | 301 | case llvm::Triple::x86: |
3988 | 301 | if (D.getVFS().exists(SysRoot + "/lib/i386-linux-gnu")) |
3989 | 12 | return "i386-linux-gnu"; |
3990 | 289 | break; |
3991 | 583 | case llvm::Triple::x86_64: |
3992 | 583 | // We don't want this for x32, otherwise it will match x86_64 libs |
3993 | 583 | if (TargetEnvironment != llvm::Triple::GNUX32 && |
3994 | 571 | D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu")) |
3995 | 19 | return "x86_64-linux-gnu"; |
3996 | 564 | break; |
3997 | 79 | case llvm::Triple::aarch64: |
3998 | 79 | if (D.getVFS().exists(SysRoot + "/lib/aarch64-linux-gnu")) |
3999 | 0 | return "aarch64-linux-gnu"; |
4000 | 79 | break; |
4001 | 1 | case llvm::Triple::aarch64_be: |
4002 | 1 | if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu")) |
4003 | 0 | return "aarch64_be-linux-gnu"; |
4004 | 1 | break; |
4005 | 492 | case llvm::Triple::mips: |
4006 | 492 | if (D.getVFS().exists(SysRoot + "/lib/mips-linux-gnu")) |
4007 | 4 | return "mips-linux-gnu"; |
4008 | 488 | break; |
4009 | 164 | case llvm::Triple::mipsel: |
4010 | 164 | if (D.getVFS().exists(SysRoot + "/lib/mipsel-linux-gnu")) |
4011 | 4 | return "mipsel-linux-gnu"; |
4012 | 160 | break; |
4013 | 113 | case llvm::Triple::mips64: |
4014 | 113 | if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu")) |
4015 | 0 | return "mips64-linux-gnu"; |
4016 | 113 | if (113 D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnuabi64")113 ) |
4017 | 4 | return "mips64-linux-gnuabi64"; |
4018 | 109 | break; |
4019 | 103 | case llvm::Triple::mips64el: |
4020 | 103 | if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu")) |
4021 | 0 | return "mips64el-linux-gnu"; |
4022 | 103 | if (103 D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnuabi64")103 ) |
4023 | 4 | return "mips64el-linux-gnuabi64"; |
4024 | 99 | break; |
4025 | 19 | case llvm::Triple::ppc: |
4026 | 19 | if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnuspe")) |
4027 | 0 | return "powerpc-linux-gnuspe"; |
4028 | 19 | if (19 D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu")19 ) |
4029 | 4 | return "powerpc-linux-gnu"; |
4030 | 15 | break; |
4031 | 103 | case llvm::Triple::ppc64: |
4032 | 103 | if (D.getVFS().exists(SysRoot + "/lib/powerpc64-linux-gnu")) |
4033 | 4 | return "powerpc64-linux-gnu"; |
4034 | 99 | break; |
4035 | 89 | case llvm::Triple::ppc64le: |
4036 | 89 | if (D.getVFS().exists(SysRoot + "/lib/powerpc64le-linux-gnu")) |
4037 | 5 | return "powerpc64le-linux-gnu"; |
4038 | 84 | break; |
4039 | 18 | case llvm::Triple::sparc: |
4040 | 18 | if (D.getVFS().exists(SysRoot + "/lib/sparc-linux-gnu")) |
4041 | 5 | return "sparc-linux-gnu"; |
4042 | 13 | break; |
4043 | 20 | case llvm::Triple::sparcv9: |
4044 | 20 | if (D.getVFS().exists(SysRoot + "/lib/sparc64-linux-gnu")) |
4045 | 4 | return "sparc64-linux-gnu"; |
4046 | 16 | break; |
4047 | 30 | case llvm::Triple::systemz: |
4048 | 30 | if (D.getVFS().exists(SysRoot + "/lib/s390x-linux-gnu")) |
4049 | 0 | return "s390x-linux-gnu"; |
4050 | 30 | break; |
4051 | 2.57k | } |
4052 | 2.50k | return TargetTriple.str(); |
4053 | 2.57k | } |
4054 | | |
4055 | 2.12k | static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) { |
4056 | 2.12k | if (isMipsArch(Triple.getArch())2.12k ) {524 |
4057 | 524 | if (Triple.isAndroid()524 ) {29 |
4058 | 29 | StringRef CPUName; |
4059 | 29 | StringRef ABIName; |
4060 | 29 | tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName); |
4061 | 29 | if (CPUName == "mips32r6") |
4062 | 3 | return "libr6"; |
4063 | 26 | if (26 CPUName == "mips32r2"26 ) |
4064 | 4 | return "libr2"; |
4065 | 26 | } |
4066 | 524 | // lib32 directory has a special meaning on MIPS targets. |
4067 | 524 | // It contains N32 ABI binaries. Use this folder if produce |
4068 | 524 | // code for N32 ABI only. |
4069 | 517 | if (517 tools::mips::hasMipsAbiArg(Args, "n32")517 ) |
4070 | 37 | return "lib32"; |
4071 | 480 | return Triple.isArch32Bit() ? 480 "lib"361 : "lib64"119 ; |
4072 | 517 | } |
4073 | 2.12k | |
4074 | 2.12k | // It happens that only x86 and PPC use the 'lib32' variant of oslibdir, and |
4075 | 2.12k | // using that variant while targeting other architectures causes problems |
4076 | 2.12k | // because the libraries are laid out in shared system roots that can't cope |
4077 | 2.12k | // with a 'lib32' library search path being considered. So we only enable |
4078 | 2.12k | // them when we know we may need it. |
4079 | 2.12k | // |
4080 | 2.12k | // FIXME: This is a bit of a hack. We should really unify this code for |
4081 | 2.12k | // reasoning about oslibdir spellings with the lib dir spellings in the |
4082 | 2.12k | // GCCInstallationDetector, but that is a more significant refactoring. |
4083 | 1.60k | if (1.60k Triple.getArch() == llvm::Triple::x86 ||1.60k |
4084 | 1.32k | Triple.getArch() == llvm::Triple::ppc) |
4085 | 297 | return "lib32"; |
4086 | 1.60k | |
4087 | 1.30k | if (1.30k Triple.getArch() == llvm::Triple::x86_64 &&1.30k |
4088 | 548 | Triple.getEnvironment() == llvm::Triple::GNUX32) |
4089 | 10 | return "libx32"; |
4090 | 1.30k | |
4091 | 1.29k | return Triple.isArch32Bit() ? 1.29k "lib"446 : "lib64"852 ; |
4092 | 1.30k | } |
4093 | | |
4094 | | static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs, |
4095 | | const Multilib &Multilib, |
4096 | | StringRef InstallPath, |
4097 | 355 | ToolChain::path_list &Paths) { |
4098 | 355 | if (const auto &PathsCallback = Multilibs.filePathsCallback()) |
4099 | 28 | for (const auto &Path : PathsCallback(Multilib)) |
4100 | 28 | addPathIfExists(D, InstallPath + Path, Paths); |
4101 | 355 | } |
4102 | | |
4103 | | Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) |
4104 | 2.12k | : Generic_ELF(D, Triple, Args) { |
4105 | 2.12k | GCCInstallation.init(Triple, Args); |
4106 | 2.12k | Multilibs = GCCInstallation.getMultilibs(); |
4107 | 2.12k | llvm::Triple::ArchType Arch = Triple.getArch(); |
4108 | 2.12k | std::string SysRoot = computeSysRoot(); |
4109 | 2.12k | |
4110 | 2.12k | // Cross-compiling binutils and GCC installations (vanilla and openSUSE at |
4111 | 2.12k | // least) put various tools in a triple-prefixed directory off of the parent |
4112 | 2.12k | // of the GCC installation. We use the GCC triple here to ensure that we end |
4113 | 2.12k | // up with tools that support the same amount of cross compiling as the |
4114 | 2.12k | // detected GCC installation. For example, if we find a GCC installation |
4115 | 2.12k | // targeting x86_64, but it is a bi-arch GCC installation, it can also be |
4116 | 2.12k | // used to target i386. |
4117 | 2.12k | // FIXME: This seems unlikely to be Linux-specific. |
4118 | 2.12k | ToolChain::path_list &PPaths = getProgramPaths(); |
4119 | 2.12k | PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + |
4120 | 2.12k | GCCInstallation.getTriple().str() + "/bin") |
4121 | 2.12k | .str()); |
4122 | 2.12k | |
4123 | 2.12k | Distro Distro(D.getVFS()); |
4124 | 2.12k | |
4125 | 2.12k | if (Distro.IsOpenSUSE() || 2.12k Distro.IsUbuntu()2.12k ) {0 |
4126 | 0 | ExtraOpts.push_back("-z"); |
4127 | 0 | ExtraOpts.push_back("relro"); |
4128 | 0 | } |
4129 | 2.12k | |
4130 | 2.12k | if (Arch == llvm::Triple::arm || 2.12k Arch == llvm::Triple::thumb1.79k ) |
4131 | 345 | ExtraOpts.push_back("-X"); |
4132 | 2.12k | |
4133 | 2.12k | const bool IsAndroid = Triple.isAndroid(); |
4134 | 2.12k | const bool IsMips = isMipsArch(Arch); |
4135 | 2.12k | const bool IsHexagon = Arch == llvm::Triple::hexagon; |
4136 | 2.12k | |
4137 | 2.12k | if (IsMips && 2.12k !SysRoot.empty()524 ) |
4138 | 202 | ExtraOpts.push_back("--sysroot=" + SysRoot); |
4139 | 2.12k | |
4140 | 2.12k | // Do not use 'gnu' hash style for Mips targets because .gnu.hash |
4141 | 2.12k | // and the MIPS ABI require .dynsym to be sorted in different ways. |
4142 | 2.12k | // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS |
4143 | 2.12k | // ABI requires a mapping between the GOT and the symbol table. |
4144 | 2.12k | // Android loader does not support .gnu.hash. |
4145 | 2.12k | // Hexagon linker/loader does not support .gnu.hash |
4146 | 2.12k | if (!IsMips && 2.12k !IsAndroid1.60k && !IsHexagon1.50k ) {1.46k |
4147 | 1.46k | if (Distro.IsRedhat() || 1.46k Distro.IsOpenSUSE()1.46k || |
4148 | 1.46k | (Distro.IsUbuntu() && 1.46k Distro >= Distro::UbuntuMaverick0 )) |
4149 | 0 | ExtraOpts.push_back("--hash-style=gnu"); |
4150 | 1.46k | |
4151 | 1.46k | if (Distro.IsDebian() || 1.46k Distro.IsOpenSUSE()1.46k || Distro == Distro::UbuntuLucid1.46k || |
4152 | 1.46k | Distro == Distro::UbuntuJaunty1.46k || Distro == Distro::UbuntuKarmic1.46k ) |
4153 | 0 | ExtraOpts.push_back("--hash-style=both"); |
4154 | 1.46k | } |
4155 | 2.12k | |
4156 | 2.12k | if (Distro.IsRedhat() && 2.12k Distro != Distro::RHEL50 && Distro != Distro::RHEL60 ) |
4157 | 0 | ExtraOpts.push_back("--no-add-needed"); |
4158 | 2.12k | |
4159 | 2.12k | #ifdef ENABLE_LINKER_BUILD_ID |
4160 | | ExtraOpts.push_back("--build-id"); |
4161 | | #endif |
4162 | 2.12k | |
4163 | 2.12k | if (Distro.IsOpenSUSE()) |
4164 | 0 | ExtraOpts.push_back("--enable-new-dtags"); |
4165 | 2.12k | |
4166 | 2.12k | // The selection of paths to try here is designed to match the patterns which |
4167 | 2.12k | // the GCC driver itself uses, as this is part of the GCC-compatible driver. |
4168 | 2.12k | // This was determined by running GCC in a fake filesystem, creating all |
4169 | 2.12k | // possible permutations of these directories, and seeing which ones it added |
4170 | 2.12k | // to the link paths. |
4171 | 2.12k | path_list &Paths = getFilePaths(); |
4172 | 2.12k | |
4173 | 2.12k | const std::string OSLibDir = getOSLibDir(Triple, Args); |
4174 | 2.12k | const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot); |
4175 | 2.12k | |
4176 | 2.12k | // Add the multilib suffixed paths where they are available. |
4177 | 2.12k | if (GCCInstallation.isValid()2.12k ) {355 |
4178 | 355 | const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); |
4179 | 355 | const std::string &LibPath = GCCInstallation.getParentLibPath(); |
4180 | 355 | const Multilib &Multilib = GCCInstallation.getMultilib(); |
4181 | 355 | const MultilibSet &Multilibs = GCCInstallation.getMultilibs(); |
4182 | 355 | |
4183 | 355 | // Add toolchain / multilib specific file paths. |
4184 | 355 | addMultilibsFilePaths(D, Multilibs, Multilib, |
4185 | 355 | GCCInstallation.getInstallPath(), Paths); |
4186 | 355 | |
4187 | 355 | // Sourcery CodeBench MIPS toolchain holds some libraries under |
4188 | 355 | // a biarch-like suffix of the GCC installation. |
4189 | 355 | addPathIfExists(D, GCCInstallation.getInstallPath() + Multilib.gccSuffix(), |
4190 | 355 | Paths); |
4191 | 355 | |
4192 | 355 | // GCC cross compiling toolchains will install target libraries which ship |
4193 | 355 | // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as |
4194 | 355 | // any part of the GCC installation in |
4195 | 355 | // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat |
4196 | 355 | // debatable, but is the reality today. We need to search this tree even |
4197 | 355 | // when we have a sysroot somewhere else. It is the responsibility of |
4198 | 355 | // whomever is doing the cross build targeting a sysroot using a GCC |
4199 | 355 | // installation that is *not* within the system root to ensure two things: |
4200 | 355 | // |
4201 | 355 | // 1) Any DSOs that are linked in from this tree or from the install path |
4202 | 355 | // above must be present on the system root and found via an |
4203 | 355 | // appropriate rpath. |
4204 | 355 | // 2) There must not be libraries installed into |
4205 | 355 | // <prefix>/<triple>/<libdir> unless they should be preferred over |
4206 | 355 | // those within the system root. |
4207 | 355 | // |
4208 | 355 | // Note that this matches the GCC behavior. See the below comment for where |
4209 | 355 | // Clang diverges from GCC's behavior. |
4210 | 355 | addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib/../" + |
4211 | 355 | OSLibDir + Multilib.osSuffix(), |
4212 | 355 | Paths); |
4213 | 355 | |
4214 | 355 | // If the GCC installation we found is inside of the sysroot, we want to |
4215 | 355 | // prefer libraries installed in the parent prefix of the GCC installation. |
4216 | 355 | // It is important to *not* use these paths when the GCC installation is |
4217 | 355 | // outside of the system root as that can pick up unintended libraries. |
4218 | 355 | // This usually happens when there is an external cross compiler on the |
4219 | 355 | // host system, and a more minimal sysroot available that is the target of |
4220 | 355 | // the cross. Note that GCC does include some of these directories in some |
4221 | 355 | // configurations but this seems somewhere between questionable and simply |
4222 | 355 | // a bug. |
4223 | 355 | if (StringRef(LibPath).startswith(SysRoot)355 ) {160 |
4224 | 160 | addPathIfExists(D, LibPath + "/" + MultiarchTriple, Paths); |
4225 | 160 | addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths); |
4226 | 160 | } |
4227 | 355 | } |
4228 | 2.12k | |
4229 | 2.12k | // Similar to the logic for GCC above, if we currently running Clang inside |
4230 | 2.12k | // of the requested system root, add its parent library paths to |
4231 | 2.12k | // those searched. |
4232 | 2.12k | // FIXME: It's not clear whether we should use the driver's installed |
4233 | 2.12k | // directory ('Dir' below) or the ResourceDir. |
4234 | 2.12k | if (StringRef(D.Dir).startswith(SysRoot)2.12k ) {1.68k |
4235 | 1.68k | addPathIfExists(D, D.Dir + "/../lib/" + MultiarchTriple, Paths); |
4236 | 1.68k | addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths); |
4237 | 1.68k | } |
4238 | 2.12k | |
4239 | 2.12k | addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths); |
4240 | 2.12k | addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths); |
4241 | 2.12k | addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths); |
4242 | 2.12k | addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths); |
4243 | 2.12k | |
4244 | 2.12k | // Try walking via the GCC triple path in case of biarch or multiarch GCC |
4245 | 2.12k | // installations with strange symlinks. |
4246 | 2.12k | if (GCCInstallation.isValid()2.12k ) {355 |
4247 | 355 | addPathIfExists(D, |
4248 | 355 | SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() + |
4249 | 355 | "/../../" + OSLibDir, |
4250 | 355 | Paths); |
4251 | 355 | |
4252 | 355 | // Add the 'other' biarch variant path |
4253 | 355 | Multilib BiarchSibling; |
4254 | 355 | if (GCCInstallation.getBiarchSibling(BiarchSibling)355 ) {34 |
4255 | 34 | addPathIfExists(D, GCCInstallation.getInstallPath() + |
4256 | 34 | BiarchSibling.gccSuffix(), |
4257 | 34 | Paths); |
4258 | 34 | } |
4259 | 355 | |
4260 | 355 | // See comments above on the multilib variant for details of why this is |
4261 | 355 | // included even from outside the sysroot. |
4262 | 355 | const std::string &LibPath = GCCInstallation.getParentLibPath(); |
4263 | 355 | const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); |
4264 | 355 | const Multilib &Multilib = GCCInstallation.getMultilib(); |
4265 | 355 | addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib" + |
4266 | 355 | Multilib.osSuffix(), |
4267 | 355 | Paths); |
4268 | 355 | |
4269 | 355 | // See comments above on the multilib variant for details of why this is |
4270 | 355 | // only included from within the sysroot. |
4271 | 355 | if (StringRef(LibPath).startswith(SysRoot)) |
4272 | 160 | addPathIfExists(D, LibPath, Paths); |
4273 | 355 | } |
4274 | 2.12k | |
4275 | 2.12k | // Similar to the logic for GCC above, if we are currently running Clang |
4276 | 2.12k | // inside of the requested system root, add its parent library path to those |
4277 | 2.12k | // searched. |
4278 | 2.12k | // FIXME: It's not clear whether we should use the driver's installed |
4279 | 2.12k | // directory ('Dir' below) or the ResourceDir. |
4280 | 2.12k | if (StringRef(D.Dir).startswith(SysRoot)) |
4281 | 1.68k | addPathIfExists(D, D.Dir + "/../lib", Paths); |
4282 | 2.12k | |
4283 | 2.12k | addPathIfExists(D, SysRoot + "/lib", Paths); |
4284 | 2.12k | addPathIfExists(D, SysRoot + "/usr/lib", Paths); |
4285 | 2.12k | } |
4286 | | |
4287 | 1.00k | bool Linux::HasNativeLLVMSupport() const { return true; } |
4288 | | |
4289 | 939 | Tool *Linux::buildLinker() const { return new tools::gnutools::Linker(*this); } |
4290 | | |
4291 | 256 | Tool *Linux::buildAssembler() const { |
4292 | 256 | return new tools::gnutools::Assembler(*this); |
4293 | 256 | } |
4294 | | |
4295 | 4.25k | std::string Linux::computeSysRoot() const { |
4296 | 4.25k | if (!getDriver().SysRoot.empty()) |
4297 | 606 | return getDriver().SysRoot; |
4298 | 4.25k | |
4299 | 3.64k | if (3.64k !GCCInstallation.isValid() || 3.64k !isMipsArch(getTriple().getArch())349 ) |
4300 | 3.32k | return std::string(); |
4301 | 3.64k | |
4302 | 3.64k | // Standalone MIPS toolchains use different names for sysroot folder |
4303 | 3.64k | // and put it into different places. Here we try to check some known |
4304 | 3.64k | // variants. |
4305 | 3.64k | |
4306 | 324 | const StringRef InstallDir = GCCInstallation.getInstallPath(); |
4307 | 324 | const StringRef TripleStr = GCCInstallation.getTriple().str(); |
4308 | 324 | const Multilib &Multilib = GCCInstallation.getMultilib(); |
4309 | 324 | |
4310 | 324 | std::string Path = |
4311 | 324 | (InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix()) |
4312 | 324 | .str(); |
4313 | 324 | |
4314 | 324 | if (getVFS().exists(Path)) |
4315 | 48 | return Path; |
4316 | 324 | |
4317 | 276 | Path = (InstallDir + "/../../../../sysroot" + Multilib.osSuffix()).str(); |
4318 | 276 | |
4319 | 276 | if (getVFS().exists(Path)) |
4320 | 276 | return Path; |
4321 | 276 | |
4322 | 0 | return std::string(); |
4323 | 276 | } |
4324 | | |
4325 | 862 | std::string Linux::getDynamicLinker(const ArgList &Args) const { |
4326 | 862 | const llvm::Triple::ArchType Arch = getArch(); |
4327 | 862 | const llvm::Triple &Triple = getTriple(); |
4328 | 862 | |
4329 | 862 | const Distro Distro(getDriver().getVFS()); |
4330 | 862 | |
4331 | 862 | if (Triple.isAndroid()) |
4332 | 87 | return Triple.isArch64Bit() ? 87 "/system/bin/linker64"31 : "/system/bin/linker"56 ; |
4333 | 862 | |
4334 | 775 | if (775 Triple.isMusl()775 ) {23 |
4335 | 23 | std::string ArchName; |
4336 | 23 | bool IsArm = false; |
4337 | 23 | |
4338 | 23 | switch (Arch) { |
4339 | 7 | case llvm::Triple::arm: |
4340 | 7 | case llvm::Triple::thumb: |
4341 | 7 | ArchName = "arm"; |
4342 | 7 | IsArm = true; |
4343 | 7 | break; |
4344 | 6 | case llvm::Triple::armeb: |
4345 | 6 | case llvm::Triple::thumbeb: |
4346 | 6 | ArchName = "armeb"; |
4347 | 6 | IsArm = true; |
4348 | 6 | break; |
4349 | 10 | default: |
4350 | 10 | ArchName = Triple.getArchName().str(); |
4351 | 23 | } |
4352 | 23 | if (23 IsArm &&23 |
4353 | 13 | (Triple.getEnvironment() == llvm::Triple::MuslEABIHF || |
4354 | 8 | tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard)) |
4355 | 9 | ArchName += "hf"; |
4356 | 23 | |
4357 | 23 | return "/lib/ld-musl-" + ArchName + ".so.1"; |
4358 | 23 | } |
4359 | 775 | |
4360 | 752 | std::string LibDir; |
4361 | 752 | std::string Loader; |
4362 | 752 | |
4363 | 752 | switch (Arch) { |
4364 | 0 | default: |
4365 | 0 | llvm_unreachable("unsupported architecture"); |
4366 | 0 |
|
4367 | 10 | case llvm::Triple::aarch64: |
4368 | 10 | LibDir = "lib"; |
4369 | 10 | Loader = "ld-linux-aarch64.so.1"; |
4370 | 10 | break; |
4371 | 0 | case llvm::Triple::aarch64_be: |
4372 | 0 | LibDir = "lib"; |
4373 | 0 | Loader = "ld-linux-aarch64_be.so.1"; |
4374 | 0 | break; |
4375 | 57 | case llvm::Triple::arm: |
4376 | 57 | case llvm::Triple::thumb: |
4377 | 57 | case llvm::Triple::armeb: |
4378 | 57 | case llvm::Triple::thumbeb: { |
4379 | 57 | const bool HF = |
4380 | 57 | Triple.getEnvironment() == llvm::Triple::GNUEABIHF || |
4381 | 47 | tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard; |
4382 | 57 | |
4383 | 57 | LibDir = "lib"; |
4384 | 45 | Loader = HF ? "ld-linux-armhf.so.3"12 : "ld-linux.so.3"45 ; |
4385 | 57 | break; |
4386 | 57 | } |
4387 | 195 | case llvm::Triple::mips: |
4388 | 195 | case llvm::Triple::mipsel: |
4389 | 195 | case llvm::Triple::mips64: |
4390 | 195 | case llvm::Triple::mips64el: { |
4391 | 195 | bool LE = (Triple.getArch() == llvm::Triple::mipsel) || |
4392 | 134 | (Triple.getArch() == llvm::Triple::mips64el); |
4393 | 195 | bool IsNaN2008 = tools::mips::isNaN2008(Args, Triple); |
4394 | 195 | |
4395 | 195 | LibDir = "lib" + tools::mips::getMipsABILibSuffix(Args, Triple); |
4396 | 195 | |
4397 | 195 | if (tools::mips::isUCLibc(Args)) |
4398 | 16 | Loader = IsNaN2008 ? 16 "ld-uClibc-mipsn8.so.0"6 : "ld-uClibc.so.0"10 ; |
4399 | 179 | else if (179 !Triple.hasEnvironment() &&179 |
4400 | 4 | Triple.getVendor() == llvm::Triple::VendorType::MipsTechnologies) |
4401 | 2 | Loader = LE ? 2 "ld-musl-mipsel.so.1"1 : "ld-musl-mips.so.1"1 ; |
4402 | 179 | else |
4403 | 177 | Loader = IsNaN2008 ? 177 "ld-linux-mipsn8.so.1"68 : "ld.so.1"109 ; |
4404 | 195 | |
4405 | 195 | break; |
4406 | 195 | } |
4407 | 10 | case llvm::Triple::ppc: |
4408 | 10 | LibDir = "lib"; |
4409 | 10 | Loader = "ld.so.1"; |
4410 | 10 | break; |
4411 | 59 | case llvm::Triple::ppc64: |
4412 | 59 | LibDir = "lib64"; |
4413 | 59 | Loader = |
4414 | 57 | (tools::ppc::hasPPCAbiArg(Args, "elfv2")) ? "ld64.so.2"2 : "ld64.so.1"57 ; |
4415 | 59 | break; |
4416 | 24 | case llvm::Triple::ppc64le: |
4417 | 24 | LibDir = "lib64"; |
4418 | 24 | Loader = |
4419 | 22 | (tools::ppc::hasPPCAbiArg(Args, "elfv1")) ? "ld64.so.1"2 : "ld64.so.2"22 ; |
4420 | 24 | break; |
4421 | 3 | case llvm::Triple::sparc: |
4422 | 3 | case llvm::Triple::sparcel: |
4423 | 3 | LibDir = "lib"; |
4424 | 3 | Loader = "ld-linux.so.2"; |
4425 | 3 | break; |
4426 | 3 | case llvm::Triple::sparcv9: |
4427 | 3 | LibDir = "lib64"; |
4428 | 3 | Loader = "ld-linux.so.2"; |
4429 | 3 | break; |
4430 | 9 | case llvm::Triple::systemz: |
4431 | 9 | LibDir = "lib"; |
4432 | 9 | Loader = "ld64.so.1"; |
4433 | 9 | break; |
4434 | 114 | case llvm::Triple::x86: |
4435 | 114 | LibDir = "lib"; |
4436 | 114 | Loader = "ld-linux.so.2"; |
4437 | 114 | break; |
4438 | 268 | case llvm::Triple::x86_64: { |
4439 | 268 | bool X32 = Triple.getEnvironment() == llvm::Triple::GNUX32; |
4440 | 268 | |
4441 | 260 | LibDir = X32 ? "libx32"8 : "lib64"260 ; |
4442 | 260 | Loader = X32 ? "ld-linux-x32.so.2"8 : "ld-linux-x86-64.so.2"260 ; |
4443 | 268 | break; |
4444 | 3 | } |
4445 | 752 | } |
4446 | 752 | |
4447 | 752 | if (752 Distro == Distro::Exherbo && 752 (Triple.getVendor() == llvm::Triple::UnknownVendor ||0 |
4448 | 0 | Triple.getVendor() == llvm::Triple::PC)) |
4449 | 0 | return "/usr/" + Triple.str() + "/lib/" + Loader; |
4450 | 752 | return "/" + LibDir + "/" + Loader; |
4451 | 752 | } |
4452 | | |
4453 | | void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
4454 | 2.12k | ArgStringList &CC1Args) const { |
4455 | 2.12k | const Driver &D = getDriver(); |
4456 | 2.12k | std::string SysRoot = computeSysRoot(); |
4457 | 2.12k | |
4458 | 2.12k | if (DriverArgs.hasArg(options::OPT_nostdinc)) |
4459 | 0 | return; |
4460 | 2.12k | |
4461 | 2.12k | if (2.12k !DriverArgs.hasArg(options::OPT_nostdlibinc)2.12k ) |
4462 | 2.12k | addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include"); |
4463 | 2.12k | |
4464 | 2.12k | if (!DriverArgs.hasArg(options::OPT_nobuiltininc)2.12k ) {2.12k |
4465 | 2.12k | SmallString<128> P(D.ResourceDir); |
4466 | 2.12k | llvm::sys::path::append(P, "include"); |
4467 | 2.12k | addSystemInclude(DriverArgs, CC1Args, P); |
4468 | 2.12k | } |
4469 | 2.12k | |
4470 | 2.12k | if (DriverArgs.hasArg(options::OPT_nostdlibinc)) |
4471 | 0 | return; |
4472 | 2.12k | |
4473 | 2.12k | // Check for configure-time C include directories. |
4474 | 2.12k | StringRef CIncludeDirs(2.12k C_INCLUDE_DIRS2.12k ); |
4475 | 2.12k | if (CIncludeDirs != ""2.12k ) {0 |
4476 | 0 | SmallVector<StringRef, 5> dirs; |
4477 | 0 | CIncludeDirs.split(dirs, ":"); |
4478 | 0 | for (StringRef dir : dirs) { |
4479 | 0 | StringRef Prefix = |
4480 | 0 | llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot)0 : ""0 ; |
4481 | 0 | addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); |
4482 | 0 | } |
4483 | 0 | return; |
4484 | 0 | } |
4485 | 2.12k | |
4486 | 2.12k | // Lacking those, try to detect the correct set of system includes for the |
4487 | 2.12k | // target triple. |
4488 | 2.12k | |
4489 | 2.12k | // Add include directories specific to the selected multilib set and multilib. |
4490 | 2.12k | if (2.12k GCCInstallation.isValid()2.12k ) {354 |
4491 | 354 | const auto &Callback = Multilibs.includeDirsCallback(); |
4492 | 354 | if (Callback354 ) {163 |
4493 | 163 | for (const auto &Path : Callback(GCCInstallation.getMultilib())) |
4494 | 298 | addExternCSystemIncludeIfExists( |
4495 | 298 | DriverArgs, CC1Args, GCCInstallation.getInstallPath() + Path); |
4496 | 163 | } |
4497 | 354 | } |
4498 | 2.12k | |
4499 | 2.12k | // Implement generic Debian multiarch support. |
4500 | 2.12k | const StringRef X86_64MultiarchIncludeDirs[] = { |
4501 | 2.12k | "/usr/include/x86_64-linux-gnu", |
4502 | 2.12k | |
4503 | 2.12k | // FIXME: These are older forms of multiarch. It's not clear that they're |
4504 | 2.12k | // in use in any released version of Debian, so we should consider |
4505 | 2.12k | // removing them. |
4506 | 2.12k | "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"}; |
4507 | 2.12k | const StringRef X86MultiarchIncludeDirs[] = { |
4508 | 2.12k | "/usr/include/i386-linux-gnu", |
4509 | 2.12k | |
4510 | 2.12k | // FIXME: These are older forms of multiarch. It's not clear that they're |
4511 | 2.12k | // in use in any released version of Debian, so we should consider |
4512 | 2.12k | // removing them. |
4513 | 2.12k | "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu", |
4514 | 2.12k | "/usr/include/i486-linux-gnu"}; |
4515 | 2.12k | const StringRef AArch64MultiarchIncludeDirs[] = { |
4516 | 2.12k | "/usr/include/aarch64-linux-gnu"}; |
4517 | 2.12k | const StringRef ARMMultiarchIncludeDirs[] = { |
4518 | 2.12k | "/usr/include/arm-linux-gnueabi"}; |
4519 | 2.12k | const StringRef ARMHFMultiarchIncludeDirs[] = { |
4520 | 2.12k | "/usr/include/arm-linux-gnueabihf"}; |
4521 | 2.12k | const StringRef ARMEBMultiarchIncludeDirs[] = { |
4522 | 2.12k | "/usr/include/armeb-linux-gnueabi"}; |
4523 | 2.12k | const StringRef ARMEBHFMultiarchIncludeDirs[] = { |
4524 | 2.12k | "/usr/include/armeb-linux-gnueabihf"}; |
4525 | 2.12k | const StringRef MIPSMultiarchIncludeDirs[] = {"/usr/include/mips-linux-gnu"}; |
4526 | 2.12k | const StringRef MIPSELMultiarchIncludeDirs[] = { |
4527 | 2.12k | "/usr/include/mipsel-linux-gnu"}; |
4528 | 2.12k | const StringRef MIPS64MultiarchIncludeDirs[] = { |
4529 | 2.12k | "/usr/include/mips64-linux-gnu", "/usr/include/mips64-linux-gnuabi64"}; |
4530 | 2.12k | const StringRef MIPS64ELMultiarchIncludeDirs[] = { |
4531 | 2.12k | "/usr/include/mips64el-linux-gnu", |
4532 | 2.12k | "/usr/include/mips64el-linux-gnuabi64"}; |
4533 | 2.12k | const StringRef PPCMultiarchIncludeDirs[] = { |
4534 | 2.12k | "/usr/include/powerpc-linux-gnu"}; |
4535 | 2.12k | const StringRef PPC64MultiarchIncludeDirs[] = { |
4536 | 2.12k | "/usr/include/powerpc64-linux-gnu"}; |
4537 | 2.12k | const StringRef PPC64LEMultiarchIncludeDirs[] = { |
4538 | 2.12k | "/usr/include/powerpc64le-linux-gnu"}; |
4539 | 2.12k | const StringRef SparcMultiarchIncludeDirs[] = { |
4540 | 2.12k | "/usr/include/sparc-linux-gnu"}; |
4541 | 2.12k | const StringRef Sparc64MultiarchIncludeDirs[] = { |
4542 | 2.12k | "/usr/include/sparc64-linux-gnu"}; |
4543 | 2.12k | const StringRef SYSTEMZMultiarchIncludeDirs[] = { |
4544 | 2.12k | "/usr/include/s390x-linux-gnu"}; |
4545 | 2.12k | ArrayRef<StringRef> MultiarchIncludeDirs; |
4546 | 2.12k | switch (getTriple().getArch()) { |
4547 | 715 | case llvm::Triple::x86_64: |
4548 | 715 | MultiarchIncludeDirs = X86_64MultiarchIncludeDirs; |
4549 | 715 | break; |
4550 | 301 | case llvm::Triple::x86: |
4551 | 301 | MultiarchIncludeDirs = X86MultiarchIncludeDirs; |
4552 | 301 | break; |
4553 | 70 | case llvm::Triple::aarch64: |
4554 | 70 | case llvm::Triple::aarch64_be: |
4555 | 70 | MultiarchIncludeDirs = AArch64MultiarchIncludeDirs; |
4556 | 70 | break; |
4557 | 328 | case llvm::Triple::arm: |
4558 | 328 | case llvm::Triple::thumb: |
4559 | 328 | if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) |
4560 | 15 | MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs; |
4561 | 328 | else |
4562 | 313 | MultiarchIncludeDirs = ARMMultiarchIncludeDirs; |
4563 | 328 | break; |
4564 | 43 | case llvm::Triple::armeb: |
4565 | 43 | case llvm::Triple::thumbeb: |
4566 | 43 | if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) |
4567 | 2 | MultiarchIncludeDirs = ARMEBHFMultiarchIncludeDirs; |
4568 | 43 | else |
4569 | 41 | MultiarchIncludeDirs = ARMEBMultiarchIncludeDirs; |
4570 | 43 | break; |
4571 | 192 | case llvm::Triple::mips: |
4572 | 192 | MultiarchIncludeDirs = MIPSMultiarchIncludeDirs; |
4573 | 192 | break; |
4574 | 96 | case llvm::Triple::mipsel: |
4575 | 96 | MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs; |
4576 | 96 | break; |
4577 | 74 | case llvm::Triple::mips64: |
4578 | 74 | MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs; |
4579 | 74 | break; |
4580 | 70 | case llvm::Triple::mips64el: |
4581 | 70 | MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs; |
4582 | 70 | break; |
4583 | 17 | case llvm::Triple::ppc: |
4584 | 17 | MultiarchIncludeDirs = PPCMultiarchIncludeDirs; |
4585 | 17 | break; |
4586 | 97 | case llvm::Triple::ppc64: |
4587 | 97 | MultiarchIncludeDirs = PPC64MultiarchIncludeDirs; |
4588 | 97 | break; |
4589 | 45 | case llvm::Triple::ppc64le: |
4590 | 45 | MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs; |
4591 | 45 | break; |
4592 | 15 | case llvm::Triple::sparc: |
4593 | 15 | MultiarchIncludeDirs = SparcMultiarchIncludeDirs; |
4594 | 15 | break; |
4595 | 17 | case llvm::Triple::sparcv9: |
4596 | 17 | MultiarchIncludeDirs = Sparc64MultiarchIncludeDirs; |
4597 | 17 | break; |
4598 | 27 | case llvm::Triple::systemz: |
4599 | 27 | MultiarchIncludeDirs = SYSTEMZMultiarchIncludeDirs; |
4600 | 27 | break; |
4601 | 17 | default: |
4602 | 17 | break; |
4603 | 2.12k | } |
4604 | 4.55k | for (StringRef Dir : MultiarchIncludeDirs) 2.12k {4.55k |
4605 | 4.55k | if (D.getVFS().exists(SysRoot + Dir)4.55k ) {42 |
4606 | 42 | addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + Dir); |
4607 | 42 | break; |
4608 | 42 | } |
4609 | 4.55k | } |
4610 | 2.12k | |
4611 | 2.12k | if (getTriple().getOS() == llvm::Triple::RTEMS) |
4612 | 0 | return; |
4613 | 2.12k | |
4614 | 2.12k | // Add an include of '/include' directly. This isn't provided by default by |
4615 | 2.12k | // system GCCs, but is often used with cross-compiling GCCs, and harmless to |
4616 | 2.12k | // add even when Clang is acting as-if it were a system compiler. |
4617 | 2.12k | addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); |
4618 | 2.12k | |
4619 | 2.12k | addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); |
4620 | 2.12k | } |
4621 | | |
4622 | 21 | static std::string DetectLibcxxIncludePath(StringRef base) { |
4623 | 21 | std::error_code EC; |
4624 | 21 | int MaxVersion = 0; |
4625 | 21 | std::string MaxVersionString = ""; |
4626 | 36 | for (llvm::sys::fs::directory_iterator LI(base, EC), LE; !EC && 36 LI != LE25 ; |
4627 | 15 | LI = LI.increment(EC)15 ) {15 |
4628 | 15 | StringRef VersionText = llvm::sys::path::filename(LI->path()); |
4629 | 15 | int Version; |
4630 | 15 | if (VersionText[0] == 'v' && |
4631 | 14 | !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)14 ) {14 |
4632 | 14 | if (Version > MaxVersion14 ) {14 |
4633 | 14 | MaxVersion = Version; |
4634 | 14 | MaxVersionString = VersionText; |
4635 | 14 | } |
4636 | 14 | } |
4637 | 15 | } |
4638 | 11 | return MaxVersion ? (base + "/" + MaxVersionString).str()10 : ""11 ; |
4639 | 21 | } |
4640 | | |
4641 | 7 | std::string Linux::findLibCxxIncludePath() const { |
4642 | 7 | const std::string LibCXXIncludePathCandidates[] = { |
4643 | 7 | DetectLibcxxIncludePath(getDriver().Dir + "/../include/c++"), |
4644 | 7 | // If this is a development, non-installed, clang, libcxx will |
4645 | 7 | // not be found at ../include/c++ but it likely to be found at |
4646 | 7 | // one of the following two locations: |
4647 | 7 | DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/local/include/c++"), |
4648 | 7 | DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/include/c++") }; |
4649 | 15 | for (const auto &IncludePath : LibCXXIncludePathCandidates) { |
4650 | 15 | if (IncludePath.empty() || 15 !getVFS().exists(IncludePath)7 ) |
4651 | 8 | continue; |
4652 | 15 | // Use the first candidate that exists. |
4653 | 7 | return IncludePath; |
4654 | 15 | } |
4655 | 0 | return ""; |
4656 | 7 | } |
4657 | | |
4658 | | void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, |
4659 | 679 | llvm::opt::ArgStringList &CC1Args) const { |
4660 | 679 | // We need a detected GCC installation on Linux to provide libstdc++'s |
4661 | 679 | // headers. |
4662 | 679 | if (!GCCInstallation.isValid()) |
4663 | 456 | return; |
4664 | 679 | |
4665 | 679 | // By default, look for the C++ headers in an include directory adjacent to |
4666 | 679 | // the lib directory of the GCC installation. Note that this is expect to be |
4667 | 679 | // equivalent to '/usr/include/c++/X.Y' in almost all cases. |
4668 | 223 | StringRef LibDir = GCCInstallation.getParentLibPath(); |
4669 | 223 | StringRef InstallDir = GCCInstallation.getInstallPath(); |
4670 | 223 | StringRef TripleStr = GCCInstallation.getTriple().str(); |
4671 | 223 | const Multilib &Multilib = GCCInstallation.getMultilib(); |
4672 | 223 | const std::string GCCMultiarchTriple = getMultiarchTriple( |
4673 | 223 | getDriver(), GCCInstallation.getTriple(), getDriver().SysRoot); |
4674 | 223 | const std::string TargetMultiarchTriple = |
4675 | 223 | getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot); |
4676 | 223 | const GCCVersion &Version = GCCInstallation.getVersion(); |
4677 | 223 | |
4678 | 223 | // The primary search for libstdc++ supports multiarch variants. |
4679 | 223 | if (addLibStdCXXIncludePaths(LibDir.str() + "/../include", |
4680 | 223 | "/c++/" + Version.Text, TripleStr, |
4681 | 223 | GCCMultiarchTriple, TargetMultiarchTriple, |
4682 | 223 | Multilib.includeSuffix(), DriverArgs, CC1Args)) |
4683 | 42 | return; |
4684 | 223 | |
4685 | 223 | // Otherwise, fall back on a bunch of options which don't use multiarch |
4686 | 223 | // layouts for simplicity. |
4687 | 181 | const std::string LibStdCXXIncludePathCandidates[] = { |
4688 | 181 | // Gentoo is weird and places its headers inside the GCC install, |
4689 | 181 | // so if the first attempt to find the headers fails, try these patterns. |
4690 | 181 | InstallDir.str() + "/include/g++-v" + Version.Text, |
4691 | 181 | InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." + |
4692 | 181 | Version.MinorStr, |
4693 | 181 | InstallDir.str() + "/include/g++-v" + Version.MajorStr, |
4694 | 181 | // Android standalone toolchain has C++ headers in yet another place. |
4695 | 181 | LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text, |
4696 | 181 | // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++, |
4697 | 181 | // without a subdirectory corresponding to the gcc version. |
4698 | 181 | LibDir.str() + "/../include/c++", |
4699 | 181 | }; |
4700 | 181 | |
4701 | 716 | for (const auto &IncludePath : LibStdCXXIncludePathCandidates) { |
4702 | 716 | if (addLibStdCXXIncludePaths(IncludePath, /*Suffix*/ "", TripleStr, |
4703 | 716 | /*GCCMultiarchTriple*/ "", |
4704 | 716 | /*TargetMultiarchTriple*/ "", |
4705 | 716 | Multilib.includeSuffix(), DriverArgs, CC1Args)) |
4706 | 174 | break; |
4707 | 716 | } |
4708 | 181 | } |
4709 | | |
4710 | | void Linux::AddCudaIncludeArgs(const ArgList &DriverArgs, |
4711 | 82 | ArgStringList &CC1Args) const { |
4712 | 82 | CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); |
4713 | 82 | } |
4714 | | |
4715 | | void Linux::AddIAMCUIncludeArgs(const ArgList &DriverArgs, |
4716 | 9 | ArgStringList &CC1Args) const { |
4717 | 9 | if (GCCInstallation.isValid()9 ) {0 |
4718 | 0 | CC1Args.push_back("-isystem"); |
4719 | 0 | CC1Args.push_back(DriverArgs.MakeArgString( |
4720 | 0 | GCCInstallation.getParentLibPath() + "/../" + |
4721 | 0 | GCCInstallation.getTriple().str() + "/include")); |
4722 | 0 | } |
4723 | 9 | } |
4724 | | |
4725 | 3.32k | bool Linux::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); } |
4726 | | |
4727 | 2.13k | SanitizerMask Linux::getSupportedSanitizers() const { |
4728 | 2.13k | const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; |
4729 | 2.13k | const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; |
4730 | 2.13k | const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 || |
4731 | 2.05k | getTriple().getArch() == llvm::Triple::mips64el; |
4732 | 2.13k | const bool IsPowerPC64 = getTriple().getArch() == llvm::Triple::ppc64 || |
4733 | 2.04k | getTriple().getArch() == llvm::Triple::ppc64le; |
4734 | 2.13k | const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64 || |
4735 | 2.06k | getTriple().getArch() == llvm::Triple::aarch64_be; |
4736 | 2.13k | SanitizerMask Res = ToolChain::getSupportedSanitizers(); |
4737 | 2.13k | Res |= SanitizerKind::Address; |
4738 | 2.13k | Res |= SanitizerKind::KernelAddress; |
4739 | 2.13k | Res |= SanitizerKind::Vptr; |
4740 | 2.13k | Res |= SanitizerKind::SafeStack; |
4741 | 2.13k | if (IsX86_64 || 2.13k IsMIPS641.54k || IsAArch641.39k ) |
4742 | 814 | Res |= SanitizerKind::DataFlow; |
4743 | 2.13k | if (IsX86_64 || 2.13k IsMIPS641.54k || IsAArch641.39k || IsX861.32k ) |
4744 | 1.10k | Res |= SanitizerKind::Leak; |
4745 | 2.13k | if (IsX86_64 || 2.13k IsMIPS641.54k || IsAArch641.39k || IsPowerPC641.32k ) |
4746 | 968 | Res |= SanitizerKind::Thread; |
4747 | 2.13k | if (IsX86_64 || 2.13k IsMIPS641.54k || IsPowerPC641.39k || IsAArch641.24k ) |
4748 | 968 | Res |= SanitizerKind::Memory; |
4749 | 2.13k | if (IsX86_64 || 2.13k IsMIPS641.54k ) |
4750 | 742 | Res |= SanitizerKind::Efficiency; |
4751 | 2.13k | if (IsX86 || 2.13k IsX86_641.85k ) {876 |
4752 | 876 | Res |= SanitizerKind::Function; |
4753 | 876 | } |
4754 | 2.13k | return Res; |
4755 | 2.13k | } |
4756 | | |
4757 | | void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args, |
4758 | 936 | llvm::opt::ArgStringList &CmdArgs) const { |
4759 | 936 | if (!needsProfileRT(Args)936 ) return928 ; |
4760 | 936 | |
4761 | 936 | // Add linker option -u__llvm_runtime_variable to cause runtime |
4762 | 936 | // initialization module to be linked in. |
4763 | 8 | if (8 !Args.hasArg(options::OPT_coverage)8 ) |
4764 | 5 | CmdArgs.push_back(Args.MakeArgString( |
4765 | 5 | Twine("-u", llvm::getInstrProfRuntimeHookVarName()))); |
4766 | 8 | ToolChain::addProfileRTLibs(Args, CmdArgs); |
4767 | 8 | } |
4768 | | |
4769 | | /// Fuchsia - Fuchsia tool chain which can call as(1) and ld(1) directly. |
4770 | | |
4771 | | Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple, |
4772 | | const ArgList &Args) |
4773 | 9 | : Generic_ELF(D, Triple, Args) { |
4774 | 9 | |
4775 | 9 | getFilePaths().push_back(D.SysRoot + "/lib"); |
4776 | 9 | getFilePaths().push_back(D.ResourceDir + "/lib/fuchsia"); |
4777 | 9 | } |
4778 | | |
4779 | 0 | Tool *Fuchsia::buildAssembler() const { |
4780 | 0 | return new tools::gnutools::Assembler(*this); |
4781 | 0 | } |
4782 | | |
4783 | 9 | Tool *Fuchsia::buildLinker() const { |
4784 | 9 | return new tools::fuchsia::Linker(*this); |
4785 | 9 | } |
4786 | | |
4787 | | ToolChain::RuntimeLibType Fuchsia::GetRuntimeLibType( |
4788 | 9 | const ArgList &Args) const { |
4789 | 9 | if (Arg *A9 = Args.getLastArg(options::OPT_rtlib_EQ)) {1 |
4790 | 1 | StringRef Value = A->getValue(); |
4791 | 1 | if (Value != "compiler-rt") |
4792 | 1 | getDriver().Diag(diag::err_drv_invalid_rtlib_name) |
4793 | 1 | << A->getAsString(Args); |
4794 | 1 | } |
4795 | 9 | |
4796 | 9 | return ToolChain::RLT_CompilerRT; |
4797 | 9 | } |
4798 | | |
4799 | | ToolChain::CXXStdlibType |
4800 | 6 | Fuchsia::GetCXXStdlibType(const ArgList &Args) const { |
4801 | 6 | if (Arg *A6 = Args.getLastArg(options::OPT_stdlib_EQ)) {2 |
4802 | 2 | StringRef Value = A->getValue(); |
4803 | 2 | if (Value != "libc++") |
4804 | 2 | getDriver().Diag(diag::err_drv_invalid_stdlib_name) |
4805 | 2 | << A->getAsString(Args); |
4806 | 2 | } |
4807 | 6 | |
4808 | 6 | return ToolChain::CST_Libcxx; |
4809 | 6 | } |
4810 | | |
4811 | | void Fuchsia::addClangTargetOptions(const ArgList &DriverArgs, |
4812 | 9 | ArgStringList &CC1Args) const { |
4813 | 9 | if (DriverArgs.hasFlag(options::OPT_fuse_init_array, |
4814 | 9 | options::OPT_fno_use_init_array, true)) |
4815 | 9 | CC1Args.push_back("-fuse-init-array"); |
4816 | 9 | } |
4817 | | |
4818 | | void Fuchsia::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
4819 | 9 | ArgStringList &CC1Args) const { |
4820 | 9 | const Driver &D = getDriver(); |
4821 | 9 | |
4822 | 9 | if (DriverArgs.hasArg(options::OPT_nostdinc)) |
4823 | 0 | return; |
4824 | 9 | |
4825 | 9 | if (9 !DriverArgs.hasArg(options::OPT_nobuiltininc)9 ) {9 |
4826 | 9 | SmallString<128> P(D.ResourceDir); |
4827 | 9 | llvm::sys::path::append(P, "include"); |
4828 | 9 | addSystemInclude(DriverArgs, CC1Args, P); |
4829 | 9 | } |
4830 | 9 | |
4831 | 9 | if (DriverArgs.hasArg(options::OPT_nostdlibinc)) |
4832 | 0 | return; |
4833 | 9 | |
4834 | 9 | // Check for configure-time C include directories. |
4835 | 9 | StringRef CIncludeDirs(9 C_INCLUDE_DIRS9 ); |
4836 | 9 | if (CIncludeDirs != ""9 ) {0 |
4837 | 0 | SmallVector<StringRef, 5> dirs; |
4838 | 0 | CIncludeDirs.split(dirs, ":"); |
4839 | 0 | for (StringRef dir : dirs) { |
4840 | 0 | StringRef Prefix = |
4841 | 0 | llvm::sys::path::is_absolute(dir) ? StringRef(D.SysRoot)0 : ""0 ; |
4842 | 0 | addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); |
4843 | 0 | } |
4844 | 0 | return; |
4845 | 0 | } |
4846 | 9 | |
4847 | 9 | addExternCSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/include"); |
4848 | 9 | } |
4849 | | |
4850 | 3 | std::string Fuchsia::findLibCxxIncludePath() const { |
4851 | 3 | return getDriver().SysRoot + "/include/c++/v1"; |
4852 | 3 | } |
4853 | | |
4854 | | void Fuchsia::AddCXXStdlibLibArgs(const ArgList &Args, |
4855 | 3 | ArgStringList &CmdArgs) const { |
4856 | 3 | (void) GetCXXStdlibType(Args); |
4857 | 3 | CmdArgs.push_back("-lc++"); |
4858 | 3 | CmdArgs.push_back("-lc++abi"); |
4859 | 3 | CmdArgs.push_back("-lunwind"); |
4860 | 3 | } |
4861 | | |
4862 | 9 | SanitizerMask Fuchsia::getSupportedSanitizers() const { |
4863 | 9 | SanitizerMask Res = ToolChain::getSupportedSanitizers(); |
4864 | 9 | Res |= SanitizerKind::SafeStack; |
4865 | 9 | return Res; |
4866 | 9 | } |
4867 | | |
4868 | | /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. |
4869 | | |
4870 | | DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple, |
4871 | | const ArgList &Args) |
4872 | 2 | : Generic_ELF(D, Triple, Args) { |
4873 | 2 | |
4874 | 2 | // Path mangling to find libexec |
4875 | 2 | getProgramPaths().push_back(getDriver().getInstalledDir()); |
4876 | 2 | if (getDriver().getInstalledDir() != getDriver().Dir) |
4877 | 1 | getProgramPaths().push_back(getDriver().Dir); |
4878 | 2 | |
4879 | 2 | getFilePaths().push_back(getDriver().Dir + "/../lib"); |
4880 | 2 | getFilePaths().push_back("/usr/lib"); |
4881 | 2 | getFilePaths().push_back("/usr/lib/gcc50"); |
4882 | 2 | } |
4883 | | |
4884 | 0 | Tool *DragonFly::buildAssembler() const { |
4885 | 0 | return new tools::dragonfly::Assembler(*this); |
4886 | 0 | } |
4887 | | |
4888 | 1 | Tool *DragonFly::buildLinker() const { |
4889 | 1 | return new tools::dragonfly::Linker(*this); |
4890 | 1 | } |
4891 | | |
4892 | | /// CUDA toolchain. Our assembler is ptxas, and our "linker" is fatbinary, |
4893 | | /// which isn't properly a linker but nonetheless performs the step of stitching |
4894 | | /// together object files from the assembler into a single blob. |
4895 | | |
4896 | | CudaToolChain::CudaToolChain(const Driver &D, const llvm::Triple &Triple, |
4897 | | const ToolChain &HostTC, const ArgList &Args) |
4898 | | : ToolChain(D, Triple, Args), HostTC(HostTC), |
4899 | 169 | CudaInstallation(D, HostTC.getTriple(), Args) { |
4900 | 169 | if (CudaInstallation.isValid()) |
4901 | 28 | getProgramPaths().push_back(CudaInstallation.getBinPath()); |
4902 | 169 | } |
4903 | | |
4904 | | void CudaToolChain::addClangTargetOptions( |
4905 | | const llvm::opt::ArgList &DriverArgs, |
4906 | 131 | llvm::opt::ArgStringList &CC1Args) const { |
4907 | 131 | HostTC.addClangTargetOptions(DriverArgs, CC1Args); |
4908 | 131 | |
4909 | 131 | CC1Args.push_back("-fcuda-is-device"); |
4910 | 131 | |
4911 | 131 | if (DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero, |
4912 | 131 | options::OPT_fno_cuda_flush_denormals_to_zero, false)) |
4913 | 0 | CC1Args.push_back("-fcuda-flush-denormals-to-zero"); |
4914 | 131 | |
4915 | 131 | if (DriverArgs.hasFlag(options::OPT_fcuda_approx_transcendentals, |
4916 | 131 | options::OPT_fno_cuda_approx_transcendentals, false)) |
4917 | 1 | CC1Args.push_back("-fcuda-approx-transcendentals"); |
4918 | 131 | |
4919 | 131 | if (DriverArgs.hasArg(options::OPT_nocudalib)) |
4920 | 18 | return; |
4921 | 131 | |
4922 | 113 | StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_march_EQ); |
4923 | 113 | assert(!GpuArch.empty() && "Must have an explicit GPU arch."); |
4924 | 113 | std::string LibDeviceFile = CudaInstallation.getLibDeviceFile(GpuArch); |
4925 | 113 | |
4926 | 113 | if (LibDeviceFile.empty()113 ) {91 |
4927 | 91 | getDriver().Diag(diag::err_drv_no_cuda_libdevice) << GpuArch; |
4928 | 91 | return; |
4929 | 91 | } |
4930 | 113 | |
4931 | 22 | CC1Args.push_back("-mlink-cuda-bitcode"); |
4932 | 22 | CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile)); |
4933 | 22 | |
4934 | 22 | // Libdevice in CUDA-7.0 requires PTX version that's more recent |
4935 | 22 | // than LLVM defaults to. Use PTX4.2 which is the PTX version that |
4936 | 22 | // came with CUDA-7.0. |
4937 | 22 | CC1Args.push_back("-target-feature"); |
4938 | 22 | CC1Args.push_back("+ptx42"); |
4939 | 22 | } |
4940 | | |
4941 | | void CudaToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs, |
4942 | 127 | ArgStringList &CC1Args) const { |
4943 | 127 | // Check our CUDA version if we're going to include the CUDA headers. |
4944 | 127 | if (!DriverArgs.hasArg(options::OPT_nocudainc) && |
4945 | 105 | !DriverArgs.hasArg(options::OPT_no_cuda_version_check)105 ) {104 |
4946 | 104 | StringRef Arch = DriverArgs.getLastArgValue(options::OPT_march_EQ); |
4947 | 104 | assert(!Arch.empty() && "Must have an explicit GPU arch."); |
4948 | 104 | CudaInstallation.CheckCudaVersionSupportsArch(StringToCudaArch(Arch)); |
4949 | 104 | } |
4950 | 127 | CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); |
4951 | 127 | } |
4952 | | |
4953 | | llvm::opt::DerivedArgList * |
4954 | | CudaToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args, |
4955 | | StringRef BoundArch, |
4956 | 224 | Action::OffloadKind DeviceOffloadKind) const { |
4957 | 224 | DerivedArgList *DAL = |
4958 | 224 | HostTC.TranslateArgs(Args, BoundArch, DeviceOffloadKind); |
4959 | 224 | if (!DAL) |
4960 | 184 | DAL = new DerivedArgList(Args.getBaseArgs()); |
4961 | 224 | |
4962 | 224 | const OptTable &Opts = getDriver().getOpts(); |
4963 | 224 | |
4964 | 1.53k | for (Arg *A : Args) { |
4965 | 1.53k | if (A->getOption().matches(options::OPT_Xarch__)1.53k ) {0 |
4966 | 0 | // Skip this argument unless the architecture matches BoundArch |
4967 | 0 | if (BoundArch.empty() || 0 A->getValue(0) != BoundArch0 ) |
4968 | 0 | continue; |
4969 | 0 |
|
4970 | 0 | unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1)); |
4971 | 0 | unsigned Prev = Index; |
4972 | 0 | std::unique_ptr<Arg> XarchArg(Opts.ParseOneArg(Args, Index)); |
4973 | 0 |
|
4974 | 0 | // If the argument parsing failed or more than one argument was |
4975 | 0 | // consumed, the -Xarch_ argument's parameter tried to consume |
4976 | 0 | // extra arguments. Emit an error and ignore. |
4977 | 0 | // |
4978 | 0 | // We also want to disallow any options which would alter the |
4979 | 0 | // driver behavior; that isn't going to work in our model. We |
4980 | 0 | // use isDriverOption() as an approximation, although things |
4981 | 0 | // like -O4 are going to slip through. |
4982 | 0 | if (!XarchArg || 0 Index > Prev + 10 ) {0 |
4983 | 0 | getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args) |
4984 | 0 | << A->getAsString(Args); |
4985 | 0 | continue; |
4986 | 0 | } else if (0 XarchArg->getOption().hasFlag(options::DriverOption)0 ) {0 |
4987 | 0 | getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver) |
4988 | 0 | << A->getAsString(Args); |
4989 | 0 | continue; |
4990 | 0 | } |
4991 | 0 | XarchArg->setBaseArg(A); |
4992 | 0 | A = XarchArg.release(); |
4993 | 0 | DAL->AddSynthesizedArg(A); |
4994 | 0 | } |
4995 | 1.53k | DAL->append(A); |
4996 | 1.53k | } |
4997 | 224 | |
4998 | 224 | if (!BoundArch.empty()224 ) {139 |
4999 | 139 | DAL->eraseArg(options::OPT_march_EQ); |
5000 | 139 | DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ), BoundArch); |
5001 | 139 | } |
5002 | 224 | return DAL; |
5003 | 224 | } |
5004 | | |
5005 | 97 | Tool *CudaToolChain::buildAssembler() const { |
5006 | 97 | return new tools::NVPTX::Assembler(*this); |
5007 | 97 | } |
5008 | | |
5009 | 85 | Tool *CudaToolChain::buildLinker() const { |
5010 | 85 | return new tools::NVPTX::Linker(*this); |
5011 | 85 | } |
5012 | | |
5013 | 131 | void CudaToolChain::addClangWarningOptions(ArgStringList &CC1Args) const { |
5014 | 131 | HostTC.addClangWarningOptions(CC1Args); |
5015 | 131 | } |
5016 | | |
5017 | | ToolChain::CXXStdlibType |
5018 | 0 | CudaToolChain::GetCXXStdlibType(const ArgList &Args) const { |
5019 | 0 | return HostTC.GetCXXStdlibType(Args); |
5020 | 0 | } |
5021 | | |
5022 | | void CudaToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
5023 | 237 | ArgStringList &CC1Args) const { |
5024 | 237 | HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args); |
5025 | 237 | } |
5026 | | |
5027 | | void CudaToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &Args, |
5028 | 237 | ArgStringList &CC1Args) const { |
5029 | 237 | HostTC.AddClangCXXStdlibIncludeArgs(Args, CC1Args); |
5030 | 237 | } |
5031 | | |
5032 | | void CudaToolChain::AddIAMCUIncludeArgs(const ArgList &Args, |
5033 | 0 | ArgStringList &CC1Args) const { |
5034 | 0 | HostTC.AddIAMCUIncludeArgs(Args, CC1Args); |
5035 | 0 | } |
5036 | | |
5037 | 119 | SanitizerMask CudaToolChain::getSupportedSanitizers() const { |
5038 | 119 | // The CudaToolChain only supports sanitizers in the sense that it allows |
5039 | 119 | // sanitizer arguments on the command line if they are supported by the host |
5040 | 119 | // toolchain. The CudaToolChain will actually ignore any command line |
5041 | 119 | // arguments for any of these "supported" sanitizers. That means that no |
5042 | 119 | // sanitization of device code is actually supported at this time. |
5043 | 119 | // |
5044 | 119 | // This behavior is necessary because the host and device toolchains |
5045 | 119 | // invocations often share the command line, so the device toolchain must |
5046 | 119 | // tolerate flags meant only for the host toolchain. |
5047 | 119 | return HostTC.getSupportedSanitizers(); |
5048 | 119 | } |
5049 | | |
5050 | | VersionTuple CudaToolChain::computeMSVCVersion(const Driver *D, |
5051 | 131 | const ArgList &Args) const { |
5052 | 131 | return HostTC.computeMSVCVersion(D, Args); |
5053 | 131 | } |
5054 | | |
5055 | | /// XCore tool chain |
5056 | | XCoreToolChain::XCoreToolChain(const Driver &D, const llvm::Triple &Triple, |
5057 | | const ArgList &Args) |
5058 | 4 | : ToolChain(D, Triple, Args) { |
5059 | 4 | // ProgramPaths are found via 'PATH' environment variable. |
5060 | 4 | } |
5061 | | |
5062 | 4 | Tool *XCoreToolChain::buildAssembler() const { |
5063 | 4 | return new tools::XCore::Assembler(*this); |
5064 | 4 | } |
5065 | | |
5066 | 4 | Tool *XCoreToolChain::buildLinker() const { |
5067 | 4 | return new tools::XCore::Linker(*this); |
5068 | 4 | } |
5069 | | |
5070 | 4 | bool XCoreToolChain::isPICDefault() const { return false; } |
5071 | | |
5072 | 4 | bool XCoreToolChain::isPIEDefault() const { return false; } |
5073 | | |
5074 | 4 | bool XCoreToolChain::isPICDefaultForced() const { return false; } |
5075 | | |
5076 | 8 | bool XCoreToolChain::SupportsProfiling() const { return false; } |
5077 | | |
5078 | 0 | bool XCoreToolChain::hasBlocksRuntime() const { return false; } |
5079 | | |
5080 | | void XCoreToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
5081 | 4 | ArgStringList &CC1Args) const { |
5082 | 4 | if (DriverArgs.hasArg(options::OPT_nostdinc) || |
5083 | 4 | DriverArgs.hasArg(options::OPT_nostdlibinc)) |
5084 | 0 | return; |
5085 | 4 | if (const char *4 cl_include_dir4 = getenv("XCC_C_INCLUDE_PATH")) {0 |
5086 | 0 | SmallVector<StringRef, 4> Dirs; |
5087 | 0 | const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'}; |
5088 | 0 | StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr)); |
5089 | 0 | ArrayRef<StringRef> DirVec(Dirs); |
5090 | 0 | addSystemIncludes(DriverArgs, CC1Args, DirVec); |
5091 | 0 | } |
5092 | 4 | } |
5093 | | |
5094 | | void XCoreToolChain::addClangTargetOptions(const ArgList &DriverArgs, |
5095 | 4 | ArgStringList &CC1Args) const { |
5096 | 4 | CC1Args.push_back("-nostdsysteminc"); |
5097 | 4 | } |
5098 | | |
5099 | | void XCoreToolChain::AddClangCXXStdlibIncludeArgs( |
5100 | 2 | const ArgList &DriverArgs, ArgStringList &CC1Args) const { |
5101 | 2 | if (DriverArgs.hasArg(options::OPT_nostdinc) || |
5102 | 2 | DriverArgs.hasArg(options::OPT_nostdlibinc) || |
5103 | 2 | DriverArgs.hasArg(options::OPT_nostdincxx)) |
5104 | 0 | return; |
5105 | 2 | if (const char *2 cl_include_dir2 = getenv("XCC_CPLUS_INCLUDE_PATH")) {0 |
5106 | 0 | SmallVector<StringRef, 4> Dirs; |
5107 | 0 | const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'}; |
5108 | 0 | StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr)); |
5109 | 0 | ArrayRef<StringRef> DirVec(Dirs); |
5110 | 0 | addSystemIncludes(DriverArgs, CC1Args, DirVec); |
5111 | 0 | } |
5112 | 2 | } |
5113 | | |
5114 | | void XCoreToolChain::AddCXXStdlibLibArgs(const ArgList &Args, |
5115 | 0 | ArgStringList &CmdArgs) const { |
5116 | 0 | // We don't output any lib args. This is handled by xcc. |
5117 | 0 | } |
5118 | | |
5119 | | MyriadToolChain::MyriadToolChain(const Driver &D, const llvm::Triple &Triple, |
5120 | | const ArgList &Args) |
5121 | 22 | : Generic_ELF(D, Triple, Args) { |
5122 | 22 | // If a target of 'sparc-myriad-elf' is specified to clang, it wants to use |
5123 | 22 | // 'sparc-myriad--elf' (note the unknown OS) as the canonical triple. |
5124 | 22 | // This won't work to find gcc. Instead we give the installation detector an |
5125 | 22 | // extra triple, which is preferable to further hacks of the logic that at |
5126 | 22 | // present is based solely on getArch(). In particular, it would be wrong to |
5127 | 22 | // choose the myriad installation when targeting a non-myriad sparc install. |
5128 | 22 | switch (Triple.getArch()) { |
5129 | 1 | default: |
5130 | 1 | D.Diag(diag::err_target_unsupported_arch) << Triple.getArchName() |
5131 | 1 | << "myriad"; |
5132 | 22 | case llvm::Triple::sparc: |
5133 | 22 | case llvm::Triple::sparcel: |
5134 | 22 | case llvm::Triple::shave: |
5135 | 22 | GCCInstallation.init(Triple, Args, {"sparc-myriad-elf"}); |
5136 | 22 | } |
5137 | 22 | |
5138 | 22 | if (22 GCCInstallation.isValid()22 ) {3 |
5139 | 3 | // This directory contains crt{i,n,begin,end}.o as well as libgcc. |
5140 | 3 | // These files are tied to a particular version of gcc. |
5141 | 3 | SmallString<128> CompilerSupportDir(GCCInstallation.getInstallPath()); |
5142 | 3 | addPathIfExists(D, CompilerSupportDir, getFilePaths()); |
5143 | 3 | } |
5144 | 22 | // libstd++ and libc++ must both be found in this one place. |
5145 | 22 | addPathIfExists(D, D.Dir + "/../sparc-myriad-elf/lib", getFilePaths()); |
5146 | 22 | } |
5147 | | |
5148 | 22 | MyriadToolChain::~MyriadToolChain() {} |
5149 | | |
5150 | | void MyriadToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
5151 | 15 | ArgStringList &CC1Args) const { |
5152 | 15 | if (!DriverArgs.hasArg(options::OPT_nostdinc)) |
5153 | 14 | addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include"); |
5154 | 15 | } |
5155 | | |
5156 | 1 | std::string MyriadToolChain::findLibCxxIncludePath() const { |
5157 | 1 | std::string Path(getDriver().getInstalledDir()); |
5158 | 1 | return Path + "/../include/c++/v1"; |
5159 | 1 | } |
5160 | | |
5161 | | void MyriadToolChain::addLibStdCxxIncludePaths( |
5162 | | const llvm::opt::ArgList &DriverArgs, |
5163 | 2 | llvm::opt::ArgStringList &CC1Args) const { |
5164 | 2 | StringRef LibDir = GCCInstallation.getParentLibPath(); |
5165 | 2 | const GCCVersion &Version = GCCInstallation.getVersion(); |
5166 | 2 | StringRef TripleStr = GCCInstallation.getTriple().str(); |
5167 | 2 | const Multilib &Multilib = GCCInstallation.getMultilib(); |
5168 | 2 | addLibStdCXXIncludePaths( |
5169 | 2 | LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text, |
5170 | 2 | "", TripleStr, "", "", Multilib.includeSuffix(), DriverArgs, CC1Args); |
5171 | 2 | } |
5172 | | |
5173 | | // MyriadToolChain handles several triples: |
5174 | | // {shave,sparc{,el}}-myriad-{rtems,unknown}-elf |
5175 | 40 | Tool *MyriadToolChain::SelectTool(const JobAction &JA) const { |
5176 | 40 | // The inherited method works fine if not targeting the SHAVE. |
5177 | 40 | if (!isShaveCompilation(getTriple())) |
5178 | 28 | return ToolChain::SelectTool(JA); |
5179 | 12 | switch (JA.getKind()) { |
5180 | 7 | case Action::PreprocessJobClass: |
5181 | 7 | case Action::CompileJobClass: |
5182 | 7 | if (!Compiler) |
5183 | 7 | Compiler.reset(new tools::SHAVE::Compiler(*this)); |
5184 | 7 | return Compiler.get(); |
5185 | 5 | case Action::AssembleJobClass: |
5186 | 5 | if (!Assembler) |
5187 | 5 | Assembler.reset(new tools::SHAVE::Assembler(*this)); |
5188 | 5 | return Assembler.get(); |
5189 | 0 | default: |
5190 | 0 | return ToolChain::getTool(JA.getKind()); |
5191 | 12 | } |
5192 | 12 | } |
5193 | | |
5194 | 5 | Tool *MyriadToolChain::buildLinker() const { |
5195 | 5 | return new tools::Myriad::Linker(*this); |
5196 | 5 | } |
5197 | | |
5198 | 15 | SanitizerMask MyriadToolChain::getSupportedSanitizers() const { |
5199 | 15 | return SanitizerKind::Address; |
5200 | 15 | } |
5201 | | |
5202 | | WebAssembly::WebAssembly(const Driver &D, const llvm::Triple &Triple, |
5203 | | const llvm::opt::ArgList &Args) |
5204 | 21 | : ToolChain(D, Triple, Args) { |
5205 | 21 | |
5206 | 21 | assert(Triple.isArch32Bit() != Triple.isArch64Bit()); |
5207 | 21 | getFilePaths().push_back( |
5208 | 14 | getDriver().SysRoot + "/lib" + (Triple.isArch32Bit() ? "32"14 : "64"7 )); |
5209 | 21 | } |
5210 | | |
5211 | 21 | bool WebAssembly::IsMathErrnoDefault() const { return false; } |
5212 | | |
5213 | 21 | bool WebAssembly::IsObjCNonFragileABIDefault() const { return true; } |
5214 | | |
5215 | 0 | bool WebAssembly::UseObjCMixedDispatch() const { return true; } |
5216 | | |
5217 | 21 | bool WebAssembly::isPICDefault() const { return false; } |
5218 | | |
5219 | 21 | bool WebAssembly::isPIEDefault() const { return false; } |
5220 | | |
5221 | 21 | bool WebAssembly::isPICDefaultForced() const { return false; } |
5222 | | |
5223 | 71 | bool WebAssembly::IsIntegratedAssemblerDefault() const { return true; } |
5224 | | |
5225 | | // TODO: Support Objective C stuff. |
5226 | 0 | bool WebAssembly::SupportsObjCGC() const { return false; } |
5227 | | |
5228 | 0 | bool WebAssembly::hasBlocksRuntime() const { return false; } |
5229 | | |
5230 | | // TODO: Support profiling. |
5231 | 42 | bool WebAssembly::SupportsProfiling() const { return false; } |
5232 | | |
5233 | 8 | bool WebAssembly::HasNativeLLVMSupport() const { return true; } |
5234 | | |
5235 | | void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs, |
5236 | 21 | ArgStringList &CC1Args) const { |
5237 | 21 | if (DriverArgs.hasFlag(options::OPT_fuse_init_array, |
5238 | 21 | options::OPT_fno_use_init_array, true)) |
5239 | 21 | CC1Args.push_back("-fuse-init-array"); |
5240 | 21 | } |
5241 | | |
5242 | 0 | ToolChain::RuntimeLibType WebAssembly::GetDefaultRuntimeLibType() const { |
5243 | 0 | return ToolChain::RLT_CompilerRT; |
5244 | 0 | } |
5245 | | |
5246 | 0 | ToolChain::CXXStdlibType WebAssembly::GetCXXStdlibType(const ArgList &Args) const { |
5247 | 0 | return ToolChain::CST_Libcxx; |
5248 | 0 | } |
5249 | | |
5250 | | void WebAssembly::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
5251 | 21 | ArgStringList &CC1Args) const { |
5252 | 21 | if (!DriverArgs.hasArg(options::OPT_nostdinc)) |
5253 | 21 | addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include"); |
5254 | 21 | } |
5255 | | |
5256 | | void WebAssembly::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, |
5257 | 6 | ArgStringList &CC1Args) const { |
5258 | 6 | if (!DriverArgs.hasArg(options::OPT_nostdlibinc) && |
5259 | 6 | !DriverArgs.hasArg(options::OPT_nostdincxx)) |
5260 | 6 | addSystemInclude(DriverArgs, CC1Args, |
5261 | 6 | getDriver().SysRoot + "/include/c++/v1"); |
5262 | 6 | } |
5263 | | |
5264 | 7 | Tool *WebAssembly::buildLinker() const { |
5265 | 7 | return new tools::wasm::Linker(*this); |
5266 | 7 | } |
5267 | | |
5268 | | PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) |
5269 | 115 | : Generic_ELF(D, Triple, Args) { |
5270 | 115 | if (Args.hasArg(options::OPT_static)) |
5271 | 1 | D.Diag(diag::err_drv_unsupported_opt_for_target) << "-static" << "PS4"; |
5272 | 115 | |
5273 | 115 | // Determine where to find the PS4 libraries. We use SCE_ORBIS_SDK_DIR |
5274 | 115 | // if it exists; otherwise use the driver's installation path, which |
5275 | 115 | // should be <SDK_DIR>/host_tools/bin. |
5276 | 115 | |
5277 | 115 | SmallString<512> PS4SDKDir; |
5278 | 115 | if (const char *EnvValue115 = getenv("SCE_ORBIS_SDK_DIR")) {22 |
5279 | 22 | if (!llvm::sys::fs::exists(EnvValue)) |
5280 | 0 | getDriver().Diag(clang::diag::warn_drv_ps4_sdk_dir) << EnvValue; |
5281 | 22 | PS4SDKDir = EnvValue; |
5282 | 93 | } else { |
5283 | 93 | PS4SDKDir = getDriver().Dir; |
5284 | 93 | llvm::sys::path::append(PS4SDKDir, "/../../"); |
5285 | 93 | } |
5286 | 115 | |
5287 | 115 | // By default, the driver won't report a warning if it can't find |
5288 | 115 | // PS4's include or lib directories. This behavior could be changed if |
5289 | 115 | // -Weverything or -Winvalid-or-nonexistent-directory options are passed. |
5290 | 115 | // If -isysroot was passed, use that as the SDK base path. |
5291 | 115 | std::string PrefixDir; |
5292 | 115 | if (const Arg *A115 = Args.getLastArg(options::OPT_isysroot)) {7 |
5293 | 7 | PrefixDir = A->getValue(); |
5294 | 7 | if (!llvm::sys::fs::exists(PrefixDir)) |
5295 | 6 | getDriver().Diag(clang::diag::warn_missing_sysroot) << PrefixDir; |
5296 | 7 | } else |
5297 | 108 | PrefixDir = PS4SDKDir.str(); |
5298 | 115 | |
5299 | 115 | SmallString<512> PS4SDKIncludeDir(PrefixDir); |
5300 | 115 | llvm::sys::path::append(PS4SDKIncludeDir, "target/include"); |
5301 | 115 | if (!Args.hasArg(options::OPT_nostdinc) && |
5302 | 111 | !Args.hasArg(options::OPT_nostdlibinc) && |
5303 | 111 | !Args.hasArg(options::OPT_isysroot) && |
5304 | 104 | !Args.hasArg(options::OPT__sysroot_EQ) && |
5305 | 100 | !llvm::sys::fs::exists(PS4SDKIncludeDir)100 ) {99 |
5306 | 99 | getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected) |
5307 | 99 | << "PS4 system headers" << PS4SDKIncludeDir; |
5308 | 99 | } |
5309 | 115 | |
5310 | 115 | SmallString<512> PS4SDKLibDir(PS4SDKDir); |
5311 | 115 | llvm::sys::path::append(PS4SDKLibDir, "target/lib"); |
5312 | 115 | if (!Args.hasArg(options::OPT_nostdlib) && |
5313 | 114 | !Args.hasArg(options::OPT_nodefaultlibs) && |
5314 | 113 | !Args.hasArg(options::OPT__sysroot_EQ)113 && !Args.hasArg(options::OPT_E)108 && |
5315 | 103 | !Args.hasArg(options::OPT_c)103 && !Args.hasArg(options::OPT_S)47 && |
5316 | 42 | !Args.hasArg(options::OPT_emit_ast) && |
5317 | 39 | !llvm::sys::fs::exists(PS4SDKLibDir)39 ) {39 |
5318 | 39 | getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected) |
5319 | 39 | << "PS4 system libraries" << PS4SDKLibDir; |
5320 | 39 | return; |
5321 | 39 | } |
5322 | 76 | getFilePaths().push_back(PS4SDKLibDir.str()); |
5323 | 76 | } |
5324 | | |
5325 | 0 | Tool *PS4CPU::buildAssembler() const { |
5326 | 0 | return new tools::PS4cpu::Assemble(*this); |
5327 | 0 | } |
5328 | | |
5329 | 37 | Tool *PS4CPU::buildLinker() const { return new tools::PS4cpu::Link(*this); } |
5330 | | |
5331 | 227 | bool PS4CPU::isPICDefault() const { return true; } |
5332 | | |
5333 | 37 | bool PS4CPU::HasNativeLLVMSupport() const { return true; } |
5334 | | |
5335 | 115 | SanitizerMask PS4CPU::getSupportedSanitizers() const { |
5336 | 115 | SanitizerMask Res = ToolChain::getSupportedSanitizers(); |
5337 | 115 | Res |= SanitizerKind::Address; |
5338 | 115 | Res |= SanitizerKind::Vptr; |
5339 | 115 | return Res; |
5340 | 115 | } |
5341 | | |
5342 | | Contiki::Contiki(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) |
5343 | 1 | : Generic_ELF(D, Triple, Args) {} |
5344 | | |
5345 | 1 | SanitizerMask Contiki::getSupportedSanitizers() const { |
5346 | 1 | const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; |
5347 | 1 | SanitizerMask Res = ToolChain::getSupportedSanitizers(); |
5348 | 1 | if (IsX86) |
5349 | 1 | Res |= SanitizerKind::SafeStack; |
5350 | 1 | return Res; |
5351 | 1 | } |
5352 | | |
5353 | | /// AVR Toolchain |
5354 | | AVRToolChain::AVRToolChain(const Driver &D, const llvm::Triple &Triple, |
5355 | | const ArgList &Args) |
5356 | 1 | : Generic_ELF(D, Triple, Args) { } |
5357 | 1 | Tool *AVRToolChain::buildLinker() const { |
5358 | 1 | return new tools::AVR::Linker(*this); |
5359 | 1 | } |
5360 | | // End AVR |