/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChains/Gnu.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- Gnu.cpp - Gnu Tool and ToolChain Implementations -------*- C++ -*-===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #include "Gnu.h" |
10 | | #include "Arch/ARM.h" |
11 | | #include "Arch/CSKY.h" |
12 | | #include "Arch/LoongArch.h" |
13 | | #include "Arch/Mips.h" |
14 | | #include "Arch/PPC.h" |
15 | | #include "Arch/RISCV.h" |
16 | | #include "Arch/Sparc.h" |
17 | | #include "Arch/SystemZ.h" |
18 | | #include "CommonArgs.h" |
19 | | #include "Linux.h" |
20 | | #include "clang/Config/config.h" // for GCC_INSTALL_PREFIX |
21 | | #include "clang/Driver/Compilation.h" |
22 | | #include "clang/Driver/Driver.h" |
23 | | #include "clang/Driver/DriverDiagnostic.h" |
24 | | #include "clang/Driver/MultilibBuilder.h" |
25 | | #include "clang/Driver/Options.h" |
26 | | #include "clang/Driver/Tool.h" |
27 | | #include "clang/Driver/ToolChain.h" |
28 | | #include "llvm/ADT/StringSet.h" |
29 | | #include "llvm/ADT/Twine.h" |
30 | | #include "llvm/Option/ArgList.h" |
31 | | #include "llvm/Support/CodeGen.h" |
32 | | #include "llvm/Support/Path.h" |
33 | | #include "llvm/Support/VirtualFileSystem.h" |
34 | | #include "llvm/TargetParser/TargetParser.h" |
35 | | #include <system_error> |
36 | | |
37 | | using namespace clang::driver; |
38 | | using namespace clang::driver::toolchains; |
39 | | using namespace clang; |
40 | | using namespace llvm::opt; |
41 | | |
42 | | using tools::addMultilibFlag; |
43 | | using tools::addPathIfExists; |
44 | | |
45 | 3.00k | static bool forwardToGCC(const Option &O) { |
46 | | // LinkerInput options have been forwarded. Don't duplicate. |
47 | 3.00k | if (O.hasFlag(options::LinkerInput)) |
48 | 2 | return false; |
49 | 3.00k | return O.matches(options::OPT_Link_Group) || O.hasFlag(options::LinkOption)2.99k ; |
50 | 3.00k | } |
51 | | |
52 | | // Switch CPU names not recognized by GNU assembler to a close CPU that it does |
53 | | // recognize, instead of a lower march from being picked in the absence of a cpu |
54 | | // flag. |
55 | | static void normalizeCPUNamesForAssembler(const ArgList &Args, |
56 | 57 | ArgStringList &CmdArgs) { |
57 | 57 | if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { |
58 | 27 | StringRef CPUArg(A->getValue()); |
59 | 27 | if (CPUArg.equals_insensitive("krait")) |
60 | 1 | CmdArgs.push_back("-mcpu=cortex-a15"); |
61 | 26 | else if (CPUArg.equals_insensitive("kryo")) |
62 | 2 | CmdArgs.push_back("-mcpu=cortex-a57"); |
63 | 24 | else |
64 | 24 | Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ); |
65 | 27 | } |
66 | 57 | } |
67 | | |
68 | | void tools::gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, |
69 | | const InputInfo &Output, |
70 | | const InputInfoList &Inputs, |
71 | | const ArgList &Args, |
72 | 430 | const char *LinkingOutput) const { |
73 | 430 | const Driver &D = getToolChain().getDriver(); |
74 | 430 | ArgStringList CmdArgs; |
75 | | |
76 | 3.00k | for (const auto &A : Args) { |
77 | 3.00k | if (forwardToGCC(A->getOption())) { |
78 | | // It is unfortunate that we have to claim here, as this means |
79 | | // we will basically never report anything interesting for |
80 | | // platforms using a generic gcc, even if we are just using gcc |
81 | | // to get to the assembler. |
82 | 11 | A->claim(); |
83 | | |
84 | 11 | A->render(Args, CmdArgs); |
85 | 11 | } |
86 | 3.00k | } |
87 | | |
88 | 430 | RenderExtraToolArgs(JA, CmdArgs); |
89 | | |
90 | | // If using a driver, force the arch. |
91 | 430 | if (getToolChain().getTriple().isOSDarwin()) { |
92 | 0 | CmdArgs.push_back("-arch"); |
93 | 0 | CmdArgs.push_back( |
94 | 0 | Args.MakeArgString(getToolChain().getDefaultUniversalArchName())); |
95 | 0 | } |
96 | | |
97 | | // Try to force gcc to match the tool chain we want, if we recognize |
98 | | // the arch. |
99 | | // |
100 | | // FIXME: The triple class should directly provide the information we want |
101 | | // here. |
102 | 430 | switch (getToolChain().getArch()) { |
103 | 280 | default: |
104 | 280 | break; |
105 | 280 | case llvm::Triple::x86: |
106 | 121 | case llvm::Triple::ppc: |
107 | 121 | case llvm::Triple::ppcle: |
108 | 121 | CmdArgs.push_back("-m32"); |
109 | 121 | break; |
110 | 26 | case llvm::Triple::x86_64: |
111 | 28 | case llvm::Triple::ppc64: |
112 | 28 | case llvm::Triple::ppc64le: |
113 | 28 | CmdArgs.push_back("-m64"); |
114 | 28 | break; |
115 | 1 | case llvm::Triple::sparcel: |
116 | 1 | CmdArgs.push_back("-EL"); |
117 | 1 | break; |
118 | 430 | } |
119 | | |
120 | 430 | assert((Output.isFilename() || Output.isNothing()) && "Invalid output."); |
121 | 430 | if (Output.isFilename()) { |
122 | 429 | CmdArgs.push_back("-o"); |
123 | 429 | CmdArgs.push_back(Output.getFilename()); |
124 | 429 | } else { |
125 | 1 | CmdArgs.push_back("-fsyntax-only"); |
126 | 1 | } |
127 | | |
128 | 430 | Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); |
129 | | |
130 | | // Only pass -x if gcc will understand it; otherwise hope gcc |
131 | | // understands the suffix correctly. The main use case this would go |
132 | | // wrong in is for linker inputs if they happened to have an odd |
133 | | // suffix; really the only way to get this to happen is a command |
134 | | // like '-x foobar a.c' which will treat a.c like a linker input. |
135 | | // |
136 | | // FIXME: For the linker case specifically, can we safely convert |
137 | | // inputs into '-Wl,' options? |
138 | 434 | for (const auto &II : Inputs) { |
139 | | // Don't try to pass LLVM or AST inputs to a generic gcc. |
140 | 434 | if (types::isLLVMIR(II.getType())) |
141 | 1 | D.Diag(clang::diag::err_drv_no_linker_llvm_support) |
142 | 1 | << getToolChain().getTripleString(); |
143 | 433 | else if (II.getType() == types::TY_AST) |
144 | 0 | D.Diag(diag::err_drv_no_ast_support) << getToolChain().getTripleString(); |
145 | 433 | else if (II.getType() == types::TY_ModuleFile) |
146 | 0 | D.Diag(diag::err_drv_no_module_support) |
147 | 0 | << getToolChain().getTripleString(); |
148 | | |
149 | 434 | if (types::canTypeBeUserSpecified(II.getType())) { |
150 | 4 | CmdArgs.push_back("-x"); |
151 | 4 | CmdArgs.push_back(types::getTypeName(II.getType())); |
152 | 4 | } |
153 | | |
154 | 434 | if (II.isFilename()) |
155 | 432 | CmdArgs.push_back(II.getFilename()); |
156 | 2 | else { |
157 | 2 | const Arg &A = II.getInputArg(); |
158 | | |
159 | | // Reverse translate some rewritten options. |
160 | 2 | if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) { |
161 | 0 | CmdArgs.push_back("-lstdc++"); |
162 | 0 | continue; |
163 | 0 | } |
164 | | |
165 | | // Don't render as input, we need gcc to do the translations. |
166 | 2 | A.render(Args, CmdArgs); |
167 | 2 | } |
168 | 434 | } |
169 | | |
170 | 430 | const std::string &customGCCName = D.getCCCGenericGCCName(); |
171 | 430 | const char *GCCName; |
172 | 430 | if (!customGCCName.empty()) |
173 | 0 | GCCName = customGCCName.c_str(); |
174 | 430 | else if (D.CCCIsCXX()) { |
175 | 0 | GCCName = "g++"; |
176 | 0 | } else |
177 | 430 | GCCName = "gcc"; |
178 | | |
179 | 430 | const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName)); |
180 | 430 | C.addCommand(std::make_unique<Command>(JA, *this, |
181 | 430 | ResponseFileSupport::AtFileCurCP(), |
182 | 430 | Exec, CmdArgs, Inputs, Output)); |
183 | 430 | } |
184 | | |
185 | | void tools::gcc::Preprocessor::RenderExtraToolArgs( |
186 | 0 | const JobAction &JA, ArgStringList &CmdArgs) const { |
187 | 0 | CmdArgs.push_back("-E"); |
188 | 0 | } |
189 | | |
190 | | void tools::gcc::Compiler::RenderExtraToolArgs(const JobAction &JA, |
191 | 4 | ArgStringList &CmdArgs) const { |
192 | 4 | const Driver &D = getToolChain().getDriver(); |
193 | | |
194 | 4 | switch (JA.getType()) { |
195 | | // If -flto, etc. are present then make sure not to force assembly output. |
196 | 0 | case types::TY_LLVM_IR: |
197 | 0 | case types::TY_LTO_IR: |
198 | 0 | case types::TY_LLVM_BC: |
199 | 0 | case types::TY_LTO_BC: |
200 | 0 | CmdArgs.push_back("-c"); |
201 | 0 | break; |
202 | | // We assume we've got an "integrated" assembler in that gcc will produce an |
203 | | // object file itself. |
204 | 2 | case types::TY_Object: |
205 | 2 | CmdArgs.push_back("-c"); |
206 | 2 | break; |
207 | 1 | case types::TY_PP_Asm: |
208 | 1 | CmdArgs.push_back("-S"); |
209 | 1 | break; |
210 | 1 | case types::TY_Nothing: |
211 | 1 | CmdArgs.push_back("-fsyntax-only"); |
212 | 1 | break; |
213 | 0 | default: |
214 | 0 | D.Diag(diag::err_drv_invalid_gcc_output_type) << getTypeName(JA.getType()); |
215 | 4 | } |
216 | 4 | } |
217 | | |
218 | | void tools::gcc::Linker::RenderExtraToolArgs(const JobAction &JA, |
219 | 426 | ArgStringList &CmdArgs) const { |
220 | | // The types are (hopefully) good enough. |
221 | 426 | } |
222 | | |
223 | 1.58k | static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { |
224 | 1.58k | switch (T.getArch()) { |
225 | 165 | case llvm::Triple::x86: |
226 | 165 | if (T.isOSIAMCU()) |
227 | 8 | return "elf_iamcu"; |
228 | 157 | return "elf_i386"; |
229 | 143 | case llvm::Triple::aarch64: |
230 | 143 | return "aarch64linux"; |
231 | 4 | case llvm::Triple::aarch64_be: |
232 | 4 | return "aarch64linuxb"; |
233 | 236 | case llvm::Triple::arm: |
234 | 241 | case llvm::Triple::thumb: |
235 | 250 | case llvm::Triple::armeb: |
236 | 255 | case llvm::Triple::thumbeb: |
237 | 255 | return tools::arm::isARMBigEndian(T, Args) ? "armelfb_linux_eabi"14 |
238 | 255 | : "armelf_linux_eabi"241 ; |
239 | 24 | case llvm::Triple::m68k: |
240 | 24 | return "m68kelf"; |
241 | 19 | case llvm::Triple::ppc: |
242 | 19 | if (T.isOSLinux()) |
243 | 19 | return "elf32ppclinux"; |
244 | 0 | return "elf32ppc"; |
245 | 3 | case llvm::Triple::ppcle: |
246 | 3 | if (T.isOSLinux()) |
247 | 3 | return "elf32lppclinux"; |
248 | 0 | return "elf32lppc"; |
249 | 55 | case llvm::Triple::ppc64: |
250 | 55 | return "elf64ppc"; |
251 | 41 | case llvm::Triple::ppc64le: |
252 | 41 | return "elf64lppc"; |
253 | 4 | case llvm::Triple::riscv32: |
254 | 4 | return "elf32lriscv"; |
255 | 16 | case llvm::Triple::riscv64: |
256 | 16 | return "elf64lriscv"; |
257 | 1 | case llvm::Triple::sparc: |
258 | 2 | case llvm::Triple::sparcel: |
259 | 2 | return "elf32_sparc"; |
260 | 1 | case llvm::Triple::sparcv9: |
261 | 1 | return "elf64_sparc"; |
262 | 0 | case llvm::Triple::loongarch32: |
263 | 0 | return "elf32loongarch"; |
264 | 10 | case llvm::Triple::loongarch64: |
265 | 10 | return "elf64loongarch"; |
266 | 12 | case llvm::Triple::mips: |
267 | 12 | return "elf32btsmip"; |
268 | 17 | case llvm::Triple::mipsel: |
269 | 17 | return "elf32ltsmip"; |
270 | 15 | case llvm::Triple::mips64: |
271 | 15 | if (tools::mips::hasMipsAbiArg(Args, "n32") || |
272 | 15 | T.getEnvironment() == llvm::Triple::GNUABIN3213 ) |
273 | 3 | return "elf32btsmipn32"; |
274 | 12 | return "elf64btsmip"; |
275 | 15 | case llvm::Triple::mips64el: |
276 | 15 | if (tools::mips::hasMipsAbiArg(Args, "n32") || |
277 | 15 | T.getEnvironment() == llvm::Triple::GNUABIN3211 ) |
278 | 4 | return "elf32ltsmipn32"; |
279 | 11 | return "elf64ltsmip"; |
280 | 10 | case llvm::Triple::systemz: |
281 | 10 | return "elf64_s390"; |
282 | 751 | case llvm::Triple::x86_64: |
283 | 751 | if (T.isX32()) |
284 | 13 | return "elf32_x86_64"; |
285 | 738 | return "elf_x86_64"; |
286 | 2 | case llvm::Triple::ve: |
287 | 2 | return "elf64ve"; |
288 | 14 | case llvm::Triple::csky: |
289 | 14 | return "cskyelf_linux"; |
290 | 2 | default: |
291 | 2 | return nullptr; |
292 | 1.58k | } |
293 | 1.58k | } |
294 | | |
295 | 1.58k | static bool getPIE(const ArgList &Args, const ToolChain &TC) { |
296 | 1.58k | if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_static)1.53k || |
297 | 1.58k | Args.hasArg(options::OPT_r)1.50k || Args.hasArg(options::OPT_static_pie)1.49k ) |
298 | 84 | return false; |
299 | | |
300 | 1.49k | Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie, |
301 | 1.49k | options::OPT_nopie); |
302 | 1.49k | if (!A) |
303 | 1.24k | return TC.isPIEDefault(Args); |
304 | 252 | return A->getOption().matches(options::OPT_pie); |
305 | 1.49k | } |
306 | | |
307 | 1.58k | static bool getStaticPIE(const ArgList &Args, const ToolChain &TC) { |
308 | 1.58k | bool HasStaticPIE = Args.hasArg(options::OPT_static_pie); |
309 | | // -no-pie is an alias for -nopie. So, handling -nopie takes care of |
310 | | // -no-pie as well. |
311 | 1.58k | if (HasStaticPIE && Args.hasArg(options::OPT_nopie)4 ) { |
312 | 3 | const Driver &D = TC.getDriver(); |
313 | 3 | const llvm::opt::OptTable &Opts = D.getOpts(); |
314 | 3 | StringRef StaticPIEName = Opts.getOptionName(options::OPT_static_pie); |
315 | 3 | StringRef NoPIEName = Opts.getOptionName(options::OPT_nopie); |
316 | 3 | D.Diag(diag::err_drv_cannot_mix_options) << StaticPIEName << NoPIEName; |
317 | 3 | } |
318 | 1.58k | return HasStaticPIE; |
319 | 1.58k | } |
320 | | |
321 | 1.58k | static bool getStatic(const ArgList &Args) { |
322 | 1.58k | return Args.hasArg(options::OPT_static) && |
323 | 1.58k | !Args.hasArg(options::OPT_static_pie)34 ; |
324 | 1.58k | } |
325 | | |
326 | | void tools::gnutools::StaticLibTool::ConstructJob( |
327 | | Compilation &C, const JobAction &JA, const InputInfo &Output, |
328 | | const InputInfoList &Inputs, const ArgList &Args, |
329 | 4 | const char *LinkingOutput) const { |
330 | 4 | const Driver &D = getToolChain().getDriver(); |
331 | | |
332 | | // Silence warning for "clang -g foo.o -o foo" |
333 | 4 | Args.ClaimAllArgs(options::OPT_g_Group); |
334 | | // and "clang -emit-llvm foo.o -o foo" |
335 | 4 | Args.ClaimAllArgs(options::OPT_emit_llvm); |
336 | | // and for "clang -w foo.o -o foo". Other warning options are already |
337 | | // handled somewhere else. |
338 | 4 | Args.ClaimAllArgs(options::OPT_w); |
339 | | // Silence warnings when linking C code with a C++ '-stdlib' argument. |
340 | 4 | Args.ClaimAllArgs(options::OPT_stdlib_EQ); |
341 | | |
342 | | // ar tool command "llvm-ar <options> <output_file> <input_files>". |
343 | 4 | ArgStringList CmdArgs; |
344 | | // Create and insert file members with a deterministic index. |
345 | 4 | CmdArgs.push_back("rcsD"); |
346 | 4 | CmdArgs.push_back(Output.getFilename()); |
347 | | |
348 | 14 | for (const auto &II : Inputs) { |
349 | 14 | if (II.isFilename()) { |
350 | 11 | CmdArgs.push_back(II.getFilename()); |
351 | 11 | } |
352 | 14 | } |
353 | | |
354 | | // Delete old output archive file if it already exists before generating a new |
355 | | // archive file. |
356 | 4 | auto OutputFileName = Output.getFilename(); |
357 | 4 | if (Output.isFilename() && llvm::sys::fs::exists(OutputFileName)) { |
358 | 0 | if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) { |
359 | 0 | D.Diag(diag::err_drv_unable_to_remove_file) << EC.message(); |
360 | 0 | return; |
361 | 0 | } |
362 | 0 | } |
363 | | |
364 | 4 | const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath()); |
365 | 4 | C.addCommand(std::make_unique<Command>(JA, *this, |
366 | 4 | ResponseFileSupport::AtFileCurCP(), |
367 | 4 | Exec, CmdArgs, Inputs, Output)); |
368 | 4 | } |
369 | | |
370 | | void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, |
371 | | const InputInfo &Output, |
372 | | const InputInfoList &Inputs, |
373 | | const ArgList &Args, |
374 | 1.58k | const char *LinkingOutput) const { |
375 | | // FIXME: The Linker class constructor takes a ToolChain and not a |
376 | | // Generic_ELF, so the static_cast might return a reference to a invalid |
377 | | // instance (see PR45061). Ideally, the Linker constructor needs to take a |
378 | | // Generic_ELF instead. |
379 | 1.58k | const toolchains::Generic_ELF &ToolChain = |
380 | 1.58k | static_cast<const toolchains::Generic_ELF &>(getToolChain()); |
381 | 1.58k | const Driver &D = ToolChain.getDriver(); |
382 | | |
383 | 1.58k | const llvm::Triple &Triple = getToolChain().getEffectiveTriple(); |
384 | | |
385 | 1.58k | const llvm::Triple::ArchType Arch = ToolChain.getArch(); |
386 | 1.58k | const bool isOHOSFamily = ToolChain.getTriple().isOHOSFamily(); |
387 | 1.58k | const bool isAndroid = ToolChain.getTriple().isAndroid(); |
388 | 1.58k | const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU(); |
389 | 1.58k | const bool IsVE = ToolChain.getTriple().isVE(); |
390 | 1.58k | const bool IsPIE = getPIE(Args, ToolChain); |
391 | 1.58k | const bool IsStaticPIE = getStaticPIE(Args, ToolChain); |
392 | 1.58k | const bool IsStatic = getStatic(Args); |
393 | 1.58k | const bool HasCRTBeginEndFiles = |
394 | 1.58k | ToolChain.getTriple().hasEnvironment() || |
395 | 1.58k | (ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies)366 ; |
396 | | |
397 | 1.58k | ArgStringList CmdArgs; |
398 | | |
399 | | // Silence warning for "clang -g foo.o -o foo" |
400 | 1.58k | Args.ClaimAllArgs(options::OPT_g_Group); |
401 | | // and "clang -emit-llvm foo.o -o foo" |
402 | 1.58k | Args.ClaimAllArgs(options::OPT_emit_llvm); |
403 | | // and for "clang -w foo.o -o foo". Other warning options are already |
404 | | // handled somewhere else. |
405 | 1.58k | Args.ClaimAllArgs(options::OPT_w); |
406 | | |
407 | 1.58k | if (!D.SysRoot.empty()) |
408 | 317 | CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); |
409 | | |
410 | 1.58k | if (IsPIE) |
411 | 1.28k | CmdArgs.push_back("-pie"); |
412 | | |
413 | 1.58k | if (IsStaticPIE) { |
414 | 4 | CmdArgs.push_back("-static"); |
415 | 4 | CmdArgs.push_back("-pie"); |
416 | 4 | CmdArgs.push_back("--no-dynamic-linker"); |
417 | 4 | CmdArgs.push_back("-z"); |
418 | 4 | CmdArgs.push_back("text"); |
419 | 4 | } |
420 | | |
421 | 1.58k | if (Args.hasArg(options::OPT_rdynamic)) |
422 | 5 | CmdArgs.push_back("-export-dynamic"); |
423 | | |
424 | 1.58k | if (Args.hasArg(options::OPT_s)) |
425 | 0 | CmdArgs.push_back("-s"); |
426 | | |
427 | 1.58k | if (Triple.isARM() || Triple.isThumb()1.33k ) { |
428 | 255 | bool IsBigEndian = arm::isARMBigEndian(Triple, Args); |
429 | 255 | if (IsBigEndian) |
430 | 14 | arm::appendBE8LinkFlag(Args, CmdArgs, Triple); |
431 | 255 | CmdArgs.push_back(IsBigEndian ? "-EB"14 : "-EL"241 ); |
432 | 1.32k | } else if (Triple.isAArch64()) { |
433 | 147 | CmdArgs.push_back(Arch == llvm::Triple::aarch64_be ? "-EB"4 : "-EL"143 ); |
434 | 147 | } |
435 | | |
436 | | // Most Android ARM64 targets should enable the linker fix for erratum |
437 | | // 843419. Only non-Cortex-A53 devices are allowed to skip this flag. |
438 | 1.58k | if (Arch == llvm::Triple::aarch64 && (143 isAndroid143 || isOHOSFamily93 )) { |
439 | 52 | std::string CPU = getCPUName(D, Args, Triple); |
440 | 52 | if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53"2 ) |
441 | 51 | CmdArgs.push_back("--fix-cortex-a53-843419"); |
442 | 52 | } |
443 | | |
444 | 1.58k | ToolChain.addExtraOpts(CmdArgs); |
445 | | |
446 | 1.58k | CmdArgs.push_back("--eh-frame-hdr"); |
447 | | |
448 | 1.58k | if (const char *LDMOption = getLDMOption(ToolChain.getTriple(), Args)) { |
449 | 1.57k | CmdArgs.push_back("-m"); |
450 | 1.57k | CmdArgs.push_back(LDMOption); |
451 | 1.57k | } else { |
452 | 2 | D.Diag(diag::err_target_unknown_triple) << Triple.str(); |
453 | 2 | return; |
454 | 2 | } |
455 | 1.57k | if (Triple.isRISCV()) |
456 | 20 | CmdArgs.push_back("-X"); |
457 | | |
458 | 1.57k | if (Args.hasArg(options::OPT_shared)) |
459 | 44 | CmdArgs.push_back("-shared"); |
460 | | |
461 | 1.57k | if (IsStatic) { |
462 | 33 | CmdArgs.push_back("-static"); |
463 | 1.54k | } else { |
464 | 1.54k | if (Args.hasArg(options::OPT_rdynamic)) |
465 | 5 | CmdArgs.push_back("-export-dynamic"); |
466 | | |
467 | 1.54k | if (!Args.hasArg(options::OPT_shared) && !IsStaticPIE1.50k && |
468 | 1.54k | !Args.hasArg(options::OPT_r)1.49k ) { |
469 | 1.49k | CmdArgs.push_back("-dynamic-linker"); |
470 | 1.49k | CmdArgs.push_back(Args.MakeArgString(Twine(D.DyldPrefix) + |
471 | 1.49k | ToolChain.getDynamicLinker(Args))); |
472 | 1.49k | } |
473 | 1.54k | } |
474 | | |
475 | 1.57k | CmdArgs.push_back("-o"); |
476 | 1.57k | CmdArgs.push_back(Output.getFilename()); |
477 | | |
478 | 1.57k | if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, |
479 | 1.57k | options::OPT_r)) { |
480 | 1.56k | if (!isAndroid && !IsIAMCU1.42k ) { |
481 | 1.41k | const char *crt1 = nullptr; |
482 | 1.41k | if (!Args.hasArg(options::OPT_shared)) { |
483 | 1.38k | if (Args.hasArg(options::OPT_pg)) |
484 | 1 | crt1 = "gcrt1.o"; |
485 | 1.38k | else if (IsPIE) |
486 | 1.18k | crt1 = "Scrt1.o"; |
487 | 201 | else if (IsStaticPIE) |
488 | 4 | crt1 = "rcrt1.o"; |
489 | 197 | else |
490 | 197 | crt1 = "crt1.o"; |
491 | 1.38k | } |
492 | 1.41k | if (crt1) |
493 | 1.38k | CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1))); |
494 | | |
495 | 1.41k | CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); |
496 | 1.41k | } |
497 | | |
498 | 1.56k | if (IsVE) { |
499 | 2 | CmdArgs.push_back("-z"); |
500 | 2 | CmdArgs.push_back("max-page-size=0x4000000"); |
501 | 2 | } |
502 | | |
503 | 1.56k | if (IsIAMCU) |
504 | 8 | CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); |
505 | 1.55k | else if (HasCRTBeginEndFiles) { |
506 | 1.55k | std::string P; |
507 | 1.55k | if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT && |
508 | 1.55k | !isAndroid194 ) { |
509 | 52 | std::string crtbegin = ToolChain.getCompilerRT(Args, "crtbegin", |
510 | 52 | ToolChain::FT_Object); |
511 | 52 | if (ToolChain.getVFS().exists(crtbegin)) |
512 | 27 | P = crtbegin; |
513 | 52 | } |
514 | 1.55k | if (P.empty()) { |
515 | 1.52k | const char *crtbegin; |
516 | 1.52k | if (Args.hasArg(options::OPT_shared)) |
517 | 42 | crtbegin = isAndroid ? "crtbegin_so.o"16 : "crtbeginS.o"26 ; |
518 | 1.48k | else if (IsStatic) |
519 | 23 | crtbegin = isAndroid ? "crtbegin_static.o"8 : "crtbeginT.o"15 ; |
520 | 1.46k | else if (IsPIE || IsStaticPIE211 ) |
521 | 1.25k | crtbegin = isAndroid ? "crtbegin_dynamic.o"91 : "crtbeginS.o"1.16k ; |
522 | 207 | else |
523 | 207 | crtbegin = isAndroid ? "crtbegin_dynamic.o"27 : "crtbegin.o"180 ; |
524 | 1.52k | P = ToolChain.GetFilePath(crtbegin); |
525 | 1.52k | } |
526 | 1.55k | CmdArgs.push_back(Args.MakeArgString(P)); |
527 | 1.55k | } |
528 | | |
529 | | // Add crtfastmath.o if available and fast math is enabled. |
530 | 1.56k | ToolChain.addFastMathRuntimeIfAvailable(Args, CmdArgs); |
531 | 1.56k | } |
532 | | |
533 | 1.57k | Args.AddAllArgs(CmdArgs, options::OPT_L); |
534 | 1.57k | Args.AddAllArgs(CmdArgs, options::OPT_u); |
535 | | |
536 | 1.57k | ToolChain.AddFilePathLibArgs(Args, CmdArgs); |
537 | | |
538 | 1.57k | if (D.isUsingLTO()) { |
539 | 89 | assert(!Inputs.empty() && "Must have at least one input."); |
540 | 89 | addLTOOptions(ToolChain, Args, CmdArgs, Output, Inputs[0], |
541 | 89 | D.getLTOMode() == LTOK_Thin); |
542 | 89 | } |
543 | | |
544 | 1.57k | if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) |
545 | 1 | CmdArgs.push_back("--no-demangle"); |
546 | | |
547 | 1.57k | bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs); |
548 | 1.57k | bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs); |
549 | 1.57k | addLinkerCompressDebugSectionsOption(ToolChain, Args, CmdArgs); |
550 | 1.57k | AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); |
551 | | |
552 | 1.57k | addHIPRuntimeLibArgs(ToolChain, C, Args, CmdArgs); |
553 | | |
554 | | // The profile runtime also needs access to system libraries. |
555 | 1.57k | getToolChain().addProfileRTLibs(Args, CmdArgs); |
556 | | |
557 | 1.57k | if (D.CCCIsCXX() && |
558 | 1.57k | !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, |
559 | 49 | options::OPT_r)) { |
560 | 49 | if (ToolChain.ShouldLinkCXXStdlib(Args)) { |
561 | 46 | bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) && |
562 | 46 | !Args.hasArg(options::OPT_static)1 ; |
563 | 46 | if (OnlyLibstdcxxStatic) |
564 | 1 | CmdArgs.push_back("-Bstatic"); |
565 | 46 | ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); |
566 | 46 | if (OnlyLibstdcxxStatic) |
567 | 1 | CmdArgs.push_back("-Bdynamic"); |
568 | 46 | } |
569 | 49 | CmdArgs.push_back("-lm"); |
570 | 49 | } |
571 | | |
572 | | // Silence warnings when linking C code with a C++ '-stdlib' argument. |
573 | 1.57k | Args.ClaimAllArgs(options::OPT_stdlib_EQ); |
574 | | |
575 | | // Additional linker set-up and flags for Fortran. This is required in order |
576 | | // to generate executables. As Fortran runtime depends on the C runtime, |
577 | | // these dependencies need to be listed before the C runtime below (i.e. |
578 | | // AddRuntTimeLibs). |
579 | 1.57k | if (D.IsFlangMode()) { |
580 | 0 | addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs); |
581 | 0 | addFortranRuntimeLibs(ToolChain, CmdArgs); |
582 | 0 | CmdArgs.push_back("-lm"); |
583 | 0 | } |
584 | | |
585 | 1.57k | if (!Args.hasArg(options::OPT_nostdlib, options::OPT_r)) { |
586 | 1.56k | if (!Args.hasArg(options::OPT_nodefaultlibs)) { |
587 | 1.56k | if (IsStatic || IsStaticPIE1.52k ) |
588 | 37 | CmdArgs.push_back("--start-group"); |
589 | | |
590 | 1.56k | if (NeedsSanitizerDeps) |
591 | 297 | linkSanitizerRuntimeDeps(ToolChain, Args, CmdArgs); |
592 | | |
593 | 1.56k | if (NeedsXRayDeps) |
594 | 15 | linkXRayRuntimeDeps(ToolChain, Args, CmdArgs); |
595 | | |
596 | 1.56k | bool WantPthread = Args.hasArg(options::OPT_pthread) || |
597 | 1.56k | Args.hasArg(options::OPT_pthreads)1.54k ; |
598 | | |
599 | | // Use the static OpenMP runtime with -static-openmp |
600 | 1.56k | bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && |
601 | 1.56k | !Args.hasArg(options::OPT_static)4 ; |
602 | | |
603 | | // FIXME: Only pass GompNeedsRT = true for platforms with libgomp that |
604 | | // require librt. Most modern Linux platforms do, but some may not. |
605 | 1.56k | if (addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP, |
606 | 1.56k | JA.isHostOffloading(Action::OFK_OpenMP), |
607 | 1.56k | /* GompNeedsRT= */ true)) |
608 | | // OpenMP runtimes implies pthreads when using the GNU toolchain. |
609 | | // FIXME: Does this really make sense for all GNU toolchains? |
610 | 31 | WantPthread = true; |
611 | | |
612 | 1.56k | AddRunTimeLibs(ToolChain, D, CmdArgs, Args); |
613 | | |
614 | | // LLVM support for atomics on 32-bit SPARC V8+ is incomplete, so |
615 | | // forcibly link with libatomic as a workaround. |
616 | | // TODO: Issue #41880 and D118021. |
617 | 1.56k | if (getToolChain().getTriple().getArch() == llvm::Triple::sparc) { |
618 | 1 | CmdArgs.push_back("--push-state"); |
619 | 1 | CmdArgs.push_back("--as-needed"); |
620 | 1 | CmdArgs.push_back("-latomic"); |
621 | 1 | CmdArgs.push_back("--pop-state"); |
622 | 1 | } |
623 | | |
624 | | // We don't need libpthread neither for bionic (Android) nor for musl, |
625 | | // (used by OHOS as runtime library). |
626 | 1.56k | if (WantPthread && !isAndroid44 && !isOHOSFamily32 ) |
627 | 31 | CmdArgs.push_back("-lpthread"); |
628 | | |
629 | 1.56k | if (Args.hasArg(options::OPT_fsplit_stack)) |
630 | 2 | CmdArgs.push_back("--wrap=pthread_create"); |
631 | | |
632 | 1.56k | if (!Args.hasArg(options::OPT_nolibc)) |
633 | 1.55k | CmdArgs.push_back("-lc"); |
634 | | |
635 | | // Add IAMCU specific libs, if needed. |
636 | 1.56k | if (IsIAMCU) |
637 | 8 | CmdArgs.push_back("-lgloss"); |
638 | | |
639 | 1.56k | if (IsStatic || IsStaticPIE1.52k ) |
640 | 37 | CmdArgs.push_back("--end-group"); |
641 | 1.52k | else |
642 | 1.52k | AddRunTimeLibs(ToolChain, D, CmdArgs, Args); |
643 | | |
644 | | // Add IAMCU specific libs (outside the group), if needed. |
645 | 1.56k | if (IsIAMCU) { |
646 | 8 | CmdArgs.push_back("--as-needed"); |
647 | 8 | CmdArgs.push_back("-lsoftfp"); |
648 | 8 | CmdArgs.push_back("--no-as-needed"); |
649 | 8 | } |
650 | 1.56k | } |
651 | | |
652 | 1.56k | if (!Args.hasArg(options::OPT_nostartfiles) && !IsIAMCU) { |
653 | 1.55k | if (HasCRTBeginEndFiles) { |
654 | 1.55k | std::string P; |
655 | 1.55k | if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT && |
656 | 1.55k | !isAndroid194 ) { |
657 | 52 | std::string crtend = ToolChain.getCompilerRT(Args, "crtend", |
658 | 52 | ToolChain::FT_Object); |
659 | 52 | if (ToolChain.getVFS().exists(crtend)) |
660 | 27 | P = crtend; |
661 | 52 | } |
662 | 1.55k | if (P.empty()) { |
663 | 1.52k | const char *crtend; |
664 | 1.52k | if (Args.hasArg(options::OPT_shared)) |
665 | 42 | crtend = isAndroid ? "crtend_so.o"16 : "crtendS.o"26 ; |
666 | 1.48k | else if (IsPIE || IsStaticPIE234 ) |
667 | 1.25k | crtend = isAndroid ? "crtend_android.o"91 : "crtendS.o"1.16k ; |
668 | 230 | else |
669 | 230 | crtend = isAndroid ? "crtend_android.o"35 : "crtend.o"195 ; |
670 | 1.52k | P = ToolChain.GetFilePath(crtend); |
671 | 1.52k | } |
672 | 1.55k | CmdArgs.push_back(Args.MakeArgString(P)); |
673 | 1.55k | } |
674 | 1.55k | if (!isAndroid) |
675 | 1.41k | CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); |
676 | 1.55k | } |
677 | 1.56k | } |
678 | | |
679 | 1.57k | Args.AddAllArgs(CmdArgs, options::OPT_T); |
680 | | |
681 | 1.57k | const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); |
682 | 1.57k | C.addCommand(std::make_unique<Command>(JA, *this, |
683 | 1.57k | ResponseFileSupport::AtFileCurCP(), |
684 | 1.57k | Exec, CmdArgs, Inputs, Output)); |
685 | 1.57k | } |
686 | | |
687 | | void tools::gnutools::Assembler::ConstructJob(Compilation &C, |
688 | | const JobAction &JA, |
689 | | const InputInfo &Output, |
690 | | const InputInfoList &Inputs, |
691 | | const ArgList &Args, |
692 | 241 | const char *LinkingOutput) const { |
693 | 241 | const auto &D = getToolChain().getDriver(); |
694 | | |
695 | 241 | claimNoWarnArgs(Args); |
696 | | |
697 | 241 | ArgStringList CmdArgs; |
698 | | |
699 | 241 | llvm::Reloc::Model RelocationModel; |
700 | 241 | unsigned PICLevel; |
701 | 241 | bool IsPIE; |
702 | 241 | const char *DefaultAssembler = "as"; |
703 | | // Enforce GNU as on Solaris; the native assembler's input syntax isn't fully |
704 | | // compatible. |
705 | 241 | if (getToolChain().getTriple().isOSSolaris()) |
706 | 4 | DefaultAssembler = "gas"; |
707 | 241 | std::tie(RelocationModel, PICLevel, IsPIE) = |
708 | 241 | ParsePICArgs(getToolChain(), Args); |
709 | | |
710 | 241 | if (const Arg *A = Args.getLastArg(options::OPT_gz, options::OPT_gz_EQ)) { |
711 | 8 | if (A->getOption().getID() == options::OPT_gz) { |
712 | 0 | CmdArgs.push_back("--compress-debug-sections"); |
713 | 8 | } else { |
714 | 8 | StringRef Value = A->getValue(); |
715 | 8 | if (Value == "none" || Value == "zlib"6 || Value == "zstd"2 ) { |
716 | 6 | CmdArgs.push_back( |
717 | 6 | Args.MakeArgString("--compress-debug-sections=" + Twine(Value))); |
718 | 6 | } else { |
719 | 2 | D.Diag(diag::err_drv_unsupported_option_argument) |
720 | 2 | << A->getSpelling() << Value; |
721 | 2 | } |
722 | 8 | } |
723 | 8 | } |
724 | | |
725 | 241 | switch (getToolChain().getArch()) { |
726 | 1 | default: |
727 | 1 | break; |
728 | | // Add --32/--64 to make sure we get the format we want. |
729 | | // This is incomplete |
730 | 25 | case llvm::Triple::x86: |
731 | 25 | CmdArgs.push_back("--32"); |
732 | 25 | break; |
733 | 17 | case llvm::Triple::x86_64: |
734 | 17 | if (getToolChain().getTriple().isX32()) |
735 | 1 | CmdArgs.push_back("--x32"); |
736 | 16 | else |
737 | 16 | CmdArgs.push_back("--64"); |
738 | 17 | break; |
739 | 5 | case llvm::Triple::ppc: { |
740 | 5 | CmdArgs.push_back("-a32"); |
741 | 5 | CmdArgs.push_back("-mppc"); |
742 | 5 | CmdArgs.push_back("-mbig-endian"); |
743 | 5 | CmdArgs.push_back(ppc::getPPCAsmModeForCPU( |
744 | 5 | getCPUName(D, Args, getToolChain().getTriple()))); |
745 | 5 | break; |
746 | 0 | } |
747 | 1 | case llvm::Triple::ppcle: { |
748 | 1 | CmdArgs.push_back("-a32"); |
749 | 1 | CmdArgs.push_back("-mppc"); |
750 | 1 | CmdArgs.push_back("-mlittle-endian"); |
751 | 1 | CmdArgs.push_back(ppc::getPPCAsmModeForCPU( |
752 | 1 | getCPUName(D, Args, getToolChain().getTriple()))); |
753 | 1 | break; |
754 | 0 | } |
755 | 4 | case llvm::Triple::ppc64: { |
756 | 4 | CmdArgs.push_back("-a64"); |
757 | 4 | CmdArgs.push_back("-mppc64"); |
758 | 4 | CmdArgs.push_back("-mbig-endian"); |
759 | 4 | CmdArgs.push_back(ppc::getPPCAsmModeForCPU( |
760 | 4 | getCPUName(D, Args, getToolChain().getTriple()))); |
761 | 4 | break; |
762 | 0 | } |
763 | 2 | case llvm::Triple::ppc64le: { |
764 | 2 | CmdArgs.push_back("-a64"); |
765 | 2 | CmdArgs.push_back("-mppc64"); |
766 | 2 | CmdArgs.push_back("-mlittle-endian"); |
767 | 2 | CmdArgs.push_back(ppc::getPPCAsmModeForCPU( |
768 | 2 | getCPUName(D, Args, getToolChain().getTriple()))); |
769 | 2 | break; |
770 | 0 | } |
771 | 4 | case llvm::Triple::riscv32: |
772 | 8 | case llvm::Triple::riscv64: { |
773 | 8 | StringRef ABIName = riscv::getRISCVABI(Args, getToolChain().getTriple()); |
774 | 8 | CmdArgs.push_back("-mabi"); |
775 | 8 | CmdArgs.push_back(ABIName.data()); |
776 | 8 | StringRef MArchName = riscv::getRISCVArch(Args, getToolChain().getTriple()); |
777 | 8 | CmdArgs.push_back("-march"); |
778 | 8 | CmdArgs.push_back(MArchName.data()); |
779 | 8 | if (!Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true)) |
780 | 1 | Args.addOptOutFlag(CmdArgs, options::OPT_mrelax, options::OPT_mno_relax); |
781 | 8 | break; |
782 | 4 | } |
783 | 24 | case llvm::Triple::sparc: |
784 | 25 | case llvm::Triple::sparcel: { |
785 | 25 | CmdArgs.push_back("-32"); |
786 | 25 | std::string CPU = getCPUName(D, Args, getToolChain().getTriple()); |
787 | 25 | CmdArgs.push_back( |
788 | 25 | sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); |
789 | 25 | AddAssemblerKPIC(getToolChain(), Args, CmdArgs); |
790 | 25 | break; |
791 | 24 | } |
792 | 4 | case llvm::Triple::sparcv9: { |
793 | 4 | CmdArgs.push_back("-64"); |
794 | 4 | std::string CPU = getCPUName(D, Args, getToolChain().getTriple()); |
795 | 4 | CmdArgs.push_back( |
796 | 4 | sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); |
797 | 4 | AddAssemblerKPIC(getToolChain(), Args, CmdArgs); |
798 | 4 | break; |
799 | 24 | } |
800 | 22 | case llvm::Triple::arm: |
801 | 27 | case llvm::Triple::armeb: |
802 | 31 | case llvm::Triple::thumb: |
803 | 35 | case llvm::Triple::thumbeb: { |
804 | 35 | const llvm::Triple &Triple2 = getToolChain().getTriple(); |
805 | 35 | CmdArgs.push_back(arm::isARMBigEndian(Triple2, Args) ? "-EB"8 : "-EL"27 ); |
806 | 35 | switch (Triple2.getSubArch()) { |
807 | 8 | case llvm::Triple::ARMSubArch_v7: |
808 | 8 | CmdArgs.push_back("-mfpu=neon"); |
809 | 8 | break; |
810 | 4 | case llvm::Triple::ARMSubArch_v8: |
811 | 4 | CmdArgs.push_back("-mfpu=crypto-neon-fp-armv8"); |
812 | 4 | break; |
813 | 23 | default: |
814 | 23 | break; |
815 | 35 | } |
816 | | |
817 | 35 | switch (arm::getARMFloatABI(getToolChain(), Args)) { |
818 | 0 | case arm::FloatABI::Invalid: llvm_unreachable("must have an ABI!"); |
819 | 24 | case arm::FloatABI::Soft: |
820 | 24 | CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=soft")); |
821 | 24 | break; |
822 | 3 | case arm::FloatABI::SoftFP: |
823 | 3 | CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=softfp")); |
824 | 3 | break; |
825 | 8 | case arm::FloatABI::Hard: |
826 | 8 | CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=hard")); |
827 | 8 | break; |
828 | 35 | } |
829 | | |
830 | 35 | Args.AddLastArg(CmdArgs, options::OPT_march_EQ); |
831 | 35 | normalizeCPUNamesForAssembler(Args, CmdArgs); |
832 | | |
833 | 35 | Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ); |
834 | | // The integrated assembler doesn't implement e_flags setting behavior for |
835 | | // -meabi=gnu (gcc -mabi={apcs-gnu,atpcs} passes -meabi=gnu to gas). For |
836 | | // compatibility we accept but warn. |
837 | 35 | if (Arg *A = Args.getLastArgNoClaim(options::OPT_mabi_EQ)) |
838 | 2 | A->ignoreTargetSpecific(); |
839 | 35 | break; |
840 | 35 | } |
841 | 18 | case llvm::Triple::aarch64: |
842 | 22 | case llvm::Triple::aarch64_be: { |
843 | 22 | CmdArgs.push_back( |
844 | 22 | getToolChain().getArch() == llvm::Triple::aarch64_be ? "-EB"4 : "-EL"18 ); |
845 | 22 | Args.AddLastArg(CmdArgs, options::OPT_march_EQ); |
846 | 22 | normalizeCPUNamesForAssembler(Args, CmdArgs); |
847 | | |
848 | 22 | break; |
849 | 18 | } |
850 | | // TODO: handle loongarch32. |
851 | 4 | case llvm::Triple::loongarch64: { |
852 | 4 | StringRef ABIName = |
853 | 4 | loongarch::getLoongArchABI(D, Args, getToolChain().getTriple()); |
854 | 4 | CmdArgs.push_back(Args.MakeArgString("-mabi=" + ABIName)); |
855 | 4 | break; |
856 | 18 | } |
857 | 53 | case llvm::Triple::mips: |
858 | 57 | case llvm::Triple::mipsel: |
859 | 80 | case llvm::Triple::mips64: |
860 | 85 | case llvm::Triple::mips64el: { |
861 | 85 | StringRef CPUName; |
862 | 85 | StringRef ABIName; |
863 | 85 | mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName); |
864 | 85 | ABIName = mips::getGnuCompatibleMipsABIName(ABIName); |
865 | | |
866 | 85 | CmdArgs.push_back("-march"); |
867 | 85 | CmdArgs.push_back(CPUName.data()); |
868 | | |
869 | 85 | CmdArgs.push_back("-mabi"); |
870 | 85 | CmdArgs.push_back(ABIName.data()); |
871 | | |
872 | | // -mno-shared should be emitted unless -fpic, -fpie, -fPIC, -fPIE, |
873 | | // or -mshared (not implemented) is in effect. |
874 | 85 | if (RelocationModel == llvm::Reloc::Static) |
875 | 46 | CmdArgs.push_back("-mno-shared"); |
876 | | |
877 | | // LLVM doesn't support -mplt yet and acts as if it is always given. |
878 | | // However, -mplt has no effect with the N64 ABI. |
879 | 85 | if (ABIName != "64" && !Args.hasArg(options::OPT_mno_abicalls)59 ) |
880 | 59 | CmdArgs.push_back("-call_nonpic"); |
881 | | |
882 | 85 | if (getToolChain().getTriple().isLittleEndian()) |
883 | 9 | CmdArgs.push_back("-EL"); |
884 | 76 | else |
885 | 76 | CmdArgs.push_back("-EB"); |
886 | | |
887 | 85 | if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) { |
888 | 2 | if (StringRef(A->getValue()) == "2008") |
889 | 1 | CmdArgs.push_back(Args.MakeArgString("-mnan=2008")); |
890 | 2 | } |
891 | | |
892 | | // Add the last -mfp32/-mfpxx/-mfp64 or -mfpxx if it is enabled by default. |
893 | 85 | if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx, |
894 | 85 | options::OPT_mfp64)) { |
895 | 9 | A->claim(); |
896 | 9 | A->render(Args, CmdArgs); |
897 | 76 | } else if (mips::shouldUseFPXX( |
898 | 76 | Args, getToolChain().getTriple(), CPUName, ABIName, |
899 | 76 | mips::getMipsFloatABI(getToolChain().getDriver(), Args, |
900 | 76 | getToolChain().getTriple()))) |
901 | 35 | CmdArgs.push_back("-mfpxx"); |
902 | | |
903 | | // Pass on -mmips16 or -mno-mips16. However, the assembler equivalent of |
904 | | // -mno-mips16 is actually -no-mips16. |
905 | 85 | if (Arg *A = |
906 | 85 | Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16)) { |
907 | 2 | if (A->getOption().matches(options::OPT_mips16)) { |
908 | 1 | A->claim(); |
909 | 1 | A->render(Args, CmdArgs); |
910 | 1 | } else { |
911 | 1 | A->claim(); |
912 | 1 | CmdArgs.push_back("-no-mips16"); |
913 | 1 | } |
914 | 2 | } |
915 | | |
916 | 85 | Args.AddLastArg(CmdArgs, options::OPT_mmicromips, |
917 | 85 | options::OPT_mno_micromips); |
918 | 85 | Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp); |
919 | 85 | Args.AddLastArg(CmdArgs, options::OPT_mdspr2, options::OPT_mno_dspr2); |
920 | | |
921 | 85 | if (Arg *A = Args.getLastArg(options::OPT_mmsa, options::OPT_mno_msa)) { |
922 | | // Do not use AddLastArg because not all versions of MIPS assembler |
923 | | // support -mmsa / -mno-msa options. |
924 | 2 | if (A->getOption().matches(options::OPT_mmsa)) |
925 | 1 | CmdArgs.push_back(Args.MakeArgString("-mmsa")); |
926 | 2 | } |
927 | | |
928 | 85 | Args.AddLastArg(CmdArgs, options::OPT_mhard_float, |
929 | 85 | options::OPT_msoft_float); |
930 | | |
931 | 85 | Args.AddLastArg(CmdArgs, options::OPT_mdouble_float, |
932 | 85 | options::OPT_msingle_float); |
933 | | |
934 | 85 | Args.AddLastArg(CmdArgs, options::OPT_modd_spreg, |
935 | 85 | options::OPT_mno_odd_spreg); |
936 | | |
937 | 85 | AddAssemblerKPIC(getToolChain(), Args, CmdArgs); |
938 | 85 | break; |
939 | 80 | } |
940 | 3 | case llvm::Triple::systemz: { |
941 | | // Always pass an -march option, since our default of z10 is later |
942 | | // than the GNU assembler's default. |
943 | 3 | std::string CPUName = systemz::getSystemZTargetCPU(Args); |
944 | 3 | CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName)); |
945 | 3 | break; |
946 | 80 | } |
947 | 0 | case llvm::Triple::ve: |
948 | 0 | DefaultAssembler = "nas"; |
949 | 241 | } |
950 | | |
951 | 241 | for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ, |
952 | 241 | options::OPT_fdebug_prefix_map_EQ)) { |
953 | 0 | StringRef Map = A->getValue(); |
954 | 0 | if (!Map.contains('=')) |
955 | 0 | D.Diag(diag::err_drv_invalid_argument_to_option) |
956 | 0 | << Map << A->getOption().getName(); |
957 | 0 | else { |
958 | 0 | CmdArgs.push_back(Args.MakeArgString("--debug-prefix-map")); |
959 | 0 | CmdArgs.push_back(Args.MakeArgString(Map)); |
960 | 0 | } |
961 | 0 | A->claim(); |
962 | 0 | } |
963 | | |
964 | 241 | Args.AddAllArgs(CmdArgs, options::OPT_I); |
965 | 241 | Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); |
966 | | |
967 | 241 | CmdArgs.push_back("-o"); |
968 | 241 | CmdArgs.push_back(Output.getFilename()); |
969 | | |
970 | 241 | for (const auto &II : Inputs) |
971 | 246 | CmdArgs.push_back(II.getFilename()); |
972 | | |
973 | 241 | if (Arg *A = Args.getLastArg(options::OPT_g_Flag, options::OPT_gN_Group, |
974 | 241 | options::OPT_gdwarf_2, options::OPT_gdwarf_3, |
975 | 241 | options::OPT_gdwarf_4, options::OPT_gdwarf_5, |
976 | 241 | options::OPT_gdwarf)) |
977 | 14 | if (!A->getOption().matches(options::OPT_g0)) { |
978 | 12 | Args.AddLastArg(CmdArgs, options::OPT_g_Flag); |
979 | | |
980 | 12 | unsigned DwarfVersion = getDwarfVersion(getToolChain(), Args); |
981 | 12 | CmdArgs.push_back(Args.MakeArgString("-gdwarf-" + Twine(DwarfVersion))); |
982 | 12 | } |
983 | | |
984 | 241 | const char *Exec = |
985 | 241 | Args.MakeArgString(getToolChain().GetProgramPath(DefaultAssembler)); |
986 | 241 | C.addCommand(std::make_unique<Command>(JA, *this, |
987 | 241 | ResponseFileSupport::AtFileCurCP(), |
988 | 241 | Exec, CmdArgs, Inputs, Output)); |
989 | | |
990 | | // Handle the debug info splitting at object creation time if we're |
991 | | // creating an object. |
992 | | // TODO: Currently only works on linux with newer objcopy. |
993 | 241 | if (Args.hasArg(options::OPT_gsplit_dwarf) && |
994 | 241 | getToolChain().getTriple().isOSLinux()1 ) |
995 | 1 | SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, |
996 | 1 | SplitDebugName(JA, Args, Inputs[0], Output)); |
997 | 241 | } |
998 | | |
999 | | namespace { |
1000 | | // Filter to remove Multilibs that don't exist as a suffix to Path |
1001 | | class FilterNonExistent { |
1002 | | StringRef Base, File; |
1003 | | llvm::vfs::FileSystem &VFS; |
1004 | | |
1005 | | public: |
1006 | | FilterNonExistent(StringRef Base, StringRef File, llvm::vfs::FileSystem &VFS) |
1007 | 424 | : Base(Base), File(File), VFS(VFS) {} |
1008 | 5.88k | bool operator()(const Multilib &M) { |
1009 | 5.88k | return !VFS.exists(Base + M.gccSuffix() + File); |
1010 | 5.88k | } |
1011 | | }; |
1012 | | } // end anonymous namespace |
1013 | | |
1014 | 56 | static bool isSoftFloatABI(const ArgList &Args) { |
1015 | 56 | Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, |
1016 | 56 | options::OPT_mfloat_abi_EQ); |
1017 | 56 | if (!A) |
1018 | 24 | return false; |
1019 | | |
1020 | 32 | return A->getOption().matches(options::OPT_msoft_float) || |
1021 | 32 | (26 A->getOption().matches(options::OPT_mfloat_abi_EQ)26 && |
1022 | 26 | A->getValue() == StringRef("soft")0 ); |
1023 | 56 | } |
1024 | | |
1025 | 459 | static bool isArmOrThumbArch(llvm::Triple::ArchType Arch) { |
1026 | 459 | return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb424 ; |
1027 | 459 | } |
1028 | | |
1029 | 56 | static bool isMipsEL(llvm::Triple::ArchType Arch) { |
1030 | 56 | return Arch == llvm::Triple::mipsel || Arch == llvm::Triple::mips64el36 ; |
1031 | 56 | } |
1032 | | |
1033 | 28 | static bool isMips16(const ArgList &Args) { |
1034 | 28 | Arg *A = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16); |
1035 | 28 | return A && A->getOption().matches(options::OPT_mips16)0 ; |
1036 | 28 | } |
1037 | | |
1038 | 28 | static bool isMicroMips(const ArgList &Args) { |
1039 | 28 | Arg *A = Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips); |
1040 | 28 | return A && A->getOption().matches(options::OPT_mmicromips)2 ; |
1041 | 28 | } |
1042 | | |
1043 | 369 | static bool isMSP430(llvm::Triple::ArchType Arch) { |
1044 | 369 | return Arch == llvm::Triple::msp430; |
1045 | 369 | } |
1046 | | |
1047 | | static bool findMipsCsMultilibs(const Multilib::flags_list &Flags, |
1048 | | FilterNonExistent &NonExistent, |
1049 | 12 | DetectedMultilibs &Result) { |
1050 | | // Check for Code Sourcery toolchain multilibs |
1051 | 12 | MultilibSet CSMipsMultilibs; |
1052 | 12 | { |
1053 | 12 | auto MArchMips16 = MultilibBuilder("/mips16").flag("-m32").flag("-mips16"); |
1054 | | |
1055 | 12 | auto MArchMicroMips = |
1056 | 12 | MultilibBuilder("/micromips").flag("-m32").flag("-mmicromips"); |
1057 | | |
1058 | 12 | auto MArchDefault = MultilibBuilder("") |
1059 | 12 | .flag("-mips16", /*Disallow=*/true) |
1060 | 12 | .flag("-mmicromips", /*Disallow=*/true); |
1061 | | |
1062 | 12 | auto UCLibc = MultilibBuilder("/uclibc").flag("-muclibc"); |
1063 | | |
1064 | 12 | auto SoftFloat = MultilibBuilder("/soft-float").flag("-msoft-float"); |
1065 | | |
1066 | 12 | auto Nan2008 = MultilibBuilder("/nan2008").flag("-mnan=2008"); |
1067 | | |
1068 | 12 | auto DefaultFloat = MultilibBuilder("") |
1069 | 12 | .flag("-msoft-float", /*Disallow=*/true) |
1070 | 12 | .flag("-mnan=2008", /*Disallow=*/true); |
1071 | | |
1072 | 12 | auto BigEndian = |
1073 | 12 | MultilibBuilder("").flag("-EB").flag("-EL", /*Disallow=*/true); |
1074 | | |
1075 | 12 | auto LittleEndian = |
1076 | 12 | MultilibBuilder("/el").flag("-EL").flag("-EB", /*Disallow=*/true); |
1077 | | |
1078 | | // Note that this one's osSuffix is "" |
1079 | 12 | auto MAbi64 = MultilibBuilder("") |
1080 | 12 | .gccSuffix("/64") |
1081 | 12 | .includeSuffix("/64") |
1082 | 12 | .flag("-mabi=n64") |
1083 | 12 | .flag("-mabi=n32", /*Disallow=*/true) |
1084 | 12 | .flag("-m32", /*Disallow=*/true); |
1085 | | |
1086 | 12 | CSMipsMultilibs = |
1087 | 12 | MultilibSetBuilder() |
1088 | 12 | .Either(MArchMips16, MArchMicroMips, MArchDefault) |
1089 | 12 | .Maybe(UCLibc) |
1090 | 12 | .Either(SoftFloat, Nan2008, DefaultFloat) |
1091 | 12 | .FilterOut("/micromips/nan2008") |
1092 | 12 | .FilterOut("/mips16/nan2008") |
1093 | 12 | .Either(BigEndian, LittleEndian) |
1094 | 12 | .Maybe(MAbi64) |
1095 | 12 | .FilterOut("/mips16.*/64") |
1096 | 12 | .FilterOut("/micromips.*/64") |
1097 | 12 | .makeMultilibSet() |
1098 | 12 | .FilterOut(NonExistent) |
1099 | 12 | .setIncludeDirsCallback([](const Multilib &M) { |
1100 | 1 | std::vector<std::string> Dirs({"/include"}); |
1101 | 1 | if (StringRef(M.includeSuffix()).startswith("/uclibc")) |
1102 | 0 | Dirs.push_back( |
1103 | 0 | "/../../../../mips-linux-gnu/libc/uclibc/usr/include"); |
1104 | 1 | else |
1105 | 1 | Dirs.push_back("/../../../../mips-linux-gnu/libc/usr/include"); |
1106 | 1 | return Dirs; |
1107 | 1 | }); |
1108 | 12 | } |
1109 | | |
1110 | 12 | MultilibSet DebianMipsMultilibs; |
1111 | 12 | { |
1112 | 12 | MultilibBuilder MAbiN32 = |
1113 | 12 | MultilibBuilder().gccSuffix("/n32").includeSuffix("/n32").flag( |
1114 | 12 | "-mabi=n32"); |
1115 | | |
1116 | 12 | MultilibBuilder M64 = MultilibBuilder() |
1117 | 12 | .gccSuffix("/64") |
1118 | 12 | .includeSuffix("/64") |
1119 | 12 | .flag("-m64") |
1120 | 12 | .flag("-m32", /*Disallow=*/true) |
1121 | 12 | .flag("-mabi=n32", /*Disallow=*/true); |
1122 | | |
1123 | 12 | MultilibBuilder M32 = MultilibBuilder() |
1124 | 12 | .gccSuffix("/32") |
1125 | 12 | .flag("-m64", /*Disallow=*/true) |
1126 | 12 | .flag("-m32") |
1127 | 12 | .flag("-mabi=n32", /*Disallow=*/true); |
1128 | | |
1129 | 12 | DebianMipsMultilibs = MultilibSetBuilder() |
1130 | 12 | .Either(M32, M64, MAbiN32) |
1131 | 12 | .makeMultilibSet() |
1132 | 12 | .FilterOut(NonExistent); |
1133 | 12 | } |
1134 | | |
1135 | | // Sort candidates. Toolchain that best meets the directories tree goes first. |
1136 | | // Then select the first toolchains matches command line flags. |
1137 | 12 | MultilibSet *Candidates[] = {&CSMipsMultilibs, &DebianMipsMultilibs}; |
1138 | 12 | if (CSMipsMultilibs.size() < DebianMipsMultilibs.size()) |
1139 | 7 | std::iter_swap(Candidates, Candidates + 1); |
1140 | 22 | for (const MultilibSet *Candidate : Candidates) { |
1141 | 22 | if (Candidate->select(Flags, Result.SelectedMultilibs)) { |
1142 | 4 | if (Candidate == &DebianMipsMultilibs) |
1143 | 3 | Result.BiarchSibling = Multilib(); |
1144 | 4 | Result.Multilibs = *Candidate; |
1145 | 4 | return true; |
1146 | 4 | } |
1147 | 22 | } |
1148 | 8 | return false; |
1149 | 12 | } |
1150 | | |
1151 | | static bool findMipsAndroidMultilibs(llvm::vfs::FileSystem &VFS, StringRef Path, |
1152 | | const Multilib::flags_list &Flags, |
1153 | | FilterNonExistent &NonExistent, |
1154 | 0 | DetectedMultilibs &Result) { |
1155 | |
|
1156 | 0 | MultilibSet AndroidMipsMultilibs = |
1157 | 0 | MultilibSetBuilder() |
1158 | 0 | .Maybe(MultilibBuilder("/mips-r2", {}, {}).flag("-march=mips32r2")) |
1159 | 0 | .Maybe(MultilibBuilder("/mips-r6", {}, {}).flag("-march=mips32r6")) |
1160 | 0 | .makeMultilibSet() |
1161 | 0 | .FilterOut(NonExistent); |
1162 | |
|
1163 | 0 | MultilibSet AndroidMipselMultilibs = |
1164 | 0 | MultilibSetBuilder() |
1165 | 0 | .Either(MultilibBuilder().flag("-march=mips32"), |
1166 | 0 | MultilibBuilder("/mips-r2", "", "/mips-r2") |
1167 | 0 | .flag("-march=mips32r2"), |
1168 | 0 | MultilibBuilder("/mips-r6", "", "/mips-r6") |
1169 | 0 | .flag("-march=mips32r6")) |
1170 | 0 | .makeMultilibSet() |
1171 | 0 | .FilterOut(NonExistent); |
1172 | |
|
1173 | 0 | MultilibSet AndroidMips64elMultilibs = |
1174 | 0 | MultilibSetBuilder() |
1175 | 0 | .Either(MultilibBuilder().flag("-march=mips64r6"), |
1176 | 0 | MultilibBuilder("/32/mips-r1", "", "/mips-r1") |
1177 | 0 | .flag("-march=mips32"), |
1178 | 0 | MultilibBuilder("/32/mips-r2", "", "/mips-r2") |
1179 | 0 | .flag("-march=mips32r2"), |
1180 | 0 | MultilibBuilder("/32/mips-r6", "", "/mips-r6") |
1181 | 0 | .flag("-march=mips32r6")) |
1182 | 0 | .makeMultilibSet() |
1183 | 0 | .FilterOut(NonExistent); |
1184 | |
|
1185 | 0 | MultilibSet *MS = &AndroidMipsMultilibs; |
1186 | 0 | if (VFS.exists(Path + "/mips-r6")) |
1187 | 0 | MS = &AndroidMipselMultilibs; |
1188 | 0 | else if (VFS.exists(Path + "/32")) |
1189 | 0 | MS = &AndroidMips64elMultilibs; |
1190 | 0 | if (MS->select(Flags, Result.SelectedMultilibs)) { |
1191 | 0 | Result.Multilibs = *MS; |
1192 | 0 | return true; |
1193 | 0 | } |
1194 | 0 | return false; |
1195 | 0 | } |
1196 | | |
1197 | | static bool findMipsMuslMultilibs(const Multilib::flags_list &Flags, |
1198 | | FilterNonExistent &NonExistent, |
1199 | 0 | DetectedMultilibs &Result) { |
1200 | | // Musl toolchain multilibs |
1201 | 0 | MultilibSet MuslMipsMultilibs; |
1202 | 0 | { |
1203 | 0 | auto MArchMipsR2 = MultilibBuilder("") |
1204 | 0 | .osSuffix("/mips-r2-hard-musl") |
1205 | 0 | .flag("-EB") |
1206 | 0 | .flag("-EL", /*Disallow=*/true) |
1207 | 0 | .flag("-march=mips32r2"); |
1208 | |
|
1209 | 0 | auto MArchMipselR2 = MultilibBuilder("/mipsel-r2-hard-musl") |
1210 | 0 | .flag("-EB", /*Disallow=*/true) |
1211 | 0 | .flag("-EL") |
1212 | 0 | .flag("-march=mips32r2"); |
1213 | |
|
1214 | 0 | MuslMipsMultilibs = MultilibSetBuilder() |
1215 | 0 | .Either(MArchMipsR2, MArchMipselR2) |
1216 | 0 | .makeMultilibSet(); |
1217 | | |
1218 | | // Specify the callback that computes the include directories. |
1219 | 0 | MuslMipsMultilibs.setIncludeDirsCallback([](const Multilib &M) { |
1220 | 0 | return std::vector<std::string>( |
1221 | 0 | {"/../sysroot" + M.osSuffix() + "/usr/include"}); |
1222 | 0 | }); |
1223 | 0 | } |
1224 | 0 | if (MuslMipsMultilibs.select(Flags, Result.SelectedMultilibs)) { |
1225 | 0 | Result.Multilibs = MuslMipsMultilibs; |
1226 | 0 | return true; |
1227 | 0 | } |
1228 | 0 | return false; |
1229 | 0 | } |
1230 | | |
1231 | | static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags, |
1232 | | FilterNonExistent &NonExistent, |
1233 | 16 | DetectedMultilibs &Result) { |
1234 | | // CodeScape MTI toolchain v1.2 and early. |
1235 | 16 | MultilibSet MtiMipsMultilibsV1; |
1236 | 16 | { |
1237 | 16 | auto MArchMips32 = MultilibBuilder("/mips32") |
1238 | 16 | .flag("-m32") |
1239 | 16 | .flag("-m64", /*Disallow=*/true) |
1240 | 16 | .flag("-mmicromips", /*Disallow=*/true) |
1241 | 16 | .flag("-march=mips32"); |
1242 | | |
1243 | 16 | auto MArchMicroMips = MultilibBuilder("/micromips") |
1244 | 16 | .flag("-m32") |
1245 | 16 | .flag("-m64", /*Disallow=*/true) |
1246 | 16 | .flag("-mmicromips"); |
1247 | | |
1248 | 16 | auto MArchMips64r2 = MultilibBuilder("/mips64r2") |
1249 | 16 | .flag("-m32", /*Disallow=*/true) |
1250 | 16 | .flag("-m64") |
1251 | 16 | .flag("-march=mips64r2"); |
1252 | | |
1253 | 16 | auto MArchMips64 = MultilibBuilder("/mips64") |
1254 | 16 | .flag("-m32", /*Disallow=*/true) |
1255 | 16 | .flag("-m64") |
1256 | 16 | .flag("-march=mips64r2", /*Disallow=*/true); |
1257 | | |
1258 | 16 | auto MArchDefault = MultilibBuilder("") |
1259 | 16 | .flag("-m32") |
1260 | 16 | .flag("-m64", /*Disallow=*/true) |
1261 | 16 | .flag("-mmicromips", /*Disallow=*/true) |
1262 | 16 | .flag("-march=mips32r2"); |
1263 | | |
1264 | 16 | auto Mips16 = MultilibBuilder("/mips16").flag("-mips16"); |
1265 | | |
1266 | 16 | auto UCLibc = MultilibBuilder("/uclibc").flag("-muclibc"); |
1267 | | |
1268 | 16 | auto MAbi64 = MultilibBuilder("/64") |
1269 | 16 | .flag("-mabi=n64") |
1270 | 16 | .flag("-mabi=n32", /*Disallow=*/true) |
1271 | 16 | .flag("-m32", /*Disallow=*/true); |
1272 | | |
1273 | 16 | auto BigEndian = |
1274 | 16 | MultilibBuilder("").flag("-EB").flag("-EL", /*Disallow=*/true); |
1275 | | |
1276 | 16 | auto LittleEndian = |
1277 | 16 | MultilibBuilder("/el").flag("-EL").flag("-EB", /*Disallow=*/true); |
1278 | | |
1279 | 16 | auto SoftFloat = MultilibBuilder("/sof").flag("-msoft-float"); |
1280 | | |
1281 | 16 | auto Nan2008 = MultilibBuilder("/nan2008").flag("-mnan=2008"); |
1282 | | |
1283 | 16 | MtiMipsMultilibsV1 = |
1284 | 16 | MultilibSetBuilder() |
1285 | 16 | .Either(MArchMips32, MArchMicroMips, MArchMips64r2, MArchMips64, |
1286 | 16 | MArchDefault) |
1287 | 16 | .Maybe(UCLibc) |
1288 | 16 | .Maybe(Mips16) |
1289 | 16 | .FilterOut("/mips64/mips16") |
1290 | 16 | .FilterOut("/mips64r2/mips16") |
1291 | 16 | .FilterOut("/micromips/mips16") |
1292 | 16 | .Maybe(MAbi64) |
1293 | 16 | .FilterOut("/micromips/64") |
1294 | 16 | .FilterOut("/mips32/64") |
1295 | 16 | .FilterOut("^/64") |
1296 | 16 | .FilterOut("/mips16/64") |
1297 | 16 | .Either(BigEndian, LittleEndian) |
1298 | 16 | .Maybe(SoftFloat) |
1299 | 16 | .Maybe(Nan2008) |
1300 | 16 | .FilterOut(".*sof/nan2008") |
1301 | 16 | .makeMultilibSet() |
1302 | 16 | .FilterOut(NonExistent) |
1303 | 16 | .setIncludeDirsCallback([](const Multilib &M) { |
1304 | 0 | std::vector<std::string> Dirs({"/include"}); |
1305 | 0 | if (StringRef(M.includeSuffix()).startswith("/uclibc")) |
1306 | 0 | Dirs.push_back("/../../../../sysroot/uclibc/usr/include"); |
1307 | 0 | else |
1308 | 0 | Dirs.push_back("/../../../../sysroot/usr/include"); |
1309 | 0 | return Dirs; |
1310 | 0 | }); |
1311 | 16 | } |
1312 | | |
1313 | | // CodeScape IMG toolchain starting from v1.3. |
1314 | 16 | MultilibSet MtiMipsMultilibsV2; |
1315 | 16 | { |
1316 | 16 | auto BeHard = MultilibBuilder("/mips-r2-hard") |
1317 | 16 | .flag("-EB") |
1318 | 16 | .flag("-msoft-float", /*Disallow=*/true) |
1319 | 16 | .flag("-mnan=2008", /*Disallow=*/true) |
1320 | 16 | .flag("-muclibc", /*Disallow=*/true); |
1321 | 16 | auto BeSoft = MultilibBuilder("/mips-r2-soft") |
1322 | 16 | .flag("-EB") |
1323 | 16 | .flag("-msoft-float") |
1324 | 16 | .flag("-mnan=2008", /*Disallow=*/true); |
1325 | 16 | auto ElHard = MultilibBuilder("/mipsel-r2-hard") |
1326 | 16 | .flag("-EL") |
1327 | 16 | .flag("-msoft-float", /*Disallow=*/true) |
1328 | 16 | .flag("-mnan=2008", /*Disallow=*/true) |
1329 | 16 | .flag("-muclibc", /*Disallow=*/true); |
1330 | 16 | auto ElSoft = MultilibBuilder("/mipsel-r2-soft") |
1331 | 16 | .flag("-EL") |
1332 | 16 | .flag("-msoft-float") |
1333 | 16 | .flag("-mnan=2008", /*Disallow=*/true) |
1334 | 16 | .flag("-mmicromips", /*Disallow=*/true); |
1335 | 16 | auto BeHardNan = MultilibBuilder("/mips-r2-hard-nan2008") |
1336 | 16 | .flag("-EB") |
1337 | 16 | .flag("-msoft-float", /*Disallow=*/true) |
1338 | 16 | .flag("-mnan=2008") |
1339 | 16 | .flag("-muclibc", /*Disallow=*/true); |
1340 | 16 | auto ElHardNan = MultilibBuilder("/mipsel-r2-hard-nan2008") |
1341 | 16 | .flag("-EL") |
1342 | 16 | .flag("-msoft-float", /*Disallow=*/true) |
1343 | 16 | .flag("-mnan=2008") |
1344 | 16 | .flag("-muclibc", /*Disallow=*/true) |
1345 | 16 | .flag("-mmicromips", /*Disallow=*/true); |
1346 | 16 | auto BeHardNanUclibc = MultilibBuilder("/mips-r2-hard-nan2008-uclibc") |
1347 | 16 | .flag("-EB") |
1348 | 16 | .flag("-msoft-float", /*Disallow=*/true) |
1349 | 16 | .flag("-mnan=2008") |
1350 | 16 | .flag("-muclibc"); |
1351 | 16 | auto ElHardNanUclibc = MultilibBuilder("/mipsel-r2-hard-nan2008-uclibc") |
1352 | 16 | .flag("-EL") |
1353 | 16 | .flag("-msoft-float", /*Disallow=*/true) |
1354 | 16 | .flag("-mnan=2008") |
1355 | 16 | .flag("-muclibc"); |
1356 | 16 | auto BeHardUclibc = MultilibBuilder("/mips-r2-hard-uclibc") |
1357 | 16 | .flag("-EB") |
1358 | 16 | .flag("-msoft-float", /*Disallow=*/true) |
1359 | 16 | .flag("-mnan=2008", /*Disallow=*/true) |
1360 | 16 | .flag("-muclibc"); |
1361 | 16 | auto ElHardUclibc = MultilibBuilder("/mipsel-r2-hard-uclibc") |
1362 | 16 | .flag("-EL") |
1363 | 16 | .flag("-msoft-float", /*Disallow=*/true) |
1364 | 16 | .flag("-mnan=2008", /*Disallow=*/true) |
1365 | 16 | .flag("-muclibc"); |
1366 | 16 | auto ElMicroHardNan = MultilibBuilder("/micromipsel-r2-hard-nan2008") |
1367 | 16 | .flag("-EL") |
1368 | 16 | .flag("-msoft-float", /*Disallow=*/true) |
1369 | 16 | .flag("-mnan=2008") |
1370 | 16 | .flag("-mmicromips"); |
1371 | 16 | auto ElMicroSoft = MultilibBuilder("/micromipsel-r2-soft") |
1372 | 16 | .flag("-EL") |
1373 | 16 | .flag("-msoft-float") |
1374 | 16 | .flag("-mnan=2008", /*Disallow=*/true) |
1375 | 16 | .flag("-mmicromips"); |
1376 | | |
1377 | 16 | auto O32 = MultilibBuilder("/lib") |
1378 | 16 | .osSuffix("") |
1379 | 16 | .flag("-mabi=n32", /*Disallow=*/true) |
1380 | 16 | .flag("-mabi=n64", /*Disallow=*/true); |
1381 | 16 | auto N32 = MultilibBuilder("/lib32") |
1382 | 16 | .osSuffix("") |
1383 | 16 | .flag("-mabi=n32") |
1384 | 16 | .flag("-mabi=n64", /*Disallow=*/true); |
1385 | 16 | auto N64 = MultilibBuilder("/lib64") |
1386 | 16 | .osSuffix("") |
1387 | 16 | .flag("-mabi=n32", /*Disallow=*/true) |
1388 | 16 | .flag("-mabi=n64"); |
1389 | | |
1390 | 16 | MtiMipsMultilibsV2 = |
1391 | 16 | MultilibSetBuilder() |
1392 | 16 | .Either({BeHard, BeSoft, ElHard, ElSoft, BeHardNan, ElHardNan, |
1393 | 16 | BeHardNanUclibc, ElHardNanUclibc, BeHardUclibc, |
1394 | 16 | ElHardUclibc, ElMicroHardNan, ElMicroSoft}) |
1395 | 16 | .Either(O32, N32, N64) |
1396 | 16 | .makeMultilibSet() |
1397 | 16 | .FilterOut(NonExistent) |
1398 | 16 | .setIncludeDirsCallback([](const Multilib &M) { |
1399 | 16 | return std::vector<std::string>({"/../../../../sysroot" + |
1400 | 16 | M.includeSuffix() + |
1401 | 16 | "/../usr/include"}); |
1402 | 16 | }) |
1403 | 28 | .setFilePathsCallback([](const Multilib &M) { |
1404 | 28 | return std::vector<std::string>( |
1405 | 28 | {"/../../../../mips-mti-linux-gnu/lib" + M.gccSuffix()}); |
1406 | 28 | }); |
1407 | 16 | } |
1408 | 32 | for (auto *Candidate : {&MtiMipsMultilibsV1, &MtiMipsMultilibsV2}) { |
1409 | 32 | if (Candidate->select(Flags, Result.SelectedMultilibs)) { |
1410 | 16 | Result.Multilibs = *Candidate; |
1411 | 16 | return true; |
1412 | 16 | } |
1413 | 32 | } |
1414 | 0 | return false; |
1415 | 16 | } |
1416 | | |
1417 | | static bool findMipsImgMultilibs(const Multilib::flags_list &Flags, |
1418 | | FilterNonExistent &NonExistent, |
1419 | 0 | DetectedMultilibs &Result) { |
1420 | | // CodeScape IMG toolchain v1.2 and early. |
1421 | 0 | MultilibSet ImgMultilibsV1; |
1422 | 0 | { |
1423 | 0 | auto Mips64r6 = MultilibBuilder("/mips64r6") |
1424 | 0 | .flag("-m64") |
1425 | 0 | .flag("-m32", /*Disallow=*/true); |
1426 | |
|
1427 | 0 | auto LittleEndian = |
1428 | 0 | MultilibBuilder("/el").flag("-EL").flag("-EB", /*Disallow=*/true); |
1429 | |
|
1430 | 0 | auto MAbi64 = MultilibBuilder("/64") |
1431 | 0 | .flag("-mabi=n64") |
1432 | 0 | .flag("-mabi=n32", /*Disallow=*/true) |
1433 | 0 | .flag("-m32", /*Disallow=*/true); |
1434 | |
|
1435 | 0 | ImgMultilibsV1 = |
1436 | 0 | MultilibSetBuilder() |
1437 | 0 | .Maybe(Mips64r6) |
1438 | 0 | .Maybe(MAbi64) |
1439 | 0 | .Maybe(LittleEndian) |
1440 | 0 | .makeMultilibSet() |
1441 | 0 | .FilterOut(NonExistent) |
1442 | 0 | .setIncludeDirsCallback([](const Multilib &M) { |
1443 | 0 | return std::vector<std::string>( |
1444 | 0 | {"/include", "/../../../../sysroot/usr/include"}); |
1445 | 0 | }); |
1446 | 0 | } |
1447 | | |
1448 | | // CodeScape IMG toolchain starting from v1.3. |
1449 | 0 | MultilibSet ImgMultilibsV2; |
1450 | 0 | { |
1451 | 0 | auto BeHard = MultilibBuilder("/mips-r6-hard") |
1452 | 0 | .flag("-EB") |
1453 | 0 | .flag("-msoft-float", /*Disallow=*/true) |
1454 | 0 | .flag("-mmicromips", /*Disallow=*/true); |
1455 | 0 | auto BeSoft = MultilibBuilder("/mips-r6-soft") |
1456 | 0 | .flag("-EB") |
1457 | 0 | .flag("-msoft-float") |
1458 | 0 | .flag("-mmicromips", /*Disallow=*/true); |
1459 | 0 | auto ElHard = MultilibBuilder("/mipsel-r6-hard") |
1460 | 0 | .flag("-EL") |
1461 | 0 | .flag("-msoft-float", /*Disallow=*/true) |
1462 | 0 | .flag("-mmicromips", /*Disallow=*/true); |
1463 | 0 | auto ElSoft = MultilibBuilder("/mipsel-r6-soft") |
1464 | 0 | .flag("-EL") |
1465 | 0 | .flag("-msoft-float") |
1466 | 0 | .flag("-mmicromips", /*Disallow=*/true); |
1467 | 0 | auto BeMicroHard = MultilibBuilder("/micromips-r6-hard") |
1468 | 0 | .flag("-EB") |
1469 | 0 | .flag("-msoft-float", /*Disallow=*/true) |
1470 | 0 | .flag("-mmicromips"); |
1471 | 0 | auto BeMicroSoft = MultilibBuilder("/micromips-r6-soft") |
1472 | 0 | .flag("-EB") |
1473 | 0 | .flag("-msoft-float") |
1474 | 0 | .flag("-mmicromips"); |
1475 | 0 | auto ElMicroHard = MultilibBuilder("/micromipsel-r6-hard") |
1476 | 0 | .flag("-EL") |
1477 | 0 | .flag("-msoft-float", /*Disallow=*/true) |
1478 | 0 | .flag("-mmicromips"); |
1479 | 0 | auto ElMicroSoft = MultilibBuilder("/micromipsel-r6-soft") |
1480 | 0 | .flag("-EL") |
1481 | 0 | .flag("-msoft-float") |
1482 | 0 | .flag("-mmicromips"); |
1483 | |
|
1484 | 0 | auto O32 = MultilibBuilder("/lib") |
1485 | 0 | .osSuffix("") |
1486 | 0 | .flag("-mabi=n32", /*Disallow=*/true) |
1487 | 0 | .flag("-mabi=n64", /*Disallow=*/true); |
1488 | 0 | auto N32 = MultilibBuilder("/lib32") |
1489 | 0 | .osSuffix("") |
1490 | 0 | .flag("-mabi=n32") |
1491 | 0 | .flag("-mabi=n64", /*Disallow=*/true); |
1492 | 0 | auto N64 = MultilibBuilder("/lib64") |
1493 | 0 | .osSuffix("") |
1494 | 0 | .flag("-mabi=n32", /*Disallow=*/true) |
1495 | 0 | .flag("-mabi=n64"); |
1496 | |
|
1497 | 0 | ImgMultilibsV2 = |
1498 | 0 | MultilibSetBuilder() |
1499 | 0 | .Either({BeHard, BeSoft, ElHard, ElSoft, BeMicroHard, BeMicroSoft, |
1500 | 0 | ElMicroHard, ElMicroSoft}) |
1501 | 0 | .Either(O32, N32, N64) |
1502 | 0 | .makeMultilibSet() |
1503 | 0 | .FilterOut(NonExistent) |
1504 | 0 | .setIncludeDirsCallback([](const Multilib &M) { |
1505 | 0 | return std::vector<std::string>({"/../../../../sysroot" + |
1506 | 0 | M.includeSuffix() + |
1507 | 0 | "/../usr/include"}); |
1508 | 0 | }) |
1509 | 0 | .setFilePathsCallback([](const Multilib &M) { |
1510 | 0 | return std::vector<std::string>( |
1511 | 0 | {"/../../../../mips-img-linux-gnu/lib" + M.gccSuffix()}); |
1512 | 0 | }); |
1513 | 0 | } |
1514 | 0 | for (auto *Candidate : {&ImgMultilibsV1, &ImgMultilibsV2}) { |
1515 | 0 | if (Candidate->select(Flags, Result.SelectedMultilibs)) { |
1516 | 0 | Result.Multilibs = *Candidate; |
1517 | 0 | return true; |
1518 | 0 | } |
1519 | 0 | } |
1520 | 0 | return false; |
1521 | 0 | } |
1522 | | |
1523 | | bool clang::driver::findMIPSMultilibs(const Driver &D, |
1524 | | const llvm::Triple &TargetTriple, |
1525 | | StringRef Path, const ArgList &Args, |
1526 | 28 | DetectedMultilibs &Result) { |
1527 | 28 | FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); |
1528 | | |
1529 | 28 | StringRef CPUName; |
1530 | 28 | StringRef ABIName; |
1531 | 28 | tools::mips::getMipsCPUAndABI(Args, TargetTriple, CPUName, ABIName); |
1532 | | |
1533 | 28 | llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); |
1534 | | |
1535 | 28 | Multilib::flags_list Flags; |
1536 | 28 | addMultilibFlag(TargetTriple.isMIPS32(), "-m32", Flags); |
1537 | 28 | addMultilibFlag(TargetTriple.isMIPS64(), "-m64", Flags); |
1538 | 28 | addMultilibFlag(isMips16(Args), "-mips16", Flags); |
1539 | 28 | addMultilibFlag(CPUName == "mips32", "-march=mips32", Flags); |
1540 | 28 | addMultilibFlag(CPUName == "mips32r2" || CPUName == "mips32r3"12 || |
1541 | 28 | CPUName == "mips32r5"12 || CPUName == "p5600"12 , |
1542 | 28 | "-march=mips32r2", Flags); |
1543 | 28 | addMultilibFlag(CPUName == "mips32r6", "-march=mips32r6", Flags); |
1544 | 28 | addMultilibFlag(CPUName == "mips64", "-march=mips64", Flags); |
1545 | 28 | addMultilibFlag(CPUName == "mips64r2" || CPUName == "mips64r3"16 || |
1546 | 28 | CPUName == "mips64r5"16 || CPUName == "octeon"16 || |
1547 | 28 | CPUName == "octeon+"16 , |
1548 | 28 | "-march=mips64r2", Flags); |
1549 | 28 | addMultilibFlag(CPUName == "mips64r6", "-march=mips64r6", Flags); |
1550 | 28 | addMultilibFlag(isMicroMips(Args), "-mmicromips", Flags); |
1551 | 28 | addMultilibFlag(tools::mips::isUCLibc(Args), "-muclibc", Flags); |
1552 | 28 | addMultilibFlag(tools::mips::isNaN2008(D, Args, TargetTriple), "-mnan=2008", |
1553 | 28 | Flags); |
1554 | 28 | addMultilibFlag(ABIName == "n32", "-mabi=n32", Flags); |
1555 | 28 | addMultilibFlag(ABIName == "n64", "-mabi=n64", Flags); |
1556 | 28 | addMultilibFlag(isSoftFloatABI(Args), "-msoft-float", Flags); |
1557 | 28 | addMultilibFlag(!isSoftFloatABI(Args), "-mhard-float", Flags); |
1558 | 28 | addMultilibFlag(isMipsEL(TargetArch), "-EL", Flags); |
1559 | 28 | addMultilibFlag(!isMipsEL(TargetArch), "-EB", Flags); |
1560 | | |
1561 | 28 | if (TargetTriple.isAndroid()) |
1562 | 0 | return findMipsAndroidMultilibs(D.getVFS(), Path, Flags, NonExistent, |
1563 | 0 | Result); |
1564 | | |
1565 | 28 | if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies && |
1566 | 28 | TargetTriple.getOS() == llvm::Triple::Linux16 && |
1567 | 28 | TargetTriple.getEnvironment() == llvm::Triple::UnknownEnvironment16 ) |
1568 | 0 | return findMipsMuslMultilibs(Flags, NonExistent, Result); |
1569 | | |
1570 | 28 | if (TargetTriple.getVendor() == llvm::Triple::MipsTechnologies && |
1571 | 28 | TargetTriple.getOS() == llvm::Triple::Linux16 && |
1572 | 28 | TargetTriple.isGNUEnvironment()16 ) |
1573 | 16 | return findMipsMtiMultilibs(Flags, NonExistent, Result); |
1574 | | |
1575 | 12 | if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies && |
1576 | 12 | TargetTriple.getOS() == llvm::Triple::Linux0 && |
1577 | 12 | TargetTriple.isGNUEnvironment()0 ) |
1578 | 0 | return findMipsImgMultilibs(Flags, NonExistent, Result); |
1579 | | |
1580 | 12 | if (findMipsCsMultilibs(Flags, NonExistent, Result)) |
1581 | 4 | return true; |
1582 | | |
1583 | | // Fallback to the regular toolchain-tree structure. |
1584 | 8 | Multilib Default; |
1585 | 8 | Result.Multilibs.push_back(Default); |
1586 | 8 | Result.Multilibs.FilterOut(NonExistent); |
1587 | | |
1588 | 8 | if (Result.Multilibs.select(Flags, Result.SelectedMultilibs)) { |
1589 | 8 | Result.BiarchSibling = Multilib(); |
1590 | 8 | return true; |
1591 | 8 | } |
1592 | | |
1593 | 0 | return false; |
1594 | 8 | } |
1595 | | |
1596 | | static void findAndroidArmMultilibs(const Driver &D, |
1597 | | const llvm::Triple &TargetTriple, |
1598 | | StringRef Path, const ArgList &Args, |
1599 | 18 | DetectedMultilibs &Result) { |
1600 | | // Find multilibs with subdirectories like armv7-a, thumb, armv7-a/thumb. |
1601 | 18 | FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); |
1602 | 18 | MultilibBuilder ArmV7Multilib = MultilibBuilder("/armv7-a") |
1603 | 18 | .flag("-march=armv7-a") |
1604 | 18 | .flag("-mthumb", /*Disallow=*/true); |
1605 | 18 | MultilibBuilder ThumbMultilib = MultilibBuilder("/thumb") |
1606 | 18 | .flag("-march=armv7-a", /*Disallow=*/true) |
1607 | 18 | .flag("-mthumb"); |
1608 | 18 | MultilibBuilder ArmV7ThumbMultilib = |
1609 | 18 | MultilibBuilder("/armv7-a/thumb").flag("-march=armv7-a").flag("-mthumb"); |
1610 | 18 | MultilibBuilder DefaultMultilib = |
1611 | 18 | MultilibBuilder("") |
1612 | 18 | .flag("-march=armv7-a", /*Disallow=*/true) |
1613 | 18 | .flag("-mthumb", /*Disallow=*/true); |
1614 | 18 | MultilibSet AndroidArmMultilibs = |
1615 | 18 | MultilibSetBuilder() |
1616 | 18 | .Either(ThumbMultilib, ArmV7Multilib, ArmV7ThumbMultilib, |
1617 | 18 | DefaultMultilib) |
1618 | 18 | .makeMultilibSet() |
1619 | 18 | .FilterOut(NonExistent); |
1620 | | |
1621 | 18 | Multilib::flags_list Flags; |
1622 | 18 | llvm::StringRef Arch = Args.getLastArgValue(options::OPT_march_EQ); |
1623 | 18 | bool IsArmArch = TargetTriple.getArch() == llvm::Triple::arm; |
1624 | 18 | bool IsThumbArch = TargetTriple.getArch() == llvm::Triple::thumb; |
1625 | 18 | bool IsV7SubArch = TargetTriple.getSubArch() == llvm::Triple::ARMSubArch_v7; |
1626 | 18 | bool IsThumbMode = IsThumbArch || |
1627 | 18 | Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, false) || |
1628 | 18 | (13 IsArmArch13 && llvm::ARM::parseArchISA(Arch) == llvm::ARM::ISAKind::THUMB13 ); |
1629 | 18 | bool IsArmV7Mode = (IsArmArch || IsThumbArch0 ) && |
1630 | 18 | (llvm::ARM::parseArchVersion(Arch) == 7 || |
1631 | 18 | (13 IsArmArch13 && Arch == ""13 && IsV7SubArch13 )); |
1632 | 18 | addMultilibFlag(IsArmV7Mode, "-march=armv7-a", Flags); |
1633 | 18 | addMultilibFlag(IsThumbMode, "-mthumb", Flags); |
1634 | | |
1635 | 18 | if (AndroidArmMultilibs.select(Flags, Result.SelectedMultilibs)) |
1636 | 18 | Result.Multilibs = AndroidArmMultilibs; |
1637 | 18 | } |
1638 | | |
1639 | | static bool findMSP430Multilibs(const Driver &D, |
1640 | | const llvm::Triple &TargetTriple, |
1641 | | StringRef Path, const ArgList &Args, |
1642 | 13 | DetectedMultilibs &Result) { |
1643 | 13 | FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); |
1644 | 13 | MultilibBuilder WithoutExceptions = |
1645 | 13 | MultilibBuilder("/430").flag("-exceptions", /*Disallow=*/true); |
1646 | 13 | MultilibBuilder WithExceptions = |
1647 | 13 | MultilibBuilder("/430/exceptions").flag("-exceptions"); |
1648 | | |
1649 | | // FIXME: when clang starts to support msp430x ISA additional logic |
1650 | | // to select between multilib must be implemented |
1651 | | // MultilibBuilder MSP430xMultilib = MultilibBuilder("/large"); |
1652 | | |
1653 | 13 | Result.Multilibs.push_back(WithoutExceptions.makeMultilib()); |
1654 | 13 | Result.Multilibs.push_back(WithExceptions.makeMultilib()); |
1655 | 13 | Result.Multilibs.FilterOut(NonExistent); |
1656 | | |
1657 | 13 | Multilib::flags_list Flags; |
1658 | 13 | addMultilibFlag(Args.hasFlag(options::OPT_fexceptions, |
1659 | 13 | options::OPT_fno_exceptions, false), |
1660 | 13 | "-exceptions", Flags); |
1661 | 13 | if (Result.Multilibs.select(Flags, Result.SelectedMultilibs)) |
1662 | 13 | return true; |
1663 | | |
1664 | 0 | return false; |
1665 | 13 | } |
1666 | | |
1667 | | static void findCSKYMultilibs(const Driver &D, const llvm::Triple &TargetTriple, |
1668 | | StringRef Path, const ArgList &Args, |
1669 | 2 | DetectedMultilibs &Result) { |
1670 | 2 | FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); |
1671 | | |
1672 | 2 | tools::csky::FloatABI TheFloatABI = tools::csky::getCSKYFloatABI(D, Args); |
1673 | 2 | std::optional<llvm::StringRef> Res = |
1674 | 2 | tools::csky::getCSKYArchName(D, Args, TargetTriple); |
1675 | | |
1676 | 2 | if (!Res) |
1677 | 0 | return; |
1678 | 2 | auto ARCHName = *Res; |
1679 | | |
1680 | 2 | Multilib::flags_list Flags; |
1681 | 2 | addMultilibFlag(TheFloatABI == tools::csky::FloatABI::Hard, "-hard-fp", |
1682 | 2 | Flags); |
1683 | 2 | addMultilibFlag(TheFloatABI == tools::csky::FloatABI::SoftFP, "-soft-fp", |
1684 | 2 | Flags); |
1685 | 2 | addMultilibFlag(TheFloatABI == tools::csky::FloatABI::Soft, "-soft", Flags); |
1686 | 2 | addMultilibFlag(ARCHName == "ck801", "-march=ck801", Flags); |
1687 | 2 | addMultilibFlag(ARCHName == "ck802", "-march=ck802", Flags); |
1688 | 2 | addMultilibFlag(ARCHName == "ck803", "-march=ck803", Flags); |
1689 | 2 | addMultilibFlag(ARCHName == "ck804", "-march=ck804", Flags); |
1690 | 2 | addMultilibFlag(ARCHName == "ck805", "-march=ck805", Flags); |
1691 | 2 | addMultilibFlag(ARCHName == "ck807", "-march=ck807", Flags); |
1692 | 2 | addMultilibFlag(ARCHName == "ck810", "-march=ck810", Flags); |
1693 | 2 | addMultilibFlag(ARCHName == "ck810v", "-march=ck810v", Flags); |
1694 | 2 | addMultilibFlag(ARCHName == "ck860", "-march=ck860", Flags); |
1695 | 2 | addMultilibFlag(ARCHName == "ck860v", "-march=ck860v", Flags); |
1696 | | |
1697 | 2 | bool isBigEndian = false; |
1698 | 2 | if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian, |
1699 | 2 | options::OPT_mbig_endian)) |
1700 | 0 | isBigEndian = !A->getOption().matches(options::OPT_mlittle_endian); |
1701 | 2 | addMultilibFlag(isBigEndian, "-EB", Flags); |
1702 | | |
1703 | 2 | auto HardFloat = MultilibBuilder("/hard-fp").flag("-hard-fp"); |
1704 | 2 | auto SoftFpFloat = MultilibBuilder("/soft-fp").flag("-soft-fp"); |
1705 | 2 | auto SoftFloat = MultilibBuilder("").flag("-soft"); |
1706 | 2 | auto Arch801 = MultilibBuilder("/ck801").flag("-march=ck801"); |
1707 | 2 | auto Arch802 = MultilibBuilder("/ck802").flag("-march=ck802"); |
1708 | 2 | auto Arch803 = MultilibBuilder("/ck803").flag("-march=ck803"); |
1709 | | // CK804 use the same library as CK803 |
1710 | 2 | auto Arch804 = MultilibBuilder("/ck803").flag("-march=ck804"); |
1711 | 2 | auto Arch805 = MultilibBuilder("/ck805").flag("-march=ck805"); |
1712 | 2 | auto Arch807 = MultilibBuilder("/ck807").flag("-march=ck807"); |
1713 | 2 | auto Arch810 = MultilibBuilder("").flag("-march=ck810"); |
1714 | 2 | auto Arch810v = MultilibBuilder("/ck810v").flag("-march=ck810v"); |
1715 | 2 | auto Arch860 = MultilibBuilder("/ck860").flag("-march=ck860"); |
1716 | 2 | auto Arch860v = MultilibBuilder("/ck860v").flag("-march=ck860v"); |
1717 | 2 | auto BigEndian = MultilibBuilder("/big").flag("-EB"); |
1718 | | |
1719 | 2 | MultilibSet CSKYMultilibs = |
1720 | 2 | MultilibSetBuilder() |
1721 | 2 | .Maybe(BigEndian) |
1722 | 2 | .Either({Arch801, Arch802, Arch803, Arch804, Arch805, Arch807, |
1723 | 2 | Arch810, Arch810v, Arch860, Arch860v}) |
1724 | 2 | .Either(HardFloat, SoftFpFloat, SoftFloat) |
1725 | 2 | .makeMultilibSet() |
1726 | 2 | .FilterOut(NonExistent); |
1727 | | |
1728 | 2 | if (CSKYMultilibs.select(Flags, Result.SelectedMultilibs)) |
1729 | 2 | Result.Multilibs = CSKYMultilibs; |
1730 | 2 | } |
1731 | | |
1732 | | static void findRISCVBareMetalMultilibs(const Driver &D, |
1733 | | const llvm::Triple &TargetTriple, |
1734 | | StringRef Path, const ArgList &Args, |
1735 | 33 | DetectedMultilibs &Result) { |
1736 | 33 | FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); |
1737 | 33 | struct RiscvMultilib { |
1738 | 33 | StringRef march; |
1739 | 33 | StringRef mabi; |
1740 | 33 | }; |
1741 | | // currently only support the set of multilibs like riscv-gnu-toolchain does. |
1742 | | // TODO: support MULTILIB_REUSE |
1743 | 33 | constexpr RiscvMultilib RISCVMultilibSet[] = { |
1744 | 33 | {"rv32i", "ilp32"}, {"rv32im", "ilp32"}, {"rv32iac", "ilp32"}, |
1745 | 33 | {"rv32imac", "ilp32"}, {"rv32imafc", "ilp32f"}, {"rv64imac", "lp64"}, |
1746 | 33 | {"rv64imafdc", "lp64d"}}; |
1747 | | |
1748 | 33 | std::vector<MultilibBuilder> Ms; |
1749 | 231 | for (auto Element : RISCVMultilibSet) { |
1750 | | // multilib path rule is ${march}/${mabi} |
1751 | 231 | Ms.emplace_back( |
1752 | 231 | MultilibBuilder( |
1753 | 231 | (Twine(Element.march) + "/" + Twine(Element.mabi)).str()) |
1754 | 231 | .flag(Twine("-march=", Element.march).str()) |
1755 | 231 | .flag(Twine("-mabi=", Element.mabi).str())); |
1756 | 231 | } |
1757 | 33 | MultilibSet RISCVMultilibs = |
1758 | 33 | MultilibSetBuilder() |
1759 | 33 | .Either(Ms) |
1760 | 33 | .makeMultilibSet() |
1761 | 33 | .FilterOut(NonExistent) |
1762 | 33 | .setFilePathsCallback([](const Multilib &M) { |
1763 | 11 | return std::vector<std::string>( |
1764 | 11 | {M.gccSuffix(), |
1765 | 11 | "/../../../../riscv64-unknown-elf/lib" + M.gccSuffix(), |
1766 | 11 | "/../../../../riscv32-unknown-elf/lib" + M.gccSuffix()}); |
1767 | 11 | }); |
1768 | | |
1769 | 33 | Multilib::flags_list Flags; |
1770 | 33 | llvm::StringSet<> Added_ABIs; |
1771 | 33 | StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple); |
1772 | 33 | StringRef MArch = tools::riscv::getRISCVArch(Args, TargetTriple); |
1773 | 231 | for (auto Element : RISCVMultilibSet) { |
1774 | 231 | addMultilibFlag(MArch == Element.march, |
1775 | 231 | Twine("-march=", Element.march).str().c_str(), Flags); |
1776 | 231 | if (!Added_ABIs.count(Element.mabi)) { |
1777 | 132 | Added_ABIs.insert(Element.mabi); |
1778 | 132 | addMultilibFlag(ABIName == Element.mabi, |
1779 | 132 | Twine("-mabi=", Element.mabi).str().c_str(), Flags); |
1780 | 132 | } |
1781 | 231 | } |
1782 | | |
1783 | 33 | if (RISCVMultilibs.select(Flags, Result.SelectedMultilibs)) |
1784 | 11 | Result.Multilibs = RISCVMultilibs; |
1785 | 33 | } |
1786 | | |
1787 | | static void findRISCVMultilibs(const Driver &D, |
1788 | | const llvm::Triple &TargetTriple, StringRef Path, |
1789 | 42 | const ArgList &Args, DetectedMultilibs &Result) { |
1790 | 42 | if (TargetTriple.getOS() == llvm::Triple::UnknownOS) |
1791 | 33 | return findRISCVBareMetalMultilibs(D, TargetTriple, Path, Args, Result); |
1792 | | |
1793 | 9 | FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); |
1794 | 9 | MultilibBuilder Ilp32 = |
1795 | 9 | MultilibBuilder("lib32/ilp32").flag("-m32").flag("-mabi=ilp32"); |
1796 | 9 | MultilibBuilder Ilp32f = |
1797 | 9 | MultilibBuilder("lib32/ilp32f").flag("-m32").flag("-mabi=ilp32f"); |
1798 | 9 | MultilibBuilder Ilp32d = |
1799 | 9 | MultilibBuilder("lib32/ilp32d").flag("-m32").flag("-mabi=ilp32d"); |
1800 | 9 | MultilibBuilder Lp64 = |
1801 | 9 | MultilibBuilder("lib64/lp64").flag("-m64").flag("-mabi=lp64"); |
1802 | 9 | MultilibBuilder Lp64f = |
1803 | 9 | MultilibBuilder("lib64/lp64f").flag("-m64").flag("-mabi=lp64f"); |
1804 | 9 | MultilibBuilder Lp64d = |
1805 | 9 | MultilibBuilder("lib64/lp64d").flag("-m64").flag("-mabi=lp64d"); |
1806 | 9 | MultilibSet RISCVMultilibs = |
1807 | 9 | MultilibSetBuilder() |
1808 | 9 | .Either({Ilp32, Ilp32f, Ilp32d, Lp64, Lp64f, Lp64d}) |
1809 | 9 | .makeMultilibSet() |
1810 | 9 | .FilterOut(NonExistent); |
1811 | | |
1812 | 9 | Multilib::flags_list Flags; |
1813 | 9 | bool IsRV64 = TargetTriple.getArch() == llvm::Triple::riscv64; |
1814 | 9 | StringRef ABIName = tools::riscv::getRISCVABI(Args, TargetTriple); |
1815 | | |
1816 | 9 | addMultilibFlag(!IsRV64, "-m32", Flags); |
1817 | 9 | addMultilibFlag(IsRV64, "-m64", Flags); |
1818 | 9 | addMultilibFlag(ABIName == "ilp32", "-mabi=ilp32", Flags); |
1819 | 9 | addMultilibFlag(ABIName == "ilp32f", "-mabi=ilp32f", Flags); |
1820 | 9 | addMultilibFlag(ABIName == "ilp32d", "-mabi=ilp32d", Flags); |
1821 | 9 | addMultilibFlag(ABIName == "lp64", "-mabi=lp64", Flags); |
1822 | 9 | addMultilibFlag(ABIName == "lp64f", "-mabi=lp64f", Flags); |
1823 | 9 | addMultilibFlag(ABIName == "lp64d", "-mabi=lp64d", Flags); |
1824 | | |
1825 | 9 | if (RISCVMultilibs.select(Flags, Result.SelectedMultilibs)) |
1826 | 4 | Result.Multilibs = RISCVMultilibs; |
1827 | 9 | } |
1828 | | |
1829 | | static bool findBiarchMultilibs(const Driver &D, |
1830 | | const llvm::Triple &TargetTriple, |
1831 | | StringRef Path, const ArgList &Args, |
1832 | | bool NeedsBiarchSuffix, |
1833 | 321 | DetectedMultilibs &Result) { |
1834 | 321 | MultilibBuilder DefaultBuilder; |
1835 | | |
1836 | | // Some versions of SUSE and Fedora on ppc64 put 32-bit libs |
1837 | | // in what would normally be GCCInstallPath and put the 64-bit |
1838 | | // libs in a subdirectory named 64. The simple logic we follow is that |
1839 | | // *if* there is a subdirectory of the right name with crtbegin.o in it, |
1840 | | // we use that. If not, and if not a biarch triple alias, we look for |
1841 | | // crtbegin.o without the subdirectory. |
1842 | | |
1843 | 321 | StringRef Suff64 = "/64"; |
1844 | | // Solaris uses platform-specific suffixes instead of /64. |
1845 | 321 | if (TargetTriple.isOSSolaris()) { |
1846 | 72 | switch (TargetTriple.getArch()) { |
1847 | 11 | case llvm::Triple::x86: |
1848 | 20 | case llvm::Triple::x86_64: |
1849 | 20 | Suff64 = "/amd64"; |
1850 | 20 | break; |
1851 | 42 | case llvm::Triple::sparc: |
1852 | 52 | case llvm::Triple::sparcv9: |
1853 | 52 | Suff64 = "/sparcv9"; |
1854 | 52 | break; |
1855 | 0 | default: |
1856 | 0 | break; |
1857 | 72 | } |
1858 | 72 | } |
1859 | | |
1860 | 321 | Multilib Alt64 = MultilibBuilder() |
1861 | 321 | .gccSuffix(Suff64) |
1862 | 321 | .includeSuffix(Suff64) |
1863 | 321 | .flag("-m32", /*Disallow=*/true) |
1864 | 321 | .flag("-m64") |
1865 | 321 | .flag("-mx32", /*Disallow=*/true) |
1866 | 321 | .makeMultilib(); |
1867 | 321 | Multilib Alt32 = MultilibBuilder() |
1868 | 321 | .gccSuffix("/32") |
1869 | 321 | .includeSuffix("/32") |
1870 | 321 | .flag("-m32") |
1871 | 321 | .flag("-m64", /*Disallow=*/true) |
1872 | 321 | .flag("-mx32", /*Disallow=*/true) |
1873 | 321 | .makeMultilib(); |
1874 | 321 | Multilib Altx32 = MultilibBuilder() |
1875 | 321 | .gccSuffix("/x32") |
1876 | 321 | .includeSuffix("/x32") |
1877 | 321 | .flag("-m32", /*Disallow=*/true) |
1878 | 321 | .flag("-m64", /*Disallow=*/true) |
1879 | 321 | .flag("-mx32") |
1880 | 321 | .makeMultilib(); |
1881 | 321 | Multilib Alt32sparc = MultilibBuilder() |
1882 | 321 | .gccSuffix("/sparcv8plus") |
1883 | 321 | .includeSuffix("/sparcv8plus") |
1884 | 321 | .flag("-m32") |
1885 | 321 | .flag("-m64", /*Disallow=*/true) |
1886 | 321 | .makeMultilib(); |
1887 | | |
1888 | | // GCC toolchain for IAMCU doesn't have crtbegin.o, so look for libgcc.a. |
1889 | 321 | FilterNonExistent NonExistent( |
1890 | 321 | Path, TargetTriple.isOSIAMCU() ? "/libgcc.a"0 : "/crtbegin.o", D.getVFS()); |
1891 | | |
1892 | | // Determine default multilib from: 32, 64, x32 |
1893 | | // Also handle cases such as 64 on 32, 32 on 64, etc. |
1894 | 321 | enum { UNKNOWN, WANT32, WANT64, WANTX32 } Want = UNKNOWN; |
1895 | 321 | const bool IsX32 = TargetTriple.isX32(); |
1896 | 321 | if (TargetTriple.isArch32Bit() && !NonExistent(Alt32)140 ) |
1897 | 14 | Want = WANT64; |
1898 | 321 | if (TargetTriple.isArch32Bit() && !NonExistent(Alt32sparc)140 ) |
1899 | 2 | Want = WANT64; |
1900 | 319 | else if (TargetTriple.isArch64Bit() && IsX32181 && !NonExistent(Altx32)13 ) |
1901 | 11 | Want = WANT64; |
1902 | 308 | else if (TargetTriple.isArch64Bit() && !IsX32170 && !NonExistent(Alt64)168 ) |
1903 | 17 | Want = WANT32; |
1904 | 291 | else if (TargetTriple.isArch64Bit() && !NonExistent(Alt32sparc)153 ) |
1905 | 2 | Want = WANT64; |
1906 | 289 | else { |
1907 | 289 | if (TargetTriple.isArch32Bit()) |
1908 | 138 | Want = NeedsBiarchSuffix ? WANT6416 : WANT32122 ; |
1909 | 151 | else if (IsX32) |
1910 | 2 | Want = NeedsBiarchSuffix ? WANT64 : WANTX320 ; |
1911 | 149 | else |
1912 | 149 | Want = NeedsBiarchSuffix ? WANT320 : WANT64; |
1913 | 289 | } |
1914 | | |
1915 | 321 | if (Want == WANT32) |
1916 | 139 | DefaultBuilder.flag("-m32") |
1917 | 139 | .flag("-m64", /*Disallow=*/true) |
1918 | 139 | .flag("-mx32", /*Disallow=*/true); |
1919 | 182 | else if (Want == WANT64) |
1920 | 182 | DefaultBuilder.flag("-m32", /*Disallow=*/true) |
1921 | 182 | .flag("-m64") |
1922 | 182 | .flag("-mx32", /*Disallow=*/true); |
1923 | 0 | else if (Want == WANTX32) |
1924 | 0 | DefaultBuilder.flag("-m32", /*Disallow=*/true) |
1925 | 0 | .flag("-m64", /*Disallow=*/true) |
1926 | 0 | .flag("-mx32"); |
1927 | 0 | else |
1928 | 0 | return false; |
1929 | | |
1930 | 321 | Multilib Default = DefaultBuilder.makeMultilib(); |
1931 | | |
1932 | 321 | Result.Multilibs.push_back(Default); |
1933 | 321 | Result.Multilibs.push_back(Alt64); |
1934 | 321 | Result.Multilibs.push_back(Alt32); |
1935 | 321 | Result.Multilibs.push_back(Altx32); |
1936 | 321 | Result.Multilibs.push_back(Alt32sparc); |
1937 | | |
1938 | 321 | Result.Multilibs.FilterOut(NonExistent); |
1939 | | |
1940 | 321 | Multilib::flags_list Flags; |
1941 | 321 | addMultilibFlag(TargetTriple.isArch64Bit() && !IsX32181 , "-m64", Flags); |
1942 | 321 | addMultilibFlag(TargetTriple.isArch32Bit(), "-m32", Flags); |
1943 | 321 | addMultilibFlag(TargetTriple.isArch64Bit() && IsX32181 , "-mx32", Flags); |
1944 | | |
1945 | 321 | if (!Result.Multilibs.select(Flags, Result.SelectedMultilibs)) |
1946 | 9 | return false; |
1947 | | |
1948 | 312 | if (Result.SelectedMultilibs.back() == Alt64 || |
1949 | 312 | Result.SelectedMultilibs.back() == Alt32295 || |
1950 | 312 | Result.SelectedMultilibs.back() == Altx32281 || |
1951 | 312 | Result.SelectedMultilibs.back() == Alt32sparc270 ) |
1952 | 44 | Result.BiarchSibling = Default; |
1953 | | |
1954 | 312 | return true; |
1955 | 321 | } |
1956 | | |
1957 | | /// Generic_GCC - A tool chain using the 'gcc' command to perform |
1958 | | /// all subcommands; this relies on gcc translating the majority of |
1959 | | /// command line options. |
1960 | | |
1961 | | /// Less-than for GCCVersion, implementing a Strict Weak Ordering. |
1962 | | bool Generic_GCC::GCCVersion::isOlderThan(int RHSMajor, int RHSMinor, |
1963 | | int RHSPatch, |
1964 | 10.7k | StringRef RHSPatchSuffix) const { |
1965 | 10.7k | if (Major != RHSMajor) |
1966 | 1.76k | return Major < RHSMajor; |
1967 | 8.94k | if (Minor != RHSMinor) { |
1968 | | // Note that versions without a specified minor sort higher than those with |
1969 | | // a minor. |
1970 | 232 | if (RHSMinor == -1) |
1971 | 0 | return true; |
1972 | 232 | if (Minor == -1) |
1973 | 0 | return false; |
1974 | 232 | return Minor < RHSMinor; |
1975 | 232 | } |
1976 | 8.71k | if (Patch != RHSPatch) { |
1977 | | // Note that versions without a specified patch sort higher than those with |
1978 | | // a patch. |
1979 | 2 | if (RHSPatch == -1) |
1980 | 0 | return true; |
1981 | 2 | if (Patch == -1) |
1982 | 0 | return false; |
1983 | | |
1984 | | // Otherwise just sort on the patch itself. |
1985 | 2 | return Patch < RHSPatch; |
1986 | 2 | } |
1987 | 8.71k | if (PatchSuffix != RHSPatchSuffix) { |
1988 | | // Sort empty suffixes higher. |
1989 | 0 | if (RHSPatchSuffix.empty()) |
1990 | 0 | return true; |
1991 | 0 | if (PatchSuffix.empty()) |
1992 | 0 | return false; |
1993 | | |
1994 | | // Provide a lexicographic sort to make this a total ordering. |
1995 | 0 | return PatchSuffix < RHSPatchSuffix; |
1996 | 0 | } |
1997 | | |
1998 | | // The versions are equal. |
1999 | 8.71k | return false; |
2000 | 8.71k | } |
2001 | | |
2002 | | /// Parse a GCCVersion object out of a string of text. |
2003 | | /// |
2004 | | /// This is the primary means of forming GCCVersion objects. |
2005 | | /*static*/ |
2006 | 7.94k | Generic_GCC::GCCVersion Generic_GCC::GCCVersion::Parse(StringRef VersionText) { |
2007 | 7.94k | const GCCVersion BadVersion = {VersionText.str(), -1, -1, -1, "", "", ""}; |
2008 | 7.94k | std::pair<StringRef, StringRef> First = VersionText.split('.'); |
2009 | 7.94k | std::pair<StringRef, StringRef> Second = First.second.split('.'); |
2010 | | |
2011 | 7.94k | GCCVersion GoodVersion = {VersionText.str(), -1, -1, -1, "", "", ""}; |
2012 | 7.94k | if (First.first.getAsInteger(10, GoodVersion.Major) || GoodVersion.Major < 07.92k ) |
2013 | 29 | return BadVersion; |
2014 | 7.92k | GoodVersion.MajorStr = First.first.str(); |
2015 | 7.92k | if (First.second.empty()) |
2016 | 68 | return GoodVersion; |
2017 | 7.85k | StringRef MinorStr = Second.first; |
2018 | 7.85k | if (Second.second.empty()) { |
2019 | 166 | if (size_t EndNumber = MinorStr.find_first_not_of("0123456789")) { |
2020 | 166 | GoodVersion.PatchSuffix = std::string(MinorStr.substr(EndNumber)); |
2021 | 166 | MinorStr = MinorStr.slice(0, EndNumber); |
2022 | 166 | } |
2023 | 166 | } |
2024 | 7.85k | if (MinorStr.getAsInteger(10, GoodVersion.Minor) || GoodVersion.Minor < 0) |
2025 | 0 | return BadVersion; |
2026 | 7.85k | GoodVersion.MinorStr = MinorStr.str(); |
2027 | | |
2028 | | // First look for a number prefix and parse that if present. Otherwise just |
2029 | | // stash the entire patch string in the suffix, and leave the number |
2030 | | // unspecified. This covers versions strings such as: |
2031 | | // 5 (handled above) |
2032 | | // 4.4 |
2033 | | // 4.4-patched |
2034 | | // 4.4.0 |
2035 | | // 4.4.x |
2036 | | // 4.4.2-rc4 |
2037 | | // 4.4.x-patched |
2038 | | // And retains any patch number it finds. |
2039 | 7.85k | StringRef PatchText = Second.second; |
2040 | 7.85k | if (!PatchText.empty()) { |
2041 | 7.68k | if (size_t EndNumber = PatchText.find_first_not_of("0123456789")) { |
2042 | | // Try to parse the number and any suffix. |
2043 | 7.68k | if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) || |
2044 | 7.68k | GoodVersion.Patch < 0) |
2045 | 0 | return BadVersion; |
2046 | 7.68k | GoodVersion.PatchSuffix = std::string(PatchText.substr(EndNumber)); |
2047 | 7.68k | } |
2048 | 7.68k | } |
2049 | | |
2050 | 7.85k | return GoodVersion; |
2051 | 7.85k | } |
2052 | | |
2053 | | static llvm::StringRef getGCCToolchainDir(const ArgList &Args, |
2054 | 5.65k | llvm::StringRef SysRoot) { |
2055 | 5.65k | const Arg *A = Args.getLastArg(clang::driver::options::OPT_gcc_toolchain); |
2056 | 5.65k | if (A) |
2057 | 380 | return A->getValue(); |
2058 | | |
2059 | | // If we have a SysRoot, ignore GCC_INSTALL_PREFIX. |
2060 | | // GCC_INSTALL_PREFIX specifies the gcc installation for the default |
2061 | | // sysroot and is likely not valid with a different sysroot. |
2062 | 5.27k | if (!SysRoot.empty()) |
2063 | 223 | return ""; |
2064 | | |
2065 | 5.05k | return GCC_INSTALL_PREFIX; |
2066 | 5.27k | } |
2067 | | |
2068 | | /// Initialize a GCCInstallationDetector from the driver. |
2069 | | /// |
2070 | | /// This performs all of the autodetection and sets up the various paths. |
2071 | | /// Once constructed, a GCCInstallationDetector is essentially immutable. |
2072 | | /// |
2073 | | /// FIXME: We shouldn't need an explicit TargetTriple parameter here, and |
2074 | | /// should instead pull the target out of the driver. This is currently |
2075 | | /// necessary because the driver doesn't store the final version of the target |
2076 | | /// triple. |
2077 | | void Generic_GCC::GCCInstallationDetector::init( |
2078 | 5.65k | const llvm::Triple &TargetTriple, const ArgList &Args) { |
2079 | 5.65k | llvm::Triple BiarchVariantTriple = TargetTriple.isArch32Bit() |
2080 | 5.65k | ? TargetTriple.get64BitArchVariant()1.91k |
2081 | 5.65k | : TargetTriple.get32BitArchVariant()3.74k ; |
2082 | | // The library directories which may contain GCC installations. |
2083 | 5.65k | SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs; |
2084 | | // The compatible GCC triples for this particular architecture. |
2085 | 5.65k | SmallVector<StringRef, 16> CandidateTripleAliases; |
2086 | 5.65k | SmallVector<StringRef, 16> CandidateBiarchTripleAliases; |
2087 | 5.65k | CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs, |
2088 | 5.65k | CandidateTripleAliases, CandidateBiarchLibDirs, |
2089 | 5.65k | CandidateBiarchTripleAliases); |
2090 | | |
2091 | 5.65k | TripleNoVendor = TargetTriple.getArchName().str() + "-" + |
2092 | 5.65k | TargetTriple.getOSAndEnvironmentName().str(); |
2093 | 5.65k | StringRef TripleNoVendorRef(TripleNoVendor); |
2094 | | |
2095 | | // If --gcc-install-dir= is specified, skip filesystem detection. |
2096 | 5.65k | if (const Arg *A = |
2097 | 5.65k | Args.getLastArg(clang::driver::options::OPT_gcc_install_dir_EQ); |
2098 | 5.65k | A && A->getValue()[0]4 ) { |
2099 | 4 | StringRef InstallDir = A->getValue(); |
2100 | 4 | if (!ScanGCCForMultilibs(TargetTriple, Args, InstallDir, false)) { |
2101 | 1 | D.Diag(diag::err_drv_invalid_gcc_install_dir) << InstallDir; |
2102 | 3 | } else { |
2103 | 3 | (void)InstallDir.consume_back("/"); |
2104 | 3 | StringRef VersionText = llvm::sys::path::filename(InstallDir); |
2105 | 3 | StringRef TripleText = |
2106 | 3 | llvm::sys::path::filename(llvm::sys::path::parent_path(InstallDir)); |
2107 | | |
2108 | 3 | Version = GCCVersion::Parse(VersionText); |
2109 | 3 | GCCTriple.setTriple(TripleText); |
2110 | 3 | GCCInstallPath = std::string(InstallDir); |
2111 | 3 | GCCParentLibPath = GCCInstallPath + "/../../.."; |
2112 | 3 | IsValid = true; |
2113 | 3 | } |
2114 | 4 | return; |
2115 | 4 | } |
2116 | | |
2117 | | // Compute the set of prefixes for our search. |
2118 | 5.65k | SmallVector<std::string, 8> Prefixes; |
2119 | 5.65k | StringRef GCCToolchainDir = getGCCToolchainDir(Args, D.SysRoot); |
2120 | 5.65k | if (GCCToolchainDir != "") { |
2121 | 111 | if (GCCToolchainDir.back() == '/') |
2122 | 0 | GCCToolchainDir = GCCToolchainDir.drop_back(); // remove the / |
2123 | | |
2124 | 111 | Prefixes.push_back(std::string(GCCToolchainDir)); |
2125 | 5.54k | } else { |
2126 | | // If we have a SysRoot, try that first. |
2127 | 5.54k | if (!D.SysRoot.empty()) { |
2128 | 471 | Prefixes.push_back(D.SysRoot); |
2129 | 471 | AddDefaultGCCPrefixes(TargetTriple, Prefixes, D.SysRoot); |
2130 | 471 | } |
2131 | | |
2132 | | // Then look for gcc installed alongside clang. |
2133 | 5.54k | Prefixes.push_back(D.InstalledDir + "/.."); |
2134 | | |
2135 | | // Next, look for prefix(es) that correspond to distribution-supplied gcc |
2136 | | // installations. |
2137 | 5.54k | if (D.SysRoot.empty()) { |
2138 | | // Typically /usr. |
2139 | 5.07k | AddDefaultGCCPrefixes(TargetTriple, Prefixes, D.SysRoot); |
2140 | 5.07k | } |
2141 | | |
2142 | | // Try to respect gcc-config on Gentoo if --gcc-toolchain is not provided. |
2143 | | // This avoids accidentally enforcing the system GCC version when using a |
2144 | | // custom toolchain. |
2145 | 5.54k | SmallVector<StringRef, 16> GentooTestTriples; |
2146 | | // Try to match an exact triple as target triple first. |
2147 | | // e.g. crossdev -S x86_64-gentoo-linux-gnu will install gcc libs for |
2148 | | // x86_64-gentoo-linux-gnu. But "clang -target x86_64-gentoo-linux-gnu" |
2149 | | // may pick the libraries for x86_64-pc-linux-gnu even when exact matching |
2150 | | // triple x86_64-gentoo-linux-gnu is present. |
2151 | 5.54k | GentooTestTriples.push_back(TargetTriple.str()); |
2152 | 5.54k | GentooTestTriples.append(CandidateTripleAliases.begin(), |
2153 | 5.54k | CandidateTripleAliases.end()); |
2154 | 5.54k | if (ScanGentooConfigs(TargetTriple, Args, GentooTestTriples, |
2155 | 5.54k | CandidateBiarchTripleAliases)) |
2156 | 9 | return; |
2157 | 5.54k | } |
2158 | | |
2159 | | // Loop over the various components which exist and select the best GCC |
2160 | | // installation available. GCC installs are ranked by version number. |
2161 | 5.64k | const GCCVersion VersionZero = GCCVersion::Parse("0.0.0"); |
2162 | 5.64k | Version = VersionZero; |
2163 | 11.2k | for (const std::string &Prefix : Prefixes) { |
2164 | 11.2k | auto &VFS = D.getVFS(); |
2165 | 11.2k | if (!VFS.exists(Prefix)) |
2166 | 2.26k | continue; |
2167 | 15.4k | for (StringRef Suffix : CandidateLibDirs)9.00k { |
2168 | 15.4k | const std::string LibDir = concat(Prefix, Suffix); |
2169 | 15.4k | if (!VFS.exists(LibDir)) |
2170 | 7.04k | continue; |
2171 | | // Maybe filter out <libdir>/gcc and <libdir>/gcc-cross. |
2172 | 8.35k | bool GCCDirExists = VFS.exists(LibDir + "/gcc"); |
2173 | 8.35k | bool GCCCrossDirExists = VFS.exists(LibDir + "/gcc-cross"); |
2174 | | // Try to match the exact target triple first. |
2175 | 8.35k | ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, TargetTriple.str(), |
2176 | 8.35k | false, GCCDirExists, GCCCrossDirExists); |
2177 | | // If vendor is unknown, let's try triple without vendor. |
2178 | 8.35k | if (TargetTriple.getVendor() == llvm::Triple::UnknownVendor) |
2179 | 7.99k | ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, TripleNoVendorRef, |
2180 | 7.99k | false, GCCDirExists, GCCCrossDirExists); |
2181 | 8.35k | for (StringRef Candidate : CandidateTripleAliases) |
2182 | 52.0k | ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, false, |
2183 | 52.0k | GCCDirExists, GCCCrossDirExists); |
2184 | 8.35k | } |
2185 | 21.0k | for (StringRef Suffix : CandidateBiarchLibDirs) { |
2186 | 21.0k | const std::string LibDir = Prefix + Suffix.str(); |
2187 | 21.0k | if (!VFS.exists(LibDir)) |
2188 | 11.0k | continue; |
2189 | 9.98k | bool GCCDirExists = VFS.exists(LibDir + "/gcc"); |
2190 | 9.98k | bool GCCCrossDirExists = VFS.exists(LibDir + "/gcc-cross"); |
2191 | 9.98k | for (StringRef Candidate : CandidateBiarchTripleAliases) |
2192 | 106k | ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, true, |
2193 | 106k | GCCDirExists, GCCCrossDirExists); |
2194 | 9.98k | } |
2195 | | |
2196 | | // Skip other prefixes once a GCC installation is found. |
2197 | 9.00k | if (Version > VersionZero) |
2198 | 438 | break; |
2199 | 9.00k | } |
2200 | 5.64k | } |
2201 | | |
2202 | 72 | void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const { |
2203 | 72 | for (const auto &InstallPath : CandidateGCCInstallPaths) |
2204 | 21 | OS << "Found candidate GCC installation: " << InstallPath << "\n"; |
2205 | | |
2206 | 72 | if (!GCCInstallPath.empty()) |
2207 | 19 | OS << "Selected GCC installation: " << GCCInstallPath << "\n"; |
2208 | | |
2209 | 72 | for (const auto &Multilib : Multilibs) |
2210 | 30 | OS << "Candidate multilib: " << Multilib << "\n"; |
2211 | | |
2212 | 72 | if (Multilibs.size() != 0 || !SelectedMultilib.isDefault()53 ) |
2213 | 19 | OS << "Selected multilib: " << SelectedMultilib << "\n"; |
2214 | 72 | } |
2215 | | |
2216 | 0 | bool Generic_GCC::GCCInstallationDetector::getBiarchSibling(Multilib &M) const { |
2217 | 0 | if (BiarchSibling) { |
2218 | 0 | M = *BiarchSibling; |
2219 | 0 | return true; |
2220 | 0 | } |
2221 | 0 | return false; |
2222 | 0 | } |
2223 | | |
2224 | | void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( |
2225 | | const llvm::Triple &TargetTriple, SmallVectorImpl<std::string> &Prefixes, |
2226 | 5.54k | StringRef SysRoot) { |
2227 | | |
2228 | 5.54k | if (TargetTriple.isOSHaiku()) { |
2229 | 12 | Prefixes.push_back(concat(SysRoot, "/boot/system/develop/tools")); |
2230 | 12 | return; |
2231 | 12 | } |
2232 | | |
2233 | 5.53k | if (TargetTriple.isOSSolaris()) { |
2234 | | // Solaris is a special case. |
2235 | | // The GCC installation is under |
2236 | | // /usr/gcc/<major>.<minor>/lib/gcc/<triple>/<major>.<minor>.<patch>/ |
2237 | | // so we need to find those /usr/gcc/*/lib/gcc libdirs and go with |
2238 | | // /usr/gcc/<version> as a prefix. |
2239 | | |
2240 | 84 | SmallVector<std::pair<GCCVersion, std::string>, 8> SolarisPrefixes; |
2241 | 84 | std::string PrefixDir = concat(SysRoot, "/usr/gcc"); |
2242 | 84 | std::error_code EC; |
2243 | 84 | for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(PrefixDir, EC), |
2244 | 84 | LE; |
2245 | 160 | !EC && LI != LE142 ; LI = LI.increment(EC)76 ) { |
2246 | 76 | StringRef VersionText = llvm::sys::path::filename(LI->path()); |
2247 | 76 | GCCVersion CandidateVersion = GCCVersion::Parse(VersionText); |
2248 | | |
2249 | | // Filter out obviously bad entries. |
2250 | 76 | if (CandidateVersion.Major == -1 || CandidateVersion.isOlderThan(4, 1, 1)) |
2251 | 0 | continue; |
2252 | | |
2253 | 76 | std::string CandidatePrefix = PrefixDir + "/" + VersionText.str(); |
2254 | 76 | std::string CandidateLibPath = CandidatePrefix + "/lib/gcc"; |
2255 | 76 | if (!D.getVFS().exists(CandidateLibPath)) |
2256 | 0 | continue; |
2257 | | |
2258 | 76 | SolarisPrefixes.emplace_back( |
2259 | 76 | std::make_pair(CandidateVersion, CandidatePrefix)); |
2260 | 76 | } |
2261 | | // Sort in reverse order so GCCInstallationDetector::init picks the latest. |
2262 | 84 | std::sort(SolarisPrefixes.rbegin(), SolarisPrefixes.rend()); |
2263 | 84 | for (auto p : SolarisPrefixes) |
2264 | 76 | Prefixes.emplace_back(p.second); |
2265 | 84 | return; |
2266 | 84 | } |
2267 | | |
2268 | | // For Linux, if --sysroot is not specified, look for RHEL/CentOS devtoolsets |
2269 | | // and gcc-toolsets. |
2270 | 5.44k | if (SysRoot.empty() && TargetTriple.getOS() == llvm::Triple::Linux5.04k && |
2271 | 5.44k | D.getVFS().exists("/opt/rh")4.82k ) { |
2272 | | // TODO: We may want to remove this, since the functionality |
2273 | | // can be achieved using config files. |
2274 | 0 | Prefixes.push_back("/opt/rh/gcc-toolset-12/root/usr"); |
2275 | 0 | Prefixes.push_back("/opt/rh/gcc-toolset-11/root/usr"); |
2276 | 0 | Prefixes.push_back("/opt/rh/gcc-toolset-10/root/usr"); |
2277 | 0 | Prefixes.push_back("/opt/rh/devtoolset-12/root/usr"); |
2278 | 0 | Prefixes.push_back("/opt/rh/devtoolset-11/root/usr"); |
2279 | 0 | Prefixes.push_back("/opt/rh/devtoolset-10/root/usr"); |
2280 | 0 | Prefixes.push_back("/opt/rh/devtoolset-9/root/usr"); |
2281 | 0 | Prefixes.push_back("/opt/rh/devtoolset-8/root/usr"); |
2282 | 0 | Prefixes.push_back("/opt/rh/devtoolset-7/root/usr"); |
2283 | 0 | Prefixes.push_back("/opt/rh/devtoolset-6/root/usr"); |
2284 | 0 | Prefixes.push_back("/opt/rh/devtoolset-4/root/usr"); |
2285 | 0 | Prefixes.push_back("/opt/rh/devtoolset-3/root/usr"); |
2286 | 0 | Prefixes.push_back("/opt/rh/devtoolset-2/root/usr"); |
2287 | 0 | } |
2288 | | |
2289 | | // Fall back to /usr which is used by most non-Solaris systems. |
2290 | 5.44k | Prefixes.push_back(concat(SysRoot, "/usr")); |
2291 | 5.44k | } |
2292 | | |
2293 | | /*static*/ void Generic_GCC::GCCInstallationDetector::CollectLibDirsAndTriples( |
2294 | | const llvm::Triple &TargetTriple, const llvm::Triple &BiarchTriple, |
2295 | | SmallVectorImpl<StringRef> &LibDirs, |
2296 | | SmallVectorImpl<StringRef> &TripleAliases, |
2297 | | SmallVectorImpl<StringRef> &BiarchLibDirs, |
2298 | 5.65k | SmallVectorImpl<StringRef> &BiarchTripleAliases) { |
2299 | | // Declare a bunch of static data sets that we'll select between below. These |
2300 | | // are specifically designed to always refer to string literals to avoid any |
2301 | | // lifetime or initialization issues. |
2302 | | // |
2303 | | // The *Triples variables hard code some triples so that, for example, |
2304 | | // --target=aarch64 (incomplete triple) can detect lib/aarch64-linux-gnu. |
2305 | | // They are not needed when the user has correct LLVM_DEFAULT_TARGET_TRIPLE |
2306 | | // and always uses the full --target (e.g. --target=aarch64-linux-gnu). The |
2307 | | // lists should shrink over time. Please don't add more elements to *Triples. |
2308 | 5.65k | static const char *const AArch64LibDirs[] = {"/lib64", "/lib"}; |
2309 | 5.65k | static const char *const AArch64Triples[] = { |
2310 | 5.65k | "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-redhat-linux", |
2311 | 5.65k | "aarch64-suse-linux"}; |
2312 | 5.65k | static const char *const AArch64beLibDirs[] = {"/lib"}; |
2313 | 5.65k | static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu", |
2314 | 5.65k | "aarch64_be-linux-gnu"}; |
2315 | | |
2316 | 5.65k | static const char *const ARMLibDirs[] = {"/lib"}; |
2317 | 5.65k | static const char *const ARMTriples[] = {"arm-linux-gnueabi"}; |
2318 | 5.65k | static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf", |
2319 | 5.65k | "armv7hl-redhat-linux-gnueabi", |
2320 | 5.65k | "armv6hl-suse-linux-gnueabi", |
2321 | 5.65k | "armv7hl-suse-linux-gnueabi"}; |
2322 | 5.65k | static const char *const ARMebLibDirs[] = {"/lib"}; |
2323 | 5.65k | static const char *const ARMebTriples[] = {"armeb-linux-gnueabi"}; |
2324 | 5.65k | static const char *const ARMebHFTriples[] = { |
2325 | 5.65k | "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"}; |
2326 | | |
2327 | 5.65k | static const char *const AVRLibDirs[] = {"/lib"}; |
2328 | 5.65k | static const char *const AVRTriples[] = {"avr"}; |
2329 | | |
2330 | 5.65k | static const char *const CSKYLibDirs[] = {"/lib"}; |
2331 | 5.65k | static const char *const CSKYTriples[] = { |
2332 | 5.65k | "csky-linux-gnuabiv2", "csky-linux-uclibcabiv2", "csky-elf-noneabiv2"}; |
2333 | | |
2334 | 5.65k | static const char *const X86_64LibDirs[] = {"/lib64", "/lib"}; |
2335 | 5.65k | static const char *const X86_64Triples[] = { |
2336 | 5.65k | "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", |
2337 | 5.65k | "x86_64-pc-linux-gnu", "x86_64-redhat-linux6E", |
2338 | 5.65k | "x86_64-redhat-linux", "x86_64-suse-linux", |
2339 | 5.65k | "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", |
2340 | 5.65k | "x86_64-slackware-linux", "x86_64-unknown-linux", |
2341 | 5.65k | "x86_64-amazon-linux"}; |
2342 | 5.65k | static const char *const X32Triples[] = {"x86_64-linux-gnux32", |
2343 | 5.65k | "x86_64-pc-linux-gnux32"}; |
2344 | 5.65k | static const char *const X32LibDirs[] = {"/libx32", "/lib"}; |
2345 | 5.65k | static const char *const X86LibDirs[] = {"/lib32", "/lib"}; |
2346 | 5.65k | static const char *const X86Triples[] = { |
2347 | 5.65k | "i586-linux-gnu", "i686-linux-gnu", "i686-pc-linux-gnu", |
2348 | 5.65k | "i386-redhat-linux6E", "i686-redhat-linux", "i386-redhat-linux", |
2349 | 5.65k | "i586-suse-linux", "i686-montavista-linux", "i686-gnu", |
2350 | 5.65k | }; |
2351 | | |
2352 | 5.65k | static const char *const LoongArch64LibDirs[] = {"/lib64", "/lib"}; |
2353 | 5.65k | static const char *const LoongArch64Triples[] = { |
2354 | 5.65k | "loongarch64-linux-gnu", "loongarch64-unknown-linux-gnu"}; |
2355 | | |
2356 | 5.65k | static const char *const M68kLibDirs[] = {"/lib"}; |
2357 | 5.65k | static const char *const M68kTriples[] = { |
2358 | 5.65k | "m68k-linux-gnu", "m68k-unknown-linux-gnu", "m68k-suse-linux"}; |
2359 | | |
2360 | 5.65k | static const char *const MIPSLibDirs[] = {"/libo32", "/lib"}; |
2361 | 5.65k | static const char *const MIPSTriples[] = { |
2362 | 5.65k | "mips-linux-gnu", "mips-mti-linux", "mips-mti-linux-gnu", |
2363 | 5.65k | "mips-img-linux-gnu", "mipsisa32r6-linux-gnu"}; |
2364 | 5.65k | static const char *const MIPSELLibDirs[] = {"/libo32", "/lib"}; |
2365 | 5.65k | static const char *const MIPSELTriples[] = { |
2366 | 5.65k | "mipsel-linux-gnu", "mips-img-linux-gnu", "mipsisa32r6el-linux-gnu"}; |
2367 | | |
2368 | 5.65k | static const char *const MIPS64LibDirs[] = {"/lib64", "/lib"}; |
2369 | 5.65k | static const char *const MIPS64Triples[] = { |
2370 | 5.65k | "mips64-linux-gnu", "mips-mti-linux-gnu", |
2371 | 5.65k | "mips-img-linux-gnu", "mips64-linux-gnuabi64", |
2372 | 5.65k | "mipsisa64r6-linux-gnu", "mipsisa64r6-linux-gnuabi64"}; |
2373 | 5.65k | static const char *const MIPS64ELLibDirs[] = {"/lib64", "/lib"}; |
2374 | 5.65k | static const char *const MIPS64ELTriples[] = { |
2375 | 5.65k | "mips64el-linux-gnu", "mips-mti-linux-gnu", |
2376 | 5.65k | "mips-img-linux-gnu", "mips64el-linux-gnuabi64", |
2377 | 5.65k | "mipsisa64r6el-linux-gnu", "mipsisa64r6el-linux-gnuabi64"}; |
2378 | | |
2379 | 5.65k | static const char *const MIPSN32LibDirs[] = {"/lib32"}; |
2380 | 5.65k | static const char *const MIPSN32Triples[] = {"mips64-linux-gnuabin32", |
2381 | 5.65k | "mipsisa64r6-linux-gnuabin32"}; |
2382 | 5.65k | static const char *const MIPSN32ELLibDirs[] = {"/lib32"}; |
2383 | 5.65k | static const char *const MIPSN32ELTriples[] = { |
2384 | 5.65k | "mips64el-linux-gnuabin32", "mipsisa64r6el-linux-gnuabin32"}; |
2385 | | |
2386 | 5.65k | static const char *const MSP430LibDirs[] = {"/lib"}; |
2387 | 5.65k | static const char *const MSP430Triples[] = {"msp430-elf"}; |
2388 | | |
2389 | 5.65k | static const char *const PPCLibDirs[] = {"/lib32", "/lib"}; |
2390 | 5.65k | static const char *const PPCTriples[] = { |
2391 | 5.65k | "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe", |
2392 | | // On 32-bit PowerPC systems running SUSE Linux, gcc is configured as a |
2393 | | // 64-bit compiler which defaults to "-m32", hence "powerpc64-suse-linux". |
2394 | 5.65k | "powerpc64-suse-linux", "powerpc-montavista-linuxspe"}; |
2395 | 5.65k | static const char *const PPCLELibDirs[] = {"/lib32", "/lib"}; |
2396 | 5.65k | static const char *const PPCLETriples[] = {"powerpcle-linux-gnu", |
2397 | 5.65k | "powerpcle-unknown-linux-gnu", |
2398 | 5.65k | "powerpcle-linux-musl"}; |
2399 | | |
2400 | 5.65k | static const char *const PPC64LibDirs[] = {"/lib64", "/lib"}; |
2401 | 5.65k | static const char *const PPC64Triples[] = { |
2402 | 5.65k | "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu", |
2403 | 5.65k | "powerpc64-suse-linux", "ppc64-redhat-linux"}; |
2404 | 5.65k | static const char *const PPC64LELibDirs[] = {"/lib64", "/lib"}; |
2405 | 5.65k | static const char *const PPC64LETriples[] = { |
2406 | 5.65k | "powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu", |
2407 | 5.65k | "powerpc64le-none-linux-gnu", "powerpc64le-suse-linux", |
2408 | 5.65k | "ppc64le-redhat-linux"}; |
2409 | | |
2410 | 5.65k | static const char *const RISCV32LibDirs[] = {"/lib32", "/lib"}; |
2411 | 5.65k | static const char *const RISCV32Triples[] = {"riscv32-unknown-linux-gnu", |
2412 | 5.65k | "riscv32-linux-gnu", |
2413 | 5.65k | "riscv32-unknown-elf"}; |
2414 | 5.65k | static const char *const RISCV64LibDirs[] = {"/lib64", "/lib"}; |
2415 | 5.65k | static const char *const RISCV64Triples[] = {"riscv64-unknown-linux-gnu", |
2416 | 5.65k | "riscv64-linux-gnu", |
2417 | 5.65k | "riscv64-unknown-elf"}; |
2418 | | |
2419 | 5.65k | static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"}; |
2420 | 5.65k | static const char *const SPARCv8Triples[] = {"sparc-linux-gnu", |
2421 | 5.65k | "sparcv8-linux-gnu"}; |
2422 | 5.65k | static const char *const SPARCv9LibDirs[] = {"/lib64", "/lib"}; |
2423 | 5.65k | static const char *const SPARCv9Triples[] = {"sparc64-linux-gnu", |
2424 | 5.65k | "sparcv9-linux-gnu"}; |
2425 | | |
2426 | 5.65k | static const char *const SystemZLibDirs[] = {"/lib64", "/lib"}; |
2427 | 5.65k | static const char *const SystemZTriples[] = { |
2428 | 5.65k | "s390x-linux-gnu", "s390x-unknown-linux-gnu", "s390x-ibm-linux-gnu", |
2429 | 5.65k | "s390x-suse-linux", "s390x-redhat-linux"}; |
2430 | | |
2431 | | |
2432 | 5.65k | using std::begin; |
2433 | 5.65k | using std::end; |
2434 | | |
2435 | 5.65k | if (TargetTriple.isOSSolaris()) { |
2436 | 90 | static const char *const SolarisLibDirs[] = {"/lib"}; |
2437 | 90 | static const char *const SolarisSparcV8Triples[] = { |
2438 | 90 | "sparc-sun-solaris2.11"}; |
2439 | 90 | static const char *const SolarisSparcV9Triples[] = { |
2440 | 90 | "sparcv9-sun-solaris2.11"}; |
2441 | 90 | static const char *const SolarisX86Triples[] = {"i386-pc-solaris2.11"}; |
2442 | 90 | static const char *const SolarisX86_64Triples[] = {"x86_64-pc-solaris2.11"}; |
2443 | 90 | LibDirs.append(begin(SolarisLibDirs), end(SolarisLibDirs)); |
2444 | 90 | BiarchLibDirs.append(begin(SolarisLibDirs), end(SolarisLibDirs)); |
2445 | 90 | switch (TargetTriple.getArch()) { |
2446 | 20 | case llvm::Triple::x86: |
2447 | 20 | TripleAliases.append(begin(SolarisX86Triples), end(SolarisX86Triples)); |
2448 | 20 | BiarchTripleAliases.append(begin(SolarisX86_64Triples), |
2449 | 20 | end(SolarisX86_64Triples)); |
2450 | 20 | break; |
2451 | 10 | case llvm::Triple::x86_64: |
2452 | 10 | TripleAliases.append(begin(SolarisX86_64Triples), |
2453 | 10 | end(SolarisX86_64Triples)); |
2454 | 10 | BiarchTripleAliases.append(begin(SolarisX86Triples), |
2455 | 10 | end(SolarisX86Triples)); |
2456 | 10 | break; |
2457 | 50 | case llvm::Triple::sparc: |
2458 | 50 | TripleAliases.append(begin(SolarisSparcV8Triples), |
2459 | 50 | end(SolarisSparcV8Triples)); |
2460 | 50 | BiarchTripleAliases.append(begin(SolarisSparcV9Triples), |
2461 | 50 | end(SolarisSparcV9Triples)); |
2462 | 50 | break; |
2463 | 10 | case llvm::Triple::sparcv9: |
2464 | 10 | TripleAliases.append(begin(SolarisSparcV9Triples), |
2465 | 10 | end(SolarisSparcV9Triples)); |
2466 | 10 | BiarchTripleAliases.append(begin(SolarisSparcV8Triples), |
2467 | 10 | end(SolarisSparcV8Triples)); |
2468 | 10 | break; |
2469 | 0 | default: |
2470 | 0 | break; |
2471 | 90 | } |
2472 | 90 | return; |
2473 | 90 | } |
2474 | | |
2475 | | // Android targets should not use GNU/Linux tools or libraries. |
2476 | 5.56k | if (TargetTriple.isAndroid()) { |
2477 | 223 | static const char *const AArch64AndroidTriples[] = { |
2478 | 223 | "aarch64-linux-android"}; |
2479 | 223 | static const char *const ARMAndroidTriples[] = {"arm-linux-androideabi"}; |
2480 | 223 | static const char *const X86AndroidTriples[] = {"i686-linux-android"}; |
2481 | 223 | static const char *const X86_64AndroidTriples[] = {"x86_64-linux-android"}; |
2482 | | |
2483 | 223 | switch (TargetTriple.getArch()) { |
2484 | 85 | case llvm::Triple::aarch64: |
2485 | 85 | LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs)); |
2486 | 85 | TripleAliases.append(begin(AArch64AndroidTriples), |
2487 | 85 | end(AArch64AndroidTriples)); |
2488 | 85 | break; |
2489 | 88 | case llvm::Triple::arm: |
2490 | 90 | case llvm::Triple::thumb: |
2491 | 90 | LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs)); |
2492 | 90 | TripleAliases.append(begin(ARMAndroidTriples), end(ARMAndroidTriples)); |
2493 | 90 | break; |
2494 | 19 | case llvm::Triple::x86_64: |
2495 | 19 | LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); |
2496 | 19 | TripleAliases.append(begin(X86_64AndroidTriples), |
2497 | 19 | end(X86_64AndroidTriples)); |
2498 | 19 | BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs)); |
2499 | 19 | BiarchTripleAliases.append(begin(X86AndroidTriples), |
2500 | 19 | end(X86AndroidTriples)); |
2501 | 19 | break; |
2502 | 17 | case llvm::Triple::x86: |
2503 | 17 | LibDirs.append(begin(X86LibDirs), end(X86LibDirs)); |
2504 | 17 | TripleAliases.append(begin(X86AndroidTriples), end(X86AndroidTriples)); |
2505 | 17 | BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); |
2506 | 17 | BiarchTripleAliases.append(begin(X86_64AndroidTriples), |
2507 | 17 | end(X86_64AndroidTriples)); |
2508 | 17 | break; |
2509 | 12 | default: |
2510 | 12 | break; |
2511 | 223 | } |
2512 | | |
2513 | 223 | return; |
2514 | 223 | } |
2515 | | |
2516 | 5.34k | switch (TargetTriple.getArch()) { |
2517 | 387 | case llvm::Triple::aarch64: |
2518 | 387 | LibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs)); |
2519 | 387 | TripleAliases.append(begin(AArch64Triples), end(AArch64Triples)); |
2520 | 387 | BiarchLibDirs.append(begin(AArch64LibDirs), end(AArch64LibDirs)); |
2521 | 387 | BiarchTripleAliases.append(begin(AArch64Triples), end(AArch64Triples)); |
2522 | 387 | break; |
2523 | 8 | case llvm::Triple::aarch64_be: |
2524 | 8 | LibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs)); |
2525 | 8 | TripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples)); |
2526 | 8 | BiarchLibDirs.append(begin(AArch64beLibDirs), end(AArch64beLibDirs)); |
2527 | 8 | BiarchTripleAliases.append(begin(AArch64beTriples), end(AArch64beTriples)); |
2528 | 8 | break; |
2529 | 535 | case llvm::Triple::arm: |
2530 | 549 | case llvm::Triple::thumb: |
2531 | 549 | LibDirs.append(begin(ARMLibDirs), end(ARMLibDirs)); |
2532 | 549 | if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) { |
2533 | 48 | TripleAliases.append(begin(ARMHFTriples), end(ARMHFTriples)); |
2534 | 501 | } else { |
2535 | 501 | TripleAliases.append(begin(ARMTriples), end(ARMTriples)); |
2536 | 501 | } |
2537 | 549 | break; |
2538 | 45 | case llvm::Triple::armeb: |
2539 | 56 | case llvm::Triple::thumbeb: |
2540 | 56 | LibDirs.append(begin(ARMebLibDirs), end(ARMebLibDirs)); |
2541 | 56 | if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) { |
2542 | 3 | TripleAliases.append(begin(ARMebHFTriples), end(ARMebHFTriples)); |
2543 | 53 | } else { |
2544 | 53 | TripleAliases.append(begin(ARMebTriples), end(ARMebTriples)); |
2545 | 53 | } |
2546 | 56 | break; |
2547 | 66 | case llvm::Triple::avr: |
2548 | 66 | LibDirs.append(begin(AVRLibDirs), end(AVRLibDirs)); |
2549 | 66 | TripleAliases.append(begin(AVRTriples), end(AVRTriples)); |
2550 | 66 | break; |
2551 | 36 | case llvm::Triple::csky: |
2552 | 36 | LibDirs.append(begin(CSKYLibDirs), end(CSKYLibDirs)); |
2553 | 36 | TripleAliases.append(begin(CSKYTriples), end(CSKYTriples)); |
2554 | 36 | break; |
2555 | 2.53k | case llvm::Triple::x86_64: |
2556 | 2.53k | if (TargetTriple.isX32()) { |
2557 | 15 | LibDirs.append(begin(X32LibDirs), end(X32LibDirs)); |
2558 | 15 | TripleAliases.append(begin(X32Triples), end(X32Triples)); |
2559 | 15 | BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); |
2560 | 15 | BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); |
2561 | 2.52k | } else { |
2562 | 2.52k | LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); |
2563 | 2.52k | TripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); |
2564 | 2.52k | BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs)); |
2565 | 2.52k | BiarchTripleAliases.append(begin(X32Triples), end(X32Triples)); |
2566 | 2.52k | } |
2567 | 2.53k | BiarchLibDirs.append(begin(X86LibDirs), end(X86LibDirs)); |
2568 | 2.53k | BiarchTripleAliases.append(begin(X86Triples), end(X86Triples)); |
2569 | 2.53k | break; |
2570 | 428 | case llvm::Triple::x86: |
2571 | 428 | LibDirs.append(begin(X86LibDirs), end(X86LibDirs)); |
2572 | | // MCU toolchain is 32 bit only and its triple alias is TargetTriple |
2573 | | // itself, which will be appended below. |
2574 | 428 | if (!TargetTriple.isOSIAMCU()) { |
2575 | 419 | TripleAliases.append(begin(X86Triples), end(X86Triples)); |
2576 | 419 | BiarchLibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); |
2577 | 419 | BiarchTripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); |
2578 | 419 | BiarchLibDirs.append(begin(X32LibDirs), end(X32LibDirs)); |
2579 | 419 | BiarchTripleAliases.append(begin(X32Triples), end(X32Triples)); |
2580 | 419 | } |
2581 | 428 | break; |
2582 | | // TODO: Handle loongarch32. |
2583 | 19 | case llvm::Triple::loongarch64: |
2584 | 19 | LibDirs.append(begin(LoongArch64LibDirs), end(LoongArch64LibDirs)); |
2585 | 19 | TripleAliases.append(begin(LoongArch64Triples), end(LoongArch64Triples)); |
2586 | 19 | break; |
2587 | 47 | case llvm::Triple::m68k: |
2588 | 47 | LibDirs.append(begin(M68kLibDirs), end(M68kLibDirs)); |
2589 | 47 | TripleAliases.append(begin(M68kTriples), end(M68kTriples)); |
2590 | 47 | break; |
2591 | 250 | case llvm::Triple::mips: |
2592 | 250 | LibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs)); |
2593 | 250 | TripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); |
2594 | 250 | BiarchLibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs)); |
2595 | 250 | BiarchTripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples)); |
2596 | 250 | BiarchLibDirs.append(begin(MIPSN32LibDirs), end(MIPSN32LibDirs)); |
2597 | 250 | BiarchTripleAliases.append(begin(MIPSN32Triples), end(MIPSN32Triples)); |
2598 | 250 | break; |
2599 | 31 | case llvm::Triple::mipsel: |
2600 | 31 | LibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs)); |
2601 | 31 | TripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples)); |
2602 | 31 | TripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); |
2603 | 31 | BiarchLibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs)); |
2604 | 31 | BiarchTripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples)); |
2605 | 31 | BiarchLibDirs.append(begin(MIPSN32ELLibDirs), end(MIPSN32ELLibDirs)); |
2606 | 31 | BiarchTripleAliases.append(begin(MIPSN32ELTriples), end(MIPSN32ELTriples)); |
2607 | 31 | break; |
2608 | 58 | case llvm::Triple::mips64: |
2609 | 58 | LibDirs.append(begin(MIPS64LibDirs), end(MIPS64LibDirs)); |
2610 | 58 | TripleAliases.append(begin(MIPS64Triples), end(MIPS64Triples)); |
2611 | 58 | BiarchLibDirs.append(begin(MIPSLibDirs), end(MIPSLibDirs)); |
2612 | 58 | BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); |
2613 | 58 | BiarchLibDirs.append(begin(MIPSN32LibDirs), end(MIPSN32LibDirs)); |
2614 | 58 | BiarchTripleAliases.append(begin(MIPSN32Triples), end(MIPSN32Triples)); |
2615 | 58 | break; |
2616 | 35 | case llvm::Triple::mips64el: |
2617 | 35 | LibDirs.append(begin(MIPS64ELLibDirs), end(MIPS64ELLibDirs)); |
2618 | 35 | TripleAliases.append(begin(MIPS64ELTriples), end(MIPS64ELTriples)); |
2619 | 35 | BiarchLibDirs.append(begin(MIPSELLibDirs), end(MIPSELLibDirs)); |
2620 | 35 | BiarchTripleAliases.append(begin(MIPSELTriples), end(MIPSELTriples)); |
2621 | 35 | BiarchLibDirs.append(begin(MIPSN32ELLibDirs), end(MIPSN32ELLibDirs)); |
2622 | 35 | BiarchTripleAliases.append(begin(MIPSN32ELTriples), end(MIPSN32ELTriples)); |
2623 | 35 | BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); |
2624 | 35 | break; |
2625 | 49 | case llvm::Triple::msp430: |
2626 | 49 | LibDirs.append(begin(MSP430LibDirs), end(MSP430LibDirs)); |
2627 | 49 | TripleAliases.append(begin(MSP430Triples), end(MSP430Triples)); |
2628 | 49 | break; |
2629 | 33 | case llvm::Triple::ppc: |
2630 | 33 | LibDirs.append(begin(PPCLibDirs), end(PPCLibDirs)); |
2631 | 33 | TripleAliases.append(begin(PPCTriples), end(PPCTriples)); |
2632 | 33 | BiarchLibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs)); |
2633 | 33 | BiarchTripleAliases.append(begin(PPC64Triples), end(PPC64Triples)); |
2634 | 33 | break; |
2635 | 3 | case llvm::Triple::ppcle: |
2636 | 3 | LibDirs.append(begin(PPCLELibDirs), end(PPCLELibDirs)); |
2637 | 3 | TripleAliases.append(begin(PPCLETriples), end(PPCLETriples)); |
2638 | 3 | BiarchLibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs)); |
2639 | 3 | BiarchTripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples)); |
2640 | 3 | break; |
2641 | 104 | case llvm::Triple::ppc64: |
2642 | 104 | LibDirs.append(begin(PPC64LibDirs), end(PPC64LibDirs)); |
2643 | 104 | TripleAliases.append(begin(PPC64Triples), end(PPC64Triples)); |
2644 | 104 | BiarchLibDirs.append(begin(PPCLibDirs), end(PPCLibDirs)); |
2645 | 104 | BiarchTripleAliases.append(begin(PPCTriples), end(PPCTriples)); |
2646 | 104 | break; |
2647 | 109 | case llvm::Triple::ppc64le: |
2648 | 109 | LibDirs.append(begin(PPC64LELibDirs), end(PPC64LELibDirs)); |
2649 | 109 | TripleAliases.append(begin(PPC64LETriples), end(PPC64LETriples)); |
2650 | 109 | BiarchLibDirs.append(begin(PPCLELibDirs), end(PPCLELibDirs)); |
2651 | 109 | BiarchTripleAliases.append(begin(PPCLETriples), end(PPCLETriples)); |
2652 | 109 | break; |
2653 | 142 | case llvm::Triple::riscv32: |
2654 | 142 | LibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs)); |
2655 | 142 | TripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples)); |
2656 | 142 | BiarchLibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs)); |
2657 | 142 | BiarchTripleAliases.append(begin(RISCV64Triples), end(RISCV64Triples)); |
2658 | 142 | break; |
2659 | 168 | case llvm::Triple::riscv64: |
2660 | 168 | LibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs)); |
2661 | 168 | TripleAliases.append(begin(RISCV64Triples), end(RISCV64Triples)); |
2662 | 168 | BiarchLibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs)); |
2663 | 168 | BiarchTripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples)); |
2664 | 168 | break; |
2665 | 13 | case llvm::Triple::sparc: |
2666 | 16 | case llvm::Triple::sparcel: |
2667 | 16 | LibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs)); |
2668 | 16 | TripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples)); |
2669 | 16 | BiarchLibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs)); |
2670 | 16 | BiarchTripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples)); |
2671 | 16 | break; |
2672 | 14 | case llvm::Triple::sparcv9: |
2673 | 14 | LibDirs.append(begin(SPARCv9LibDirs), end(SPARCv9LibDirs)); |
2674 | 14 | TripleAliases.append(begin(SPARCv9Triples), end(SPARCv9Triples)); |
2675 | 14 | BiarchLibDirs.append(begin(SPARCv8LibDirs), end(SPARCv8LibDirs)); |
2676 | 14 | BiarchTripleAliases.append(begin(SPARCv8Triples), end(SPARCv8Triples)); |
2677 | 14 | break; |
2678 | 47 | case llvm::Triple::systemz: |
2679 | 47 | LibDirs.append(begin(SystemZLibDirs), end(SystemZLibDirs)); |
2680 | 47 | TripleAliases.append(begin(SystemZTriples), end(SystemZTriples)); |
2681 | 47 | break; |
2682 | 155 | default: |
2683 | | // By default, just rely on the standard lib directories and the original |
2684 | | // triple. |
2685 | 155 | break; |
2686 | 5.34k | } |
2687 | | |
2688 | | // Also include the multiarch variant if it's different. |
2689 | 5.34k | if (TargetTriple.str() != BiarchTriple.str()) |
2690 | 5.34k | BiarchTripleAliases.push_back(BiarchTriple.str()); |
2691 | 5.34k | } |
2692 | | |
2693 | | bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs( |
2694 | | const llvm::Triple &TargetTriple, const ArgList &Args, |
2695 | 459 | StringRef Path, bool NeedsBiarchSuffix) { |
2696 | 459 | llvm::Triple::ArchType TargetArch = TargetTriple.getArch(); |
2697 | 459 | DetectedMultilibs Detected; |
2698 | | |
2699 | | // Android standalone toolchain could have multilibs for ARM and Thumb. |
2700 | | // Debian mips multilibs behave more like the rest of the biarch ones, |
2701 | | // so handle them there |
2702 | 459 | if (isArmOrThumbArch(TargetArch) && TargetTriple.isAndroid()37 ) { |
2703 | | // It should also work without multilibs in a simplified toolchain. |
2704 | 18 | findAndroidArmMultilibs(D, TargetTriple, Path, Args, Detected); |
2705 | 441 | } else if (TargetTriple.isCSKY()) { |
2706 | 2 | findCSKYMultilibs(D, TargetTriple, Path, Args, Detected); |
2707 | 439 | } else if (TargetTriple.isMIPS()) { |
2708 | 28 | if (!findMIPSMultilibs(D, TargetTriple, Path, Args, Detected)) |
2709 | 0 | return false; |
2710 | 411 | } else if (TargetTriple.isRISCV()) { |
2711 | 42 | findRISCVMultilibs(D, TargetTriple, Path, Args, Detected); |
2712 | 369 | } else if (isMSP430(TargetArch)) { |
2713 | 13 | findMSP430Multilibs(D, TargetTriple, Path, Args, Detected); |
2714 | 356 | } else if (TargetArch == llvm::Triple::avr) { |
2715 | | // AVR has no multilibs. |
2716 | 321 | } else if (!findBiarchMultilibs(D, TargetTriple, Path, Args, |
2717 | 321 | NeedsBiarchSuffix, Detected)) { |
2718 | 9 | return false; |
2719 | 9 | } |
2720 | | |
2721 | 450 | Multilibs = Detected.Multilibs; |
2722 | 450 | SelectedMultilib = Detected.SelectedMultilibs.empty() |
2723 | 450 | ? Multilib()62 |
2724 | 450 | : Detected.SelectedMultilibs.back()388 ; |
2725 | 450 | BiarchSibling = Detected.BiarchSibling; |
2726 | | |
2727 | 450 | return true; |
2728 | 459 | } |
2729 | | |
2730 | | void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple( |
2731 | | const llvm::Triple &TargetTriple, const ArgList &Args, |
2732 | | const std::string &LibDir, StringRef CandidateTriple, |
2733 | 174k | bool NeedsBiarchSuffix, bool GCCDirExists, bool GCCCrossDirExists) { |
2734 | | // Locations relative to the system lib directory where GCC's triple-specific |
2735 | | // directories might reside. |
2736 | 174k | struct GCCLibSuffix { |
2737 | | // Path from system lib directory to GCC triple-specific directory. |
2738 | 174k | std::string LibSuffix; |
2739 | | // Path from GCC triple-specific directory back to system lib directory. |
2740 | | // This is one '..' component per component in LibSuffix. |
2741 | 174k | StringRef ReversePath; |
2742 | | // Whether this library suffix is relevant for the triple. |
2743 | 174k | bool Active; |
2744 | 174k | } Suffixes[] = { |
2745 | | // This is the normal place. |
2746 | 174k | {"gcc/" + CandidateTriple.str(), "../..", GCCDirExists}, |
2747 | | |
2748 | | // Debian puts cross-compilers in gcc-cross. |
2749 | 174k | {"gcc-cross/" + CandidateTriple.str(), "../..", GCCCrossDirExists}, |
2750 | | |
2751 | | // The Freescale PPC SDK has the gcc libraries in |
2752 | | // <sysroot>/usr/lib/<triple>/x.y.z so have a look there as well. Only do |
2753 | | // this on Freescale triples, though, since some systems put a *lot* of |
2754 | | // files in that location, not just GCC installation data. |
2755 | 174k | {CandidateTriple.str(), "..", |
2756 | 174k | TargetTriple.getVendor() == llvm::Triple::Freescale || |
2757 | 174k | TargetTriple.getVendor() == llvm::Triple::OpenEmbedded174k }}; |
2758 | | |
2759 | 523k | for (auto &Suffix : Suffixes) { |
2760 | 523k | if (!Suffix.Active) |
2761 | 514k | continue; |
2762 | | |
2763 | 8.88k | StringRef LibSuffix = Suffix.LibSuffix; |
2764 | 8.88k | std::error_code EC; |
2765 | 8.88k | for (llvm::vfs::directory_iterator |
2766 | 8.88k | LI = D.getVFS().dir_begin(LibDir + "/" + LibSuffix, EC), |
2767 | 8.88k | LE; |
2768 | 10.0k | !EC && LI != LE2.21k ; LI = LI.increment(EC)1.12k ) { |
2769 | 1.12k | StringRef VersionText = llvm::sys::path::filename(LI->path()); |
2770 | 1.12k | GCCVersion CandidateVersion = GCCVersion::Parse(VersionText); |
2771 | 1.12k | if (CandidateVersion.Major != -1) // Filter obviously bad entries. |
2772 | 1.09k | if (!CandidateGCCInstallPaths.insert(std::string(LI->path())).second) |
2773 | 504 | continue; // Saw this path before; no need to look at it again. |
2774 | 621 | if (CandidateVersion.isOlderThan(4, 1, 1)) |
2775 | 28 | continue; |
2776 | 593 | if (CandidateVersion <= Version) |
2777 | 147 | continue; |
2778 | | |
2779 | 446 | if (!ScanGCCForMultilibs(TargetTriple, Args, LI->path(), |
2780 | 446 | NeedsBiarchSuffix)) |
2781 | 8 | continue; |
2782 | | |
2783 | 438 | Version = CandidateVersion; |
2784 | 438 | GCCTriple.setTriple(CandidateTriple); |
2785 | | // FIXME: We hack together the directory name here instead of |
2786 | | // using LI to ensure stable path separators across Windows and |
2787 | | // Linux. |
2788 | 438 | GCCInstallPath = (LibDir + "/" + LibSuffix + "/" + VersionText).str(); |
2789 | 438 | GCCParentLibPath = (GCCInstallPath + "/../" + Suffix.ReversePath).str(); |
2790 | 438 | IsValid = true; |
2791 | 438 | } |
2792 | 8.88k | } |
2793 | 174k | } |
2794 | | |
2795 | | bool Generic_GCC::GCCInstallationDetector::ScanGentooConfigs( |
2796 | | const llvm::Triple &TargetTriple, const ArgList &Args, |
2797 | | const SmallVectorImpl<StringRef> &CandidateTriples, |
2798 | 5.54k | const SmallVectorImpl<StringRef> &CandidateBiarchTriples) { |
2799 | 5.54k | if (!D.getVFS().exists(concat(D.SysRoot, GentooConfigDir))) |
2800 | 5.53k | return false; |
2801 | | |
2802 | 51 | for (StringRef CandidateTriple : CandidateTriples)9 { |
2803 | 51 | if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple)) |
2804 | 3 | return true; |
2805 | 51 | } |
2806 | | |
2807 | 18 | for (StringRef CandidateTriple : CandidateBiarchTriples)6 { |
2808 | 18 | if (ScanGentooGccConfig(TargetTriple, Args, CandidateTriple, true)) |
2809 | 6 | return true; |
2810 | 18 | } |
2811 | 0 | return false; |
2812 | 6 | } |
2813 | | |
2814 | | bool Generic_GCC::GCCInstallationDetector::ScanGentooGccConfig( |
2815 | | const llvm::Triple &TargetTriple, const ArgList &Args, |
2816 | 69 | StringRef CandidateTriple, bool NeedsBiarchSuffix) { |
2817 | 69 | llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File = |
2818 | 69 | D.getVFS().getBufferForFile(concat(D.SysRoot, GentooConfigDir, |
2819 | 69 | "/config-" + CandidateTriple.str())); |
2820 | 69 | if (File) { |
2821 | 9 | SmallVector<StringRef, 2> Lines; |
2822 | 9 | File.get()->getBuffer().split(Lines, "\n"); |
2823 | 9 | for (StringRef Line : Lines) { |
2824 | 9 | Line = Line.trim(); |
2825 | | // CURRENT=triple-version |
2826 | 9 | if (!Line.consume_front("CURRENT=")) |
2827 | 0 | continue; |
2828 | | // Process the config file pointed to by CURRENT. |
2829 | 9 | llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ConfigFile = |
2830 | 9 | D.getVFS().getBufferForFile( |
2831 | 9 | concat(D.SysRoot, GentooConfigDir, "/" + Line)); |
2832 | 9 | std::pair<StringRef, StringRef> ActiveVersion = Line.rsplit('-'); |
2833 | | // List of paths to scan for libraries. |
2834 | 9 | SmallVector<StringRef, 4> GentooScanPaths; |
2835 | | // Scan the Config file to find installed GCC libraries path. |
2836 | | // Typical content of the GCC config file: |
2837 | | // LDPATH="/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x:/usr/lib/gcc/ |
2838 | | // (continued from previous line) x86_64-pc-linux-gnu/4.9.x/32" |
2839 | | // MANPATH="/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.x/man" |
2840 | | // INFOPATH="/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.x/info" |
2841 | | // STDCXX_INCDIR="/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/include/g++-v4" |
2842 | | // We are looking for the paths listed in LDPATH=... . |
2843 | 9 | if (ConfigFile) { |
2844 | 9 | SmallVector<StringRef, 2> ConfigLines; |
2845 | 9 | ConfigFile.get()->getBuffer().split(ConfigLines, "\n"); |
2846 | 99 | for (StringRef ConfLine : ConfigLines) { |
2847 | 99 | ConfLine = ConfLine.trim(); |
2848 | 99 | if (ConfLine.consume_front("LDPATH=")) { |
2849 | | // Drop '"' from front and back if present. |
2850 | 9 | ConfLine.consume_back("\""); |
2851 | 9 | ConfLine.consume_front("\""); |
2852 | | // Get all paths sperated by ':' |
2853 | 9 | ConfLine.split(GentooScanPaths, ':', -1, /*AllowEmpty*/ false); |
2854 | 9 | } |
2855 | 99 | } |
2856 | 9 | } |
2857 | | // Test the path based on the version in /etc/env.d/gcc/config-{tuple}. |
2858 | 9 | std::string basePath = "/usr/lib/gcc/" + ActiveVersion.first.str() + "/" |
2859 | 9 | + ActiveVersion.second.str(); |
2860 | 9 | GentooScanPaths.push_back(StringRef(basePath)); |
2861 | | |
2862 | | // Scan all paths for GCC libraries. |
2863 | 9 | for (const auto &GentooScanPath : GentooScanPaths) { |
2864 | 9 | std::string GentooPath = concat(D.SysRoot, GentooScanPath); |
2865 | 9 | if (D.getVFS().exists(GentooPath + "/crtbegin.o")) { |
2866 | 9 | if (!ScanGCCForMultilibs(TargetTriple, Args, GentooPath, |
2867 | 9 | NeedsBiarchSuffix)) |
2868 | 0 | continue; |
2869 | | |
2870 | 9 | Version = GCCVersion::Parse(ActiveVersion.second); |
2871 | 9 | GCCInstallPath = GentooPath; |
2872 | 9 | GCCParentLibPath = GentooPath + std::string("/../../.."); |
2873 | 9 | GCCTriple.setTriple(ActiveVersion.first); |
2874 | 9 | IsValid = true; |
2875 | 9 | return true; |
2876 | 9 | } |
2877 | 9 | } |
2878 | 9 | } |
2879 | 9 | } |
2880 | | |
2881 | 60 | return false; |
2882 | 69 | } |
2883 | | |
2884 | | Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple &Triple, |
2885 | | const ArgList &Args) |
2886 | 19.9k | : ToolChain(D, Triple, Args), GCCInstallation(D), |
2887 | 19.9k | CudaInstallation(D, Triple, Args), RocmInstallation(D, Triple, Args) { |
2888 | 19.9k | getProgramPaths().push_back(getDriver().getInstalledDir()); |
2889 | 19.9k | if (getDriver().getInstalledDir() != getDriver().Dir) |
2890 | 20 | getProgramPaths().push_back(getDriver().Dir); |
2891 | 19.9k | } |
2892 | | |
2893 | 19.9k | Generic_GCC::~Generic_GCC() {} |
2894 | | |
2895 | 3.76k | Tool *Generic_GCC::getTool(Action::ActionClass AC) const { |
2896 | 3.76k | switch (AC) { |
2897 | 0 | case Action::PreprocessJobClass: |
2898 | 0 | if (!Preprocess) |
2899 | 0 | Preprocess.reset(new clang::driver::tools::gcc::Preprocessor(*this)); |
2900 | 0 | return Preprocess.get(); |
2901 | 4 | case Action::CompileJobClass: |
2902 | 4 | if (!Compile) |
2903 | 4 | Compile.reset(new tools::gcc::Compiler(*this)); |
2904 | 4 | return Compile.get(); |
2905 | 3.76k | default: |
2906 | 3.76k | return ToolChain::getTool(AC); |
2907 | 3.76k | } |
2908 | 3.76k | } |
2909 | | |
2910 | 46 | Tool *Generic_GCC::buildAssembler() const { |
2911 | 46 | return new tools::gnutools::Assembler(*this); |
2912 | 46 | } |
2913 | | |
2914 | 427 | Tool *Generic_GCC::buildLinker() const { return new tools::gcc::Linker(*this); } |
2915 | | |
2916 | 72 | void Generic_GCC::printVerboseInfo(raw_ostream &OS) const { |
2917 | | // Print the information about how we detected the GCC installation. |
2918 | 72 | GCCInstallation.print(OS); |
2919 | 72 | CudaInstallation->print(OS); |
2920 | 72 | RocmInstallation->print(OS); |
2921 | 72 | } |
2922 | | |
2923 | | ToolChain::UnwindTableLevel |
2924 | 37.9k | Generic_GCC::getDefaultUnwindTableLevel(const ArgList &Args) const { |
2925 | 37.9k | switch (getArch()) { |
2926 | 2.25k | case llvm::Triple::aarch64: |
2927 | 2.37k | case llvm::Triple::ppc: |
2928 | 2.38k | case llvm::Triple::ppcle: |
2929 | 2.64k | case llvm::Triple::ppc64: |
2930 | 2.87k | case llvm::Triple::ppc64le: |
2931 | 3.15k | case llvm::Triple::riscv32: |
2932 | 3.51k | case llvm::Triple::riscv64: |
2933 | 25.2k | case llvm::Triple::x86: |
2934 | 31.4k | case llvm::Triple::x86_64: |
2935 | 31.4k | return UnwindTableLevel::Asynchronous; |
2936 | 6.55k | default: |
2937 | 6.55k | return UnwindTableLevel::None; |
2938 | 37.9k | } |
2939 | 37.9k | } |
2940 | | |
2941 | 13.7k | bool Generic_GCC::isPICDefault() const { |
2942 | 13.7k | switch (getArch()) { |
2943 | 531 | case llvm::Triple::x86_64: |
2944 | 531 | return getTriple().isOSWindows(); |
2945 | 34 | case llvm::Triple::mips64: |
2946 | 52 | case llvm::Triple::mips64el: |
2947 | 52 | return true; |
2948 | 13.1k | default: |
2949 | 13.1k | return false; |
2950 | 13.7k | } |
2951 | 13.7k | } |
2952 | | |
2953 | 13.8k | bool Generic_GCC::isPIEDefault(const llvm::opt::ArgList &Args) const { |
2954 | 13.8k | return false; |
2955 | 13.8k | } |
2956 | | |
2957 | 19.8k | bool Generic_GCC::isPICDefaultForced() const { |
2958 | 19.8k | return getArch() == llvm::Triple::x86_64 && getTriple().isOSWindows()3.31k ; |
2959 | 19.8k | } |
2960 | | |
2961 | 118k | bool Generic_GCC::IsIntegratedAssemblerDefault() const { |
2962 | 118k | switch (getTriple().getArch()) { |
2963 | 0 | case llvm::Triple::nvptx: |
2964 | 0 | case llvm::Triple::nvptx64: |
2965 | 0 | case llvm::Triple::xcore: |
2966 | 0 | return false; |
2967 | 118k | default: |
2968 | 118k | return true; |
2969 | 118k | } |
2970 | 118k | } |
2971 | | |
2972 | 5.38k | void Generic_GCC::PushPPaths(ToolChain::path_list &PPaths) { |
2973 | | // Cross-compiling binutils and GCC installations (vanilla and openSUSE at |
2974 | | // least) put various tools in a triple-prefixed directory off of the parent |
2975 | | // of the GCC installation. We use the GCC triple here to ensure that we end |
2976 | | // up with tools that support the same amount of cross compiling as the |
2977 | | // detected GCC installation. For example, if we find a GCC installation |
2978 | | // targeting x86_64, but it is a bi-arch GCC installation, it can also be |
2979 | | // used to target i386. |
2980 | 5.38k | if (GCCInstallation.isValid()) { |
2981 | 293 | PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + |
2982 | 293 | GCCInstallation.getTriple().str() + "/bin") |
2983 | 293 | .str()); |
2984 | 293 | } |
2985 | 5.38k | } |
2986 | | |
2987 | | void Generic_GCC::AddMultilibPaths(const Driver &D, |
2988 | | const std::string &SysRoot, |
2989 | | const std::string &OSLibDir, |
2990 | | const std::string &MultiarchTriple, |
2991 | 5.66k | path_list &Paths) { |
2992 | | // Add the multilib suffixed paths where they are available. |
2993 | 5.66k | if (GCCInstallation.isValid()) { |
2994 | 309 | assert(!SelectedMultilibs.empty()); |
2995 | 309 | const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); |
2996 | 309 | const std::string &LibPath = |
2997 | 309 | std::string(GCCInstallation.getParentLibPath()); |
2998 | | |
2999 | | // Sourcery CodeBench MIPS toolchain holds some libraries under |
3000 | | // a biarch-like suffix of the GCC installation. |
3001 | 309 | if (const auto &PathsCallback = Multilibs.filePathsCallback()) |
3002 | 28 | for (const auto &Path : PathsCallback(SelectedMultilibs.back())) |
3003 | 28 | addPathIfExists(D, GCCInstallation.getInstallPath() + Path, Paths); |
3004 | | |
3005 | | // Add lib/gcc/$triple/$version, with an optional /multilib suffix. |
3006 | 309 | addPathIfExists(D, |
3007 | 309 | GCCInstallation.getInstallPath() + |
3008 | 309 | SelectedMultilibs.back().gccSuffix(), |
3009 | 309 | Paths); |
3010 | | |
3011 | | // Add lib/gcc/$triple/$libdir |
3012 | | // For GCC built with --enable-version-specific-runtime-libs. |
3013 | 309 | addPathIfExists(D, GCCInstallation.getInstallPath() + "/../" + OSLibDir, |
3014 | 309 | Paths); |
3015 | | |
3016 | | // GCC cross compiling toolchains will install target libraries which ship |
3017 | | // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as |
3018 | | // any part of the GCC installation in |
3019 | | // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat |
3020 | | // debatable, but is the reality today. We need to search this tree even |
3021 | | // when we have a sysroot somewhere else. It is the responsibility of |
3022 | | // whomever is doing the cross build targeting a sysroot using a GCC |
3023 | | // installation that is *not* within the system root to ensure two things: |
3024 | | // |
3025 | | // 1) Any DSOs that are linked in from this tree or from the install path |
3026 | | // above must be present on the system root and found via an |
3027 | | // appropriate rpath. |
3028 | | // 2) There must not be libraries installed into |
3029 | | // <prefix>/<triple>/<libdir> unless they should be preferred over |
3030 | | // those within the system root. |
3031 | | // |
3032 | | // Note that this matches the GCC behavior. See the below comment for where |
3033 | | // Clang diverges from GCC's behavior. |
3034 | 309 | addPathIfExists(D, |
3035 | 309 | LibPath + "/../" + GCCTriple.str() + "/lib/../" + OSLibDir + |
3036 | 309 | SelectedMultilibs.back().osSuffix(), |
3037 | 309 | Paths); |
3038 | | |
3039 | | // If the GCC installation we found is inside of the sysroot, we want to |
3040 | | // prefer libraries installed in the parent prefix of the GCC installation. |
3041 | | // It is important to *not* use these paths when the GCC installation is |
3042 | | // outside of the system root as that can pick up unintended libraries. |
3043 | | // This usually happens when there is an external cross compiler on the |
3044 | | // host system, and a more minimal sysroot available that is the target of |
3045 | | // the cross. Note that GCC does include some of these directories in some |
3046 | | // configurations but this seems somewhere between questionable and simply |
3047 | | // a bug. |
3048 | 309 | if (StringRef(LibPath).startswith(SysRoot)) |
3049 | 254 | addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths); |
3050 | 309 | } |
3051 | 5.66k | } |
3052 | | |
3053 | | void Generic_GCC::AddMultiarchPaths(const Driver &D, |
3054 | | const std::string &SysRoot, |
3055 | | const std::string &OSLibDir, |
3056 | 5.38k | path_list &Paths) { |
3057 | 5.38k | if (GCCInstallation.isValid()) { |
3058 | 293 | const std::string &LibPath = |
3059 | 293 | std::string(GCCInstallation.getParentLibPath()); |
3060 | 293 | const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); |
3061 | 293 | const Multilib &Multilib = GCCInstallation.getMultilib(); |
3062 | 293 | addPathIfExists( |
3063 | 293 | D, LibPath + "/../" + GCCTriple.str() + "/lib" + Multilib.osSuffix(), |
3064 | 293 | Paths); |
3065 | 293 | } |
3066 | 5.38k | } |
3067 | | |
3068 | | void Generic_GCC::AddMultilibIncludeArgs(const ArgList &DriverArgs, |
3069 | 5.79k | ArgStringList &CC1Args) const { |
3070 | | // Add include directories specific to the selected multilib set and multilib. |
3071 | 5.79k | if (!GCCInstallation.isValid()) |
3072 | 5.50k | return; |
3073 | | // gcc TOOL_INCLUDE_DIR. |
3074 | 286 | const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); |
3075 | 286 | std::string LibPath(GCCInstallation.getParentLibPath()); |
3076 | 286 | addSystemInclude(DriverArgs, CC1Args, |
3077 | 286 | Twine(LibPath) + "/../" + GCCTriple.str() + "/include"); |
3078 | | |
3079 | 286 | const auto &Callback = Multilibs.includeDirsCallback(); |
3080 | 286 | if (Callback) { |
3081 | 17 | for (const auto &Path : Callback(GCCInstallation.getMultilib())) |
3082 | 18 | addExternCSystemIncludeIfExists(DriverArgs, CC1Args, |
3083 | 18 | GCCInstallation.getInstallPath() + Path); |
3084 | 17 | } |
3085 | 286 | } |
3086 | | |
3087 | | void Generic_GCC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, |
3088 | 11.5k | ArgStringList &CC1Args) const { |
3089 | 11.5k | if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdincxx, |
3090 | 11.5k | options::OPT_nostdlibinc)) |
3091 | 3 | return; |
3092 | | |
3093 | 11.5k | switch (GetCXXStdlibType(DriverArgs)) { |
3094 | 126 | case ToolChain::CST_Libcxx: |
3095 | 126 | addLibCxxIncludePaths(DriverArgs, CC1Args); |
3096 | 126 | break; |
3097 | | |
3098 | 11.4k | case ToolChain::CST_Libstdcxx: |
3099 | 11.4k | addLibStdCxxIncludePaths(DriverArgs, CC1Args); |
3100 | 11.4k | break; |
3101 | 11.5k | } |
3102 | 11.5k | } |
3103 | | |
3104 | | void |
3105 | | Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, |
3106 | 50 | llvm::opt::ArgStringList &CC1Args) const { |
3107 | 50 | const Driver &D = getDriver(); |
3108 | 50 | std::string SysRoot = computeSysRoot(); |
3109 | 50 | if (SysRoot.empty()) |
3110 | 20 | SysRoot = llvm::sys::path::get_separator(); |
3111 | | |
3112 | 112 | auto AddIncludePath = [&](StringRef Path, bool TargetDirRequired = false) { |
3113 | 112 | std::string Version = detectLibcxxVersion(Path); |
3114 | 112 | if (Version.empty()) |
3115 | 49 | return false; |
3116 | | |
3117 | | // First add the per-target include path if it exists. |
3118 | 63 | bool TargetDirExists = false; |
3119 | 63 | std::optional<std::string> TargetIncludeDir = getTargetSubDirPath(Path); |
3120 | 63 | if (TargetIncludeDir) { |
3121 | 17 | SmallString<128> TargetDir(*TargetIncludeDir); |
3122 | 17 | llvm::sys::path::append(TargetDir, "c++", Version); |
3123 | 17 | if (D.getVFS().exists(TargetDir)) { |
3124 | 17 | addSystemInclude(DriverArgs, CC1Args, TargetDir); |
3125 | 17 | TargetDirExists = true; |
3126 | 17 | } |
3127 | 17 | } |
3128 | 63 | if (TargetDirRequired && !TargetDirExists32 ) |
3129 | 24 | return false; |
3130 | | |
3131 | | // Second add the generic one. |
3132 | 39 | SmallString<128> GenericDir(Path); |
3133 | 39 | llvm::sys::path::append(GenericDir, "c++", Version); |
3134 | 39 | addSystemInclude(DriverArgs, CC1Args, GenericDir); |
3135 | 39 | return true; |
3136 | 63 | }; |
3137 | | |
3138 | | // Android only uses the libc++ headers installed alongside the toolchain if |
3139 | | // they contain an Android-specific target include path, otherwise they're |
3140 | | // incompatible with the NDK libraries. |
3141 | 50 | SmallString<128> DriverIncludeDir(getDriver().Dir); |
3142 | 50 | llvm::sys::path::append(DriverIncludeDir, "..", "include"); |
3143 | 50 | if (AddIncludePath(DriverIncludeDir, |
3144 | 50 | /*TargetDirRequired=*/getTriple().isAndroid())) |
3145 | 19 | return; |
3146 | | // If this is a development, non-installed, clang, libcxx will |
3147 | | // not be found at ../include/c++ but it likely to be found at |
3148 | | // one of the following two locations: |
3149 | 31 | SmallString<128> UsrLocalIncludeDir(SysRoot); |
3150 | 31 | llvm::sys::path::append(UsrLocalIncludeDir, "usr", "local", "include"); |
3151 | 31 | if (AddIncludePath(UsrLocalIncludeDir)) |
3152 | 0 | return; |
3153 | 31 | SmallString<128> UsrIncludeDir(SysRoot); |
3154 | 31 | llvm::sys::path::append(UsrIncludeDir, "usr", "include"); |
3155 | 31 | if (AddIncludePath(UsrIncludeDir)) |
3156 | 20 | return; |
3157 | 31 | } |
3158 | | |
3159 | | bool Generic_GCC::addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple, |
3160 | | Twine IncludeSuffix, |
3161 | | const llvm::opt::ArgList &DriverArgs, |
3162 | | llvm::opt::ArgStringList &CC1Args, |
3163 | 326 | bool DetectDebian) const { |
3164 | 326 | if (!getVFS().exists(IncludeDir)) |
3165 | 238 | return false; |
3166 | | |
3167 | | // Debian native gcc uses g++-multiarch-incdir.diff which uses |
3168 | | // include/x86_64-linux-gnu/c++/10$IncludeSuffix instead of |
3169 | | // include/c++/10/x86_64-linux-gnu$IncludeSuffix. |
3170 | 88 | std::string Dir = IncludeDir.str(); |
3171 | 88 | StringRef Include = |
3172 | 88 | llvm::sys::path::parent_path(llvm::sys::path::parent_path(Dir)); |
3173 | 88 | std::string Path = |
3174 | 88 | (Include + "/" + Triple + Dir.substr(Include.size()) + IncludeSuffix) |
3175 | 88 | .str(); |
3176 | 88 | if (DetectDebian && !getVFS().exists(Path)24 ) |
3177 | 12 | return false; |
3178 | | |
3179 | | // GPLUSPLUS_INCLUDE_DIR |
3180 | 76 | addSystemInclude(DriverArgs, CC1Args, IncludeDir); |
3181 | | // GPLUSPLUS_TOOL_INCLUDE_DIR. If Triple is not empty, add a target-dependent |
3182 | | // include directory. |
3183 | 76 | if (DetectDebian) |
3184 | 12 | addSystemInclude(DriverArgs, CC1Args, Path); |
3185 | 64 | else if (!Triple.empty()) |
3186 | 61 | addSystemInclude(DriverArgs, CC1Args, |
3187 | 61 | IncludeDir + "/" + Triple + IncludeSuffix); |
3188 | | // GPLUSPLUS_BACKWARD_INCLUDE_DIR |
3189 | 76 | addSystemInclude(DriverArgs, CC1Args, IncludeDir + "/backward"); |
3190 | 76 | return true; |
3191 | 88 | } |
3192 | | |
3193 | | bool Generic_GCC::addGCCLibStdCxxIncludePaths( |
3194 | | const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, |
3195 | 72 | StringRef DebianMultiarch) const { |
3196 | 72 | assert(GCCInstallation.isValid()); |
3197 | | |
3198 | | // By default, look for the C++ headers in an include directory adjacent to |
3199 | | // the lib directory of the GCC installation. Note that this is expect to be |
3200 | | // equivalent to '/usr/include/c++/X.Y' in almost all cases. |
3201 | 72 | StringRef LibDir = GCCInstallation.getParentLibPath(); |
3202 | 72 | StringRef InstallDir = GCCInstallation.getInstallPath(); |
3203 | 72 | StringRef TripleStr = GCCInstallation.getTriple().str(); |
3204 | 72 | const Multilib &Multilib = GCCInstallation.getMultilib(); |
3205 | 72 | const GCCVersion &Version = GCCInstallation.getVersion(); |
3206 | | |
3207 | | // Try /../$triple/include/c++/$version (gcc --print-multiarch is not empty). |
3208 | 72 | if (addLibStdCXXIncludePaths( |
3209 | 72 | LibDir.str() + "/../" + TripleStr + "/include/c++/" + Version.Text, |
3210 | 72 | TripleStr, Multilib.includeSuffix(), DriverArgs, CC1Args)) |
3211 | 20 | return true; |
3212 | | |
3213 | | // Try /gcc/$triple/$version/include/c++/ (gcc --print-multiarch is not |
3214 | | // empty). Like above but for GCC built with |
3215 | | // --enable-version-specific-runtime-libs. |
3216 | 52 | if (addLibStdCXXIncludePaths(LibDir.str() + "/gcc/" + TripleStr + "/" + |
3217 | 52 | Version.Text + "/include/c++/", |
3218 | 52 | TripleStr, Multilib.includeSuffix(), DriverArgs, |
3219 | 52 | CC1Args)) |
3220 | 4 | return true; |
3221 | | |
3222 | | // Detect Debian g++-multiarch-incdir.diff. |
3223 | 48 | if (addLibStdCXXIncludePaths(LibDir.str() + "/../include/c++/" + Version.Text, |
3224 | 48 | DebianMultiarch, Multilib.includeSuffix(), |
3225 | 48 | DriverArgs, CC1Args, /*Debian=*/true)) |
3226 | 12 | return true; |
3227 | | |
3228 | | // Try /../include/c++/$version (gcc --print-multiarch is empty). |
3229 | 36 | if (addLibStdCXXIncludePaths(LibDir.str() + "/../include/c++/" + Version.Text, |
3230 | 36 | TripleStr, Multilib.includeSuffix(), DriverArgs, |
3231 | 36 | CC1Args)) |
3232 | 12 | return true; |
3233 | | |
3234 | | // Otherwise, fall back on a bunch of options which don't use multiarch |
3235 | | // layouts for simplicity. |
3236 | 24 | const std::string LibStdCXXIncludePathCandidates[] = { |
3237 | | // Gentoo is weird and places its headers inside the GCC install, |
3238 | | // so if the first attempt to find the headers fails, try these patterns. |
3239 | 24 | InstallDir.str() + "/include/g++-v" + Version.Text, |
3240 | 24 | InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." + |
3241 | 24 | Version.MinorStr, |
3242 | 24 | InstallDir.str() + "/include/g++-v" + Version.MajorStr, |
3243 | 24 | }; |
3244 | | |
3245 | 57 | for (const auto &IncludePath : LibStdCXXIncludePathCandidates) { |
3246 | 57 | if (addLibStdCXXIncludePaths(IncludePath, TripleStr, |
3247 | 57 | Multilib.includeSuffix(), DriverArgs, CC1Args)) |
3248 | 9 | return true; |
3249 | 57 | } |
3250 | 15 | return false; |
3251 | 24 | } |
3252 | | |
3253 | | void |
3254 | | Generic_GCC::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, |
3255 | 8.76k | llvm::opt::ArgStringList &CC1Args) const { |
3256 | 8.76k | if (GCCInstallation.isValid()) { |
3257 | 1 | addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args, |
3258 | 1 | GCCInstallation.getTriple().str()); |
3259 | 1 | } |
3260 | 8.76k | } |
3261 | | |
3262 | | llvm::opt::DerivedArgList * |
3263 | | Generic_GCC::TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef, |
3264 | 20.2k | Action::OffloadKind DeviceOffloadKind) const { |
3265 | | |
3266 | | // If this tool chain is used for an OpenMP offloading device we have to make |
3267 | | // sure we always generate a shared library regardless of the commands the |
3268 | | // user passed to the host. This is required because the runtime library |
3269 | | // is required to load the device image dynamically at run time. |
3270 | 20.2k | if (DeviceOffloadKind == Action::OFK_OpenMP) { |
3271 | 25 | DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); |
3272 | 25 | const OptTable &Opts = getDriver().getOpts(); |
3273 | | |
3274 | | // Request the shared library. Given that these options are decided |
3275 | | // implicitly, they do not refer to any base argument. |
3276 | 25 | DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_shared)); |
3277 | 25 | DAL->AddFlagArg(/*BaseArg=*/nullptr, Opts.getOption(options::OPT_fPIC)); |
3278 | | |
3279 | | // Filter all the arguments we don't care passing to the offloading |
3280 | | // toolchain as they can mess up with the creation of a shared library. |
3281 | 227 | for (auto *A : Args) { |
3282 | 227 | switch ((options::ID)A->getOption().getID()) { |
3283 | 227 | default: |
3284 | 227 | DAL->append(A); |
3285 | 227 | break; |
3286 | 0 | case options::OPT_shared: |
3287 | 0 | case options::OPT_dynamic: |
3288 | 0 | case options::OPT_static: |
3289 | 0 | case options::OPT_fPIC: |
3290 | 0 | case options::OPT_fno_PIC: |
3291 | 0 | case options::OPT_fpic: |
3292 | 0 | case options::OPT_fno_pic: |
3293 | 0 | case options::OPT_fPIE: |
3294 | 0 | case options::OPT_fno_PIE: |
3295 | 0 | case options::OPT_fpie: |
3296 | 0 | case options::OPT_fno_pie: |
3297 | 0 | break; |
3298 | 227 | } |
3299 | 227 | } |
3300 | 25 | return DAL; |
3301 | 25 | } |
3302 | 20.2k | return nullptr; |
3303 | 20.2k | } |
3304 | | |
3305 | 0 | void Generic_ELF::anchor() {} |
3306 | | |
3307 | | void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs, |
3308 | | ArgStringList &CC1Args, |
3309 | 18.3k | Action::OffloadKind) const { |
3310 | 18.3k | if (!DriverArgs.hasFlag(options::OPT_fuse_init_array, |
3311 | 18.3k | options::OPT_fno_use_init_array, true)) |
3312 | 1 | CC1Args.push_back("-fno-use-init-array"); |
3313 | 18.3k | } |