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;
56 return Triple.isX86() && Triple.getOS() == llvm::Triple::UnknownOS &&
57 Triple.getEnvironmentName() ==
"elf";
61 const llvm::Triple &TargetTriple,
67 if (TargetTriple.isRISCV64()) {
71 .
flag(
"-march=rv64imafdc")
76 (
Arch ==
"rv64imafdc") || (
Arch ==
"rv64gc");
85 return Result.Multilibs.select(D, Flags, Result.SelectedMultilibs);
87 if (TargetTriple.isRISCV32()) {
94 .
flag(
"-march=rv32im")
97 .
flag(
"-march=rv32iac")
100 .
flag(
"-march=rv32imafc")
101 .
flag(
"-mabi=ilp32f");
104 bool UseI = (
Arch ==
"rv32i") || (
Arch ==
"rv32ic");
105 bool UseIm = (
Arch ==
"rv32im") || (
Arch ==
"rv32imc");
106 bool UseImafc = (
Arch ==
"rv32imafc") || (
Arch ==
"rv32imafdc") ||
119 return Result.Multilibs.select(D, Flags, Result.SelectedMultilibs);
125 bool IncludeTriple) {
130 llvm::sys::path::append(SysRootDir,
"..",
"lib",
"clang-runtimes");
135 return std::string(SysRootDir);
142 const llvm::opt::ArgList &Args) {
143 if (Args.getLastArg(options::OPT_gcc_toolchain) ||
144 Args.getLastArg(clang::options::OPT_gcc_install_dir_EQ)) {
159 return llvm::sys::fs::exists(GCCDir);
173 if (!SysRoot.empty())
179 if (!D.SysRoot.empty())
185 if (IsGCCInstallationValid) {
186 llvm::sys::path::append(inferredSysRoot,
GCCInstallation.getParentLibPath(),
191 llvm::sys::path::append(inferredSysRoot, D.Dir,
"..", D.getTargetTriple());
194 if (!inferredSysRoot.empty() && llvm::sys::fs::exists(inferredSysRoot))
195 return std::string(inferredSysRoot);
205 llvm::sys::path::append(Path,
"lib");
206 return std::string(Path.str());
213 StringRef InstallPath,
216 for (
const auto &Path : PathsCallback(
Multilib))
229 if (IsGCCInstallationValid) {
231 D.Diag(clang::diag::warn_drv_multilib_not_available_for_target);
243 Paths.push_back(ComputedSysRoot +
"/lib");
251 PPaths.push_back((
GCCInstallation.getParentLibPath() +
"/../bin").str());
256 if (!SysRootDir.empty()) {
257 for (
const Multilib &M : getOrderedMultilibs()) {
259 llvm::sys::path::append(Dir, M.osSuffix(),
"lib");
269 StringRef MultilibPath,
const ArgList &Args,
272 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MB =
273 D.
getVFS().getBufferForFile(MultilibPath);
277 llvm::ErrorOr<MultilibSet> ErrorOrMultilibSet =
279 if (ErrorOrMultilibSet.getError())
281 Result.Multilibs = ErrorOrMultilibSet.get();
282 if (Result.Multilibs.select(D, Flags, Result.SelectedMultilibs,
283 &CustomFlagsMacroDefines))
285 D.
Diag(clang::diag::warn_drv_missing_multilib) << llvm::join(Flags,
" ");
286 std::stringstream ss;
293 D.
Diag(clang::diag::note_drv_available_multilibs) << ss.str();
302 D.
Diag(clang::diag::err_drv_multilib_custom_error)
307 Result.SelectedMultilibs.clear();
312static std::optional<llvm::SmallString<128>>
314 const ArgList &Args) {
316 if (Arg *ConfigFileArg = Args.getLastArg(options::OPT_multi_lib_config)) {
317 MultilibPath = ConfigFileArg->getValue();
318 if (!D.
getVFS().exists(MultilibPath)) {
319 D.
Diag(clang::diag::err_drv_no_such_file) << MultilibPath.str();
330 const ArgList &Args) {
334 std::optional<llvm::SmallString<128>> MultilibPath =
338 if (D.getVFS().exists(*MultilibPath)) {
344 CustomFlagMacroDefines);
347 MultilibMacroDefines.append(CustomFlagMacroDefines.begin(),
348 CustomFlagMacroDefines.end());
371BareMetal::OrderedMultilibs BareMetal::getOrderedMultilibs()
const {
382 if (
getTriple().isRISCV() && IsGCCInstallationValid)
388 if (
getTriple().isRISCV() && IsGCCInstallationValid)
404 ArgStringList &CC1Args)
const {
405 if (DriverArgs.hasArg(options::OPT_nostdinc))
408 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
410 llvm::sys::path::append(Dir,
"include");
414 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
423 if (!SysRootDir.empty()) {
424 for (
const Multilib &M : getOrderedMultilibs()) {
426 llvm::sys::path::append(Dir, M.includeSuffix());
427 llvm::sys::path::append(Dir,
"include");
432 if (D.getVFS().exists(Dir)) {
433 llvm::sys::path::append(Dir,
"include");
440 ArgStringList &CC1Args,
442 CC1Args.push_back(
"-nostdsysteminc");
446 const llvm::opt::ArgList &DriverArgs,
447 llvm::opt::ArgStringList &CC1Args)
const {
448 if (!IsGCCInstallationValid)
459 ArgStringList &CC1Args)
const {
460 if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
461 options::OPT_nostdincxx))
467 auto AddCXXIncludePath = [&](StringRef Path) {
475 llvm::sys::path::append(TargetDir,
Target,
"c++", Version);
482 llvm::sys::path::append(Dir,
"c++", Version);
490 llvm::sys::path::append(P,
"..",
"include");
491 AddCXXIncludePath(P);
500 if (SysRootDir.empty())
503 for (
const Multilib &M : getOrderedMultilibs()) {
505 llvm::sys::path::append(Dir, M.gccSuffix());
510 llvm::sys::path::append(TargetDir,
"usr",
"include",
"c++",
"v1");
511 if (D.getVFS().exists(TargetDir)) {
516 llvm::sys::path::append(Dir,
"include",
"c++",
"v1");
521 llvm::sys::path::append(Dir,
"include",
"c++");
525 for (llvm::vfs::directory_iterator
526 LI = D.getVFS().dir_begin(Dir.str(), EC),
528 !EC && LI != LE; LI = LI.increment(EC)) {
529 StringRef VersionText = llvm::sys::path::filename(LI->path());
531 if (CandidateVersion.Major == -1)
533 if (CandidateVersion <= Version)
535 Version = CandidateVersion;
537 if (Version.
Major != -1) {
538 llvm::sys::path::append(Dir, Version.
Text);
548 llvm::sys::path::append(Dir,
Target,
"include",
"c++",
"v1");
549 if (D.getVFS().exists(Dir))
562 const char *LinkingOutput)
const {
566 Args.ClaimAllArgs(options::OPT_g_Group);
568 Args.ClaimAllArgs(options::OPT_emit_llvm);
571 Args.ClaimAllArgs(options::OPT_w);
573 Args.ClaimAllArgs(options::OPT_stdlib_EQ);
576 ArgStringList CmdArgs;
578 CmdArgs.push_back(
"rcsD");
581 for (
const auto &II : Inputs) {
582 if (II.isFilename()) {
583 CmdArgs.push_back(II.getFilename());
590 if (Output.
isFilename() && llvm::sys::fs::exists(OutputFileName)) {
591 if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) {
592 D.
Diag(diag::err_drv_unable_to_remove_file) << EC.message();
597 const char *Exec = Args.MakeArgString(
getToolChain().GetStaticLibToolPath());
598 C.addCommand(std::make_unique<Command>(JA, *
this,
600 Exec, CmdArgs, Inputs, Output));
607 const char *LinkingOutput)
const {
608 ArgStringList CmdArgs;
612 const llvm::Triple::ArchType
Arch = TC.getArch();
613 const llvm::Triple &Triple =
getToolChain().getEffectiveTriple();
617 CmdArgs.push_back(Args.MakeArgString(
"--sysroot=" + D.
SysRoot));
619 CmdArgs.push_back(
"-Bstatic");
621 CmdArgs.push_back(
"-pie");
622 CmdArgs.push_back(
"--no-dynamic-linker");
623 CmdArgs.push_back(
"-z");
624 CmdArgs.push_back(
"text");
627 if (
const char *LDMOption =
getLDMOption(TC.getTriple(), Args)) {
628 CmdArgs.push_back(
"-m");
629 CmdArgs.push_back(LDMOption);
631 D.
Diag(diag::err_target_unknown_triple) << Triple.str();
635 if (Triple.isRISCV()) {
636 CmdArgs.push_back(
"-X");
637 if (Args.hasArg(options::OPT_mno_relax))
638 CmdArgs.push_back(
"--no-relax");
641 if (Triple.isARM() || Triple.isThumb()) {
645 CmdArgs.push_back(IsBigEndian ?
"-EB" :
"-EL");
646 }
else if (Triple.isAArch64()) {
647 CmdArgs.push_back(
Arch == llvm::Triple::aarch64_be ?
"-EB" :
"-EL");
651 !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles);
653 const char *CRTBegin, *CRTEnd;
655 if (!Args.hasArg(options::OPT_r)) {
656 const char *crt =
"crt0.o";
659 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(crt)));
662 auto RuntimeLib = TC.GetRuntimeLibType(Args);
663 switch (RuntimeLib) {
665 CRTBegin = IsStaticPIE ?
"crtbeginS.o" :
"crtbegin.o";
666 CRTEnd = IsStaticPIE ?
"crtendS.o" :
"crtend.o";
677 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(CRTBegin)));
681 Args.addAllArgs(CmdArgs, {options::OPT_L});
682 TC.AddFilePathLibArgs(Args, CmdArgs);
683 Args.addAllArgs(CmdArgs, {options::OPT_u, options::OPT_T_Group,
684 options::OPT_s, options::OPT_t, options::OPT_r});
686 for (
const auto &LibPath : TC.getLibraryPaths())
687 CmdArgs.push_back(Args.MakeArgString(llvm::Twine(
"-L", LibPath)));
695 if (TC.ShouldLinkCXXStdlib(Args)) {
696 bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
697 !Args.hasArg(options::OPT_static);
698 if (OnlyLibstdcxxStatic)
699 CmdArgs.push_back(
"-Bstatic");
700 TC.AddCXXStdlibLibArgs(Args, CmdArgs);
701 if (OnlyLibstdcxxStatic)
702 CmdArgs.push_back(
"-Bdynamic");
703 CmdArgs.push_back(
"-lm");
706 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
707 CmdArgs.push_back(
"--start-group");
709 if (!Args.hasArg(options::OPT_nolibc))
710 CmdArgs.push_back(
"-lc");
712 CmdArgs.push_back(
"-lgloss");
713 CmdArgs.push_back(
"--end-group");
718 CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(CRTEnd)));
724 CmdArgs.push_back(
"--target2=rel");
726 CmdArgs.push_back(
"-o");
729 C.addCommand(std::make_unique<Command>(
731 Args.MakeArgString(TC.GetLinkerPath()), CmdArgs, Inputs, Output));
738 const bool IsX86_64 =
getTriple().getArch() == llvm::Triple::x86_64;
739 const bool IsAArch64 =
getTriple().getArch() == llvm::Triple::aarch64 ||
740 getTriple().getArch() == llvm::Triple::aarch64_be;
741 const bool IsRISCV64 =
getTriple().isRISCV64();
743 Res |= SanitizerKind::Address;
744 Res |= SanitizerKind::KernelAddress;
745 Res |= SanitizerKind::PointerCompare;
746 Res |= SanitizerKind::PointerSubtract;
747 Res |= SanitizerKind::Fuzzer;
748 Res |= SanitizerKind::FuzzerNoLink;
749 Res |= SanitizerKind::Vptr;
750 Res |= SanitizerKind::SafeStack;
751 Res |= SanitizerKind::Thread;
752 Res |= SanitizerKind::Scudo;
753 if (IsX86_64 || IsAArch64 || IsRISCV64) {
754 Res |= SanitizerKind::HWAddress;
755 Res |= SanitizerKind::KernelHWAddress;
762 return MultilibMacroDefines;
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...
std::string SysRoot
sysroot, if present
DiagnosticBuilder Diag(unsigned DiagID) const
llvm::vfs::FileSystem & getVFS() const
std::string Dir
The path the driver executable was in, as invoked from the command line.
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
std::string getTargetTriple() const
LTOKind getLTOMode() const
Get the specific kind of LTO being performed.
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.
SmallVector< InputInfo, 4 > InputInfoList
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()