22#include "llvm/ADT/StringExtras.h"
23#include "llvm/Option/ArgList.h"
24#include "llvm/Support/Path.h"
25#include "llvm/Support/VirtualFileSystem.h"
36 if (!Triple.isRISCV())
39 if (Triple.getVendor() != llvm::Triple::UnknownVendor)
42 if (Triple.getOS() != llvm::Triple::UnknownOS)
45 return Triple.getEnvironmentName() ==
"elf";
50 return Triple.isPPC() && Triple.getOS() == llvm::Triple::UnknownOS &&
51 Triple.getEnvironment() == llvm::Triple::EABI;
55 const llvm::Triple &TargetTriple,
61 if (TargetTriple.isRISCV64()) {
65 .
flag(
"-march=rv64imafdc")
70 (
Arch ==
"rv64imafdc") || (
Arch ==
"rv64gc");
79 return Result.Multilibs.select(
D, Flags, Result.SelectedMultilibs);
81 if (TargetTriple.isRISCV32()) {
88 .
flag(
"-march=rv32im")
91 .
flag(
"-march=rv32iac")
94 .
flag(
"-march=rv32imafc")
95 .
flag(
"-mabi=ilp32f");
98 bool UseI = (
Arch ==
"rv32i") || (
Arch ==
"rv32ic");
99 bool UseIm = (
Arch ==
"rv32im") || (
Arch ==
"rv32imc");
100 bool UseImafc = (
Arch ==
"rv32imafc") || (
Arch ==
"rv32imafdc") ||
113 return Result.Multilibs.select(
D, Flags, Result.SelectedMultilibs);
119 bool IncludeTriple) {
120 if (!
D.SysRoot.empty())
124 llvm::sys::path::append(SysRootDir,
"..",
"lib",
"clang-runtimes");
127 llvm::sys::path::append(SysRootDir,
D.getTargetTriple());
129 return std::string(SysRootDir);
136 const llvm::opt::ArgList &Args) {
137 if (Args.getLastArg(options::OPT_gcc_toolchain) ||
138 Args.getLastArg(clang::driver::options::OPT_gcc_install_dir_EQ)) {
151 llvm::sys::path::append(GCCDir,
D.Dir,
"..",
D.getTargetTriple(),
153 return llvm::sys::fs::exists(GCCDir);
167 if (!SysRoot.empty())
173 if (!
D.SysRoot.empty())
179 if (IsGCCInstallationValid) {
185 llvm::sys::path::append(inferredSysRoot,
D.Dir,
"..",
D.getTargetTriple());
188 if (!inferredSysRoot.empty() && llvm::sys::fs::exists(inferredSysRoot))
189 return std::string(inferredSysRoot);
199 llvm::sys::path::append(
Path,
"lib");
200 return std::string(
Path.str());
207 StringRef InstallPath,
223 if (IsGCCInstallationValid) {
225 D.Diag(clang::diag::warn_drv_multilib_not_available_for_target);
237 Paths.push_back(ComputedSysRoot +
"/lib");
250 if (!SysRootDir.empty()) {
251 for (
const Multilib &M : getOrderedMultilibs()) {
253 llvm::sys::path::append(Dir, M.osSuffix(),
"lib");
263 StringRef MultilibPath,
const ArgList &Args,
266 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MB =
267 D.getVFS().getBufferForFile(MultilibPath);
271 llvm::ErrorOr<MultilibSet> ErrorOrMultilibSet =
273 if (ErrorOrMultilibSet.getError())
275 Result.Multilibs = ErrorOrMultilibSet.get();
276 if (
Result.Multilibs.select(
D, Flags,
Result.SelectedMultilibs,
277 &CustomFlagsMacroDefines))
279 D.Diag(clang::diag::warn_drv_missing_multilib) << llvm::join(Flags,
" ");
280 std::stringstream ss;
287 D.Diag(clang::diag::note_drv_available_multilibs) << ss.str();
296 D.Diag(clang::diag::err_drv_multilib_custom_error)
301 Result.SelectedMultilibs.clear();
306static std::optional<llvm::SmallString<128>>
308 const ArgList &Args) {
310 if (Arg *ConfigFileArg = Args.getLastArg(options::OPT_multi_lib_config)) {
311 MultilibPath = ConfigFileArg->getValue();
312 if (!
D.getVFS().exists(MultilibPath)) {
313 D.Diag(clang::diag::err_drv_no_such_file) << MultilibPath.str();
324 const ArgList &Args) {
328 std::optional<llvm::SmallString<128>> MultilibPath =
332 if (
D.getVFS().exists(*MultilibPath)) {
338 CustomFlagMacroDefines);
341 MultilibMacroDefines.append(CustomFlagMacroDefines.begin(),
342 CustomFlagMacroDefines.end());
365BareMetal::OrderedMultilibs BareMetal::getOrderedMultilibs()
const {
376 if (
getTriple().isRISCV() && IsGCCInstallationValid)
382 if (
getTriple().isRISCV() && IsGCCInstallationValid)
398 ArgStringList &CC1Args)
const {
399 if (DriverArgs.hasArg(options::OPT_nostdinc))
402 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
404 llvm::sys::path::append(Dir,
"include");
408 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
415 if (!SysRootDir.empty()) {
416 for (
const Multilib &M : getOrderedMultilibs()) {
418 llvm::sys::path::append(Dir, M.includeSuffix());
419 llvm::sys::path::append(Dir,
"include");
426 ArgStringList &CC1Args,
428 CC1Args.push_back(
"-nostdsysteminc");
432 const llvm::opt::ArgList &DriverArgs,
433 llvm::opt::ArgStringList &CC1Args)
const {
434 if (!IsGCCInstallationValid)
445 ArgStringList &CC1Args)
const {
446 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
447 options::OPT_nostdincxx))
453 auto AddCXXIncludePath = [&](StringRef
Path) {
461 llvm::sys::path::append(TargetDir,
Target,
"c++", Version);
468 llvm::sys::path::append(Dir,
"c++", Version);
476 llvm::sys::path::append(
P,
"..",
"include");
477 AddCXXIncludePath(
P);
486 if (SysRootDir.empty())
489 for (
const Multilib &M : getOrderedMultilibs()) {
491 llvm::sys::path::append(Dir, M.gccSuffix());
496 llvm::sys::path::append(TargetDir,
"usr",
"include",
"c++",
"v1");
497 if (
D.getVFS().exists(TargetDir)) {
502 llvm::sys::path::append(Dir,
"include",
"c++",
"v1");
507 llvm::sys::path::append(Dir,
"include",
"c++");
511 for (llvm::vfs::directory_iterator
512 LI =
D.getVFS().dir_begin(Dir.str(), EC),
514 !EC && LI != LE; LI = LI.increment(EC)) {
515 StringRef VersionText = llvm::sys::path::filename(LI->path());
517 if (CandidateVersion.Major == -1)
519 if (CandidateVersion <= Version)
521 Version = CandidateVersion;
523 if (Version.
Major != -1) {
524 llvm::sys::path::append(Dir, Version.
Text);
537 const char *LinkingOutput)
const {
538 const Driver &
D = getToolChain().getDriver();
541 Args.ClaimAllArgs(options::OPT_g_Group);
543 Args.ClaimAllArgs(options::OPT_emit_llvm);
546 Args.ClaimAllArgs(options::OPT_w);
548 Args.ClaimAllArgs(options::OPT_stdlib_EQ);
551 ArgStringList CmdArgs;
553 CmdArgs.push_back(
"rcsD");
556 for (
const auto &II : Inputs) {
557 if (II.isFilename()) {
558 CmdArgs.push_back(II.getFilename());
565 if (Output.
isFilename() && llvm::sys::fs::exists(OutputFileName)) {
566 if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {
567 D.Diag(diag::err_drv_unable_to_remove_file) << EC.message();
572 const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath());
573 C.addCommand(std::make_unique<Command>(JA, *
this,
575 Exec, CmdArgs, Inputs, Output));
582 const char *LinkingOutput)
const {
583 ArgStringList CmdArgs;
586 const Driver &
D = getToolChain().getDriver();
587 const llvm::Triple::ArchType
Arch = TC.getArch();
588 const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
591 if (!
D.SysRoot.empty())
592 CmdArgs.push_back(Args.MakeArgString(
"--sysroot=" +
D.SysRoot));
594 CmdArgs.push_back(
"-Bstatic");
596 CmdArgs.push_back(
"-pie");
597 CmdArgs.push_back(
"--no-dynamic-linker");
598 CmdArgs.push_back(
"-z");
599 CmdArgs.push_back(
"text");
602 if (
const char *LDMOption =
getLDMOption(TC.getTriple(), Args)) {
603 CmdArgs.push_back(
"-m");
604 CmdArgs.push_back(LDMOption);
606 D.Diag(diag::err_target_unknown_triple) << Triple.str();
610 if (Triple.isRISCV()) {
611 CmdArgs.push_back(
"-X");
612 if (Args.hasArg(options::OPT_mno_relax))
613 CmdArgs.push_back(
"--no-relax");
616 if (Triple.isARM() || Triple.isThumb()) {
620 CmdArgs.push_back(IsBigEndian ?
"-EB" :
"-EL");
621 }
else if (Triple.isAArch64()) {
622 CmdArgs.push_back(
Arch == llvm::Triple::aarch64_be ?
"-EB" :
"-EL");
626 !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles);
628 const char *CRTBegin, *CRTEnd;
630 if (!Args.hasArg(options::OPT_r)) {
631 const char *crt =
"crt0.o";
634 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(crt)));
637 auto RuntimeLib = TC.GetRuntimeLibType(Args);
638 switch (RuntimeLib) {
640 CRTBegin = IsStaticPIE ?
"crtbeginS.o" :
"crtbegin.o";
641 CRTEnd = IsStaticPIE ?
"crtendS.o" :
"crtend.o";
652 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(CRTBegin)));
656 Args.addAllArgs(CmdArgs,
657 {options::OPT_L, options::OPT_u, options::OPT_T_Group,
658 options::OPT_s, options::OPT_t, options::OPT_r});
660 TC.AddFilePathLibArgs(Args, CmdArgs);
662 for (
const auto &LibPath : TC.getLibraryPaths())
663 CmdArgs.push_back(Args.MakeArgString(llvm::Twine(
"-L", LibPath)));
671 if (TC.ShouldLinkCXXStdlib(Args)) {
672 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
673 !Args.hasArg(options::OPT_static);
674 if (OnlyLibstdcxxStatic)
675 CmdArgs.push_back(
"-Bstatic");
676 TC.AddCXXStdlibLibArgs(Args, CmdArgs);
677 if (OnlyLibstdcxxStatic)
678 CmdArgs.push_back(
"-Bdynamic");
679 CmdArgs.push_back(
"-lm");
682 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
683 CmdArgs.push_back(
"--start-group");
685 if (!Args.hasArg(options::OPT_nolibc))
686 CmdArgs.push_back(
"-lc");
688 CmdArgs.push_back(
"-lgloss");
689 CmdArgs.push_back(
"--end-group");
694 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(CRTEnd)));
700 CmdArgs.push_back(
"--target2=rel");
702 CmdArgs.push_back(
"-o");
705 C.addCommand(std::make_unique<Command>(
707 Args.MakeArgString(TC.GetLinkerPath()), CmdArgs, Inputs, Output));
714 const bool IsX86_64 =
getTriple().getArch() == llvm::Triple::x86_64;
715 const bool IsAArch64 =
getTriple().getArch() == llvm::Triple::aarch64 ||
716 getTriple().getArch() == llvm::Triple::aarch64_be;
717 const bool IsRISCV64 =
getTriple().getArch() == llvm::Triple::riscv64;
719 Res |= SanitizerKind::Address;
720 Res |= SanitizerKind::KernelAddress;
721 Res |= SanitizerKind::PointerCompare;
722 Res |= SanitizerKind::PointerSubtract;
723 Res |= SanitizerKind::Fuzzer;
724 Res |= SanitizerKind::FuzzerNoLink;
725 Res |= SanitizerKind::Vptr;
726 Res |= SanitizerKind::SafeStack;
727 Res |= SanitizerKind::Thread;
728 Res |= SanitizerKind::Scudo;
729 if (IsX86_64 || IsAArch64 || IsRISCV64) {
730 Res |= SanitizerKind::HWAddress;
731 Res |= SanitizerKind::KernelHWAddress;
738 return MultilibMacroDefines;
llvm::MachO::Target Target
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
This corresponds to a single GCC multilib, or a segment of one controlled by a command line flag.
MultilibBuilder & flag(StringRef Flag, bool Disallow=false)
Add a flag to the flags list Flag must be a flag accepted by the driver.
This class can be used to create a MultilibSet, and contains helper functions to add combinations of ...
MultilibSetBuilder & Either(const MultilibBuilder &M1, const MultilibBuilder &M2)
Add a set of mutually incompatible Multilib segments.
MultilibSet makeMultilibSet() const
See also MultilibSetBuilder for combining multilibs into a set.
static llvm::ErrorOr< MultilibSet > parseYaml(llvm::MemoryBufferRef, llvm::SourceMgr::DiagHandlerTy=nullptr, void *DiagHandlerCtxt=nullptr)
const IncludeDirsFunc & filePathsCallback() const
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const std::string & getErrorMessage() const
const flags_list & flags() const
Get the flags that indicate or contraindicate this multilib's use All elements begin with either '-' ...
std::vector< std::string > flags_list
const std::string & includeSuffix() const
Get the include directory suffix.
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
static constexpr ResponseFileSupport AtFileCurCP()