PageRenderTime 21ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/LibDriver/LibDriver.cpp

https://gitlab.com/Birhetia/platform_external_llvm
C++ | 154 lines | 117 code | 21 blank | 16 comment | 15 complexity | 631bd7e7db9d9db8e7594f608d38eefe MD5 | raw file
  1. //===- LibDriver.cpp - lib.exe-compatible driver --------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // Defines an interface to a lib.exe-compatible driver that also understands
  11. // bitcode files. Used by llvm-lib and lld-link /lib.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "llvm/LibDriver/LibDriver.h"
  15. #include "llvm/ADT/STLExtras.h"
  16. #include "llvm/Object/ArchiveWriter.h"
  17. #include "llvm/Option/Arg.h"
  18. #include "llvm/Option/ArgList.h"
  19. #include "llvm/Option/Option.h"
  20. #include "llvm/Support/CommandLine.h"
  21. #include "llvm/Support/StringSaver.h"
  22. #include "llvm/Support/Path.h"
  23. #include "llvm/Support/Process.h"
  24. #include "llvm/Support/raw_ostream.h"
  25. using namespace llvm;
  26. namespace {
  27. enum {
  28. OPT_INVALID = 0,
  29. #define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11) OPT_##ID,
  30. #include "Options.inc"
  31. #undef OPTION
  32. };
  33. #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
  34. #include "Options.inc"
  35. #undef PREFIX
  36. static const llvm::opt::OptTable::Info infoTable[] = {
  37. #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X6, X7, X8, X9, X10) \
  38. { \
  39. X1, X2, X9, X10, OPT_##ID, llvm::opt::Option::KIND##Class, X8, X7, \
  40. OPT_##GROUP, OPT_##ALIAS, X6 \
  41. },
  42. #include "Options.inc"
  43. #undef OPTION
  44. };
  45. class LibOptTable : public llvm::opt::OptTable {
  46. public:
  47. LibOptTable() : OptTable(infoTable, true) {}
  48. };
  49. }
  50. static std::string getOutputPath(llvm::opt::InputArgList *Args,
  51. const llvm::NewArchiveIterator &FirstMember) {
  52. if (auto *Arg = Args->getLastArg(OPT_out))
  53. return Arg->getValue();
  54. SmallString<128> Val = FirstMember.getNew();
  55. llvm::sys::path::replace_extension(Val, ".lib");
  56. return Val.str();
  57. }
  58. static std::vector<StringRef> getSearchPaths(llvm::opt::InputArgList *Args,
  59. StringSaver &Saver) {
  60. std::vector<StringRef> Ret;
  61. // Add current directory as first item of the search path.
  62. Ret.push_back("");
  63. // Add /libpath flags.
  64. for (auto *Arg : Args->filtered(OPT_libpath))
  65. Ret.push_back(Arg->getValue());
  66. // Add $LIB.
  67. Optional<std::string> EnvOpt = sys::Process::GetEnv("LIB");
  68. if (!EnvOpt.hasValue())
  69. return Ret;
  70. StringRef Env = Saver.save(*EnvOpt);
  71. while (!Env.empty()) {
  72. StringRef Path;
  73. std::tie(Path, Env) = Env.split(';');
  74. Ret.push_back(Path);
  75. }
  76. return Ret;
  77. }
  78. static Optional<std::string> findInputFile(StringRef File,
  79. ArrayRef<StringRef> Paths) {
  80. for (auto Dir : Paths) {
  81. SmallString<128> Path = Dir;
  82. sys::path::append(Path, File);
  83. if (sys::fs::exists(Path))
  84. return Path.str().str();
  85. }
  86. return Optional<std::string>();
  87. }
  88. int llvm::libDriverMain(llvm::ArrayRef<const char*> ArgsArr) {
  89. SmallVector<const char *, 20> NewArgs(ArgsArr.begin(), ArgsArr.end());
  90. BumpPtrAllocator Alloc;
  91. StringSaver Saver(Alloc);
  92. cl::ExpandResponseFiles(Saver, cl::TokenizeWindowsCommandLine, NewArgs);
  93. ArgsArr = NewArgs;
  94. LibOptTable Table;
  95. unsigned MissingIndex;
  96. unsigned MissingCount;
  97. llvm::opt::InputArgList Args =
  98. Table.ParseArgs(ArgsArr.slice(1), MissingIndex, MissingCount);
  99. if (MissingCount) {
  100. llvm::errs() << "missing arg value for \""
  101. << Args.getArgString(MissingIndex) << "\", expected "
  102. << MissingCount
  103. << (MissingCount == 1 ? " argument.\n" : " arguments.\n");
  104. return 1;
  105. }
  106. for (auto *Arg : Args.filtered(OPT_UNKNOWN))
  107. llvm::errs() << "ignoring unknown argument: " << Arg->getSpelling() << "\n";
  108. if (Args.filtered_begin(OPT_INPUT) == Args.filtered_end()) {
  109. llvm::errs() << "no input files.\n";
  110. return 1;
  111. }
  112. std::vector<StringRef> SearchPaths = getSearchPaths(&Args, Saver);
  113. std::vector<llvm::NewArchiveIterator> Members;
  114. for (auto *Arg : Args.filtered(OPT_INPUT)) {
  115. Optional<std::string> Path = findInputFile(Arg->getValue(), SearchPaths);
  116. if (!Path.hasValue()) {
  117. llvm::errs() << Arg->getValue() << ": no such file or directory\n";
  118. return 1;
  119. }
  120. Members.emplace_back(Saver.save(*Path));
  121. }
  122. std::pair<StringRef, std::error_code> Result =
  123. llvm::writeArchive(getOutputPath(&Args, Members[0]), Members,
  124. /*WriteSymtab=*/true, object::Archive::K_GNU,
  125. /*Deterministic*/ true, Args.hasArg(OPT_llvmlibthin));
  126. if (Result.second) {
  127. if (Result.first.empty())
  128. Result.first = ArgsArr[0];
  129. llvm::errs() << Result.first << ": " << Result.second.message() << "\n";
  130. return 1;
  131. }
  132. return 0;
  133. }