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