LLVM  8.0.1
LibDriver.cpp
Go to the documentation of this 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 
16 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/Option/Arg.h"
20 #include "llvm/Option/ArgList.h"
21 #include "llvm/Option/Option.h"
23 #include "llvm/Support/Path.h"
24 #include "llvm/Support/Process.h"
27 
28 using namespace llvm;
29 
30 namespace {
31 
32 enum {
33  OPT_INVALID = 0,
34 #define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID,
35 #include "Options.inc"
36 #undef OPTION
37 };
38 
39 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
40 #include "Options.inc"
41 #undef PREFIX
42 
43 static const opt::OptTable::Info InfoTable[] = {
44 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
45  {X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \
46  X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
47 #include "Options.inc"
48 #undef OPTION
49 };
50 
51 class LibOptTable : public opt::OptTable {
52 public:
53  LibOptTable() : OptTable(InfoTable, true) {}
54 };
55 
56 }
57 
58 static std::string getOutputPath(opt::InputArgList *Args,
59  const NewArchiveMember &FirstMember) {
60  if (auto *Arg = Args->getLastArg(OPT_out))
61  return Arg->getValue();
62  SmallString<128> Val = StringRef(FirstMember.Buf->getBufferIdentifier());
63  sys::path::replace_extension(Val, ".lib");
64  return Val.str();
65 }
66 
67 static std::vector<StringRef> getSearchPaths(opt::InputArgList *Args,
68  StringSaver &Saver) {
69  std::vector<StringRef> Ret;
70  // Add current directory as first item of the search path.
71  Ret.push_back("");
72 
73  // Add /libpath flags.
74  for (auto *Arg : Args->filtered(OPT_libpath))
75  Ret.push_back(Arg->getValue());
76 
77  // Add $LIB.
79  if (!EnvOpt.hasValue())
80  return Ret;
81  StringRef Env = Saver.save(*EnvOpt);
82  while (!Env.empty()) {
83  StringRef Path;
84  std::tie(Path, Env) = Env.split(';');
85  Ret.push_back(Path);
86  }
87  return Ret;
88 }
89 
90 static std::string findInputFile(StringRef File, ArrayRef<StringRef> Paths) {
91  for (StringRef Dir : Paths) {
92  SmallString<128> Path = Dir;
93  sys::path::append(Path, File);
94  if (sys::fs::exists(Path))
95  return Path.str().str();
96  }
97  return "";
98 }
99 
101  BumpPtrAllocator Alloc;
102  StringSaver Saver(Alloc);
103 
104  // Parse command line arguments.
105  SmallVector<const char *, 20> NewArgs(ArgsArr.begin(), ArgsArr.end());
107  ArgsArr = NewArgs;
108 
109  LibOptTable Table;
110  unsigned MissingIndex;
111  unsigned MissingCount;
113  Table.ParseArgs(ArgsArr.slice(1), MissingIndex, MissingCount);
114  if (MissingCount) {
115  llvm::errs() << "missing arg value for \""
116  << Args.getArgString(MissingIndex) << "\", expected "
117  << MissingCount
118  << (MissingCount == 1 ? " argument.\n" : " arguments.\n");
119  return 1;
120  }
121  for (auto *Arg : Args.filtered(OPT_UNKNOWN))
122  llvm::errs() << "ignoring unknown argument: " << Arg->getSpelling() << "\n";
123 
124  // Handle /help
125  if (Args.hasArg(OPT_help)) {
126  Table.PrintHelp(outs(), "llvm-lib [options] file...", "LLVM Lib");
127  return 0;
128  }
129 
130  // If no input files, silently do nothing to match lib.exe.
131  if (!Args.hasArgNoClaim(OPT_INPUT))
132  return 0;
133 
134  std::vector<StringRef> SearchPaths = getSearchPaths(&Args, Saver);
135 
136  // Create a NewArchiveMember for each input file.
137  std::vector<NewArchiveMember> Members;
138  for (auto *Arg : Args.filtered(OPT_INPUT)) {
139  std::string Path = findInputFile(Arg->getValue(), SearchPaths);
140  if (Path.empty()) {
141  llvm::errs() << Arg->getValue() << ": no such file or directory\n";
142  return 1;
143  }
144 
146  NewArchiveMember::getFile(Saver.save(Path), /*Deterministic=*/true);
147  if (!MOrErr) {
148  handleAllErrors(MOrErr.takeError(), [&](const ErrorInfoBase &EIB) {
149  llvm::errs() << Arg->getValue() << ": " << EIB.message() << "\n";
150  });
151  return 1;
152  }
153 
154  file_magic Magic = identify_magic(MOrErr->Buf->getBuffer());
155  if (Magic != file_magic::coff_object && Magic != file_magic::bitcode &&
156  Magic != file_magic::windows_resource) {
157  llvm::errs() << Arg->getValue()
158  << ": not a COFF object, bitcode or resource file\n";
159  return 1;
160  }
161  Members.emplace_back(std::move(*MOrErr));
162  }
163 
164  // Create an archive file.
165  std::string OutputPath = getOutputPath(&Args, Members[0]);
166  if (Error E =
167  writeArchive(OutputPath, Members,
168  /*WriteSymtab=*/true, object::Archive::K_GNU,
169  /*Deterministic*/ true, Args.hasArg(OPT_llvmlibthin))) {
170  handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) {
171  llvm::errs() << OutputPath << ": " << EI.message() << "\n";
172  });
173  return 1;
174  }
175 
176  return 0;
177 }
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:228
This class represents lattice values for constants.
Definition: AllocatorList.h:24
iterator begin() const
Definition: ArrayRef.h:137
static std::string findInputFile(StringRef File, ArrayRef< StringRef > Paths)
Definition: LibDriver.cpp:90
Windows compiled resource file (.res)
Definition: Magic.h:47
virtual std::string message() const
Return the error message as a string.
Definition: Error.h:57
iterator_range< filtered_iterator< sizeof...(OptSpecifiers)> > filtered(OptSpecifiers ...Ids) const
Definition: ArgList.h:206
Error takeError()
Take ownership of the stored error.
Definition: Error.h:553
Base class for error info classes.
Definition: Error.h:49
Error writeArchive(StringRef ArcName, ArrayRef< NewArchiveMember > NewMembers, bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr< MemoryBuffer > OldArchiveBuf=nullptr)
Bitcode file.
Definition: Magic.h:24
const char * getArgString(unsigned Index) const override
getArgString - Return the input argument string at Index.
Definition: ArgList.h:410
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:480
file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
Definition: Magic.cpp:35
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver, SmallVectorImpl< const char *> &NewArgv, bool MarkEOLs=false)
Tokenizes a Windows command line which may contain quotes and escaped quotes.
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:267
static std::vector< StringRef > getSearchPaths(opt::InputArgList *Args, StringSaver &Saver)
Definition: LibDriver.cpp:67
bool hasArg(OptSpecifiers ...Ids) const
Definition: ArgList.h:245
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:133
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
raw_ostream & outs()
This returns a reference to a raw_ostream for standard output.
bool hasArgNoClaim(OptSpecifiers ...Ids) const
hasArg - Does the arg list contain any option matching Id.
Definition: ArgList.h:241
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:141
Provide access to the Option info table.
Definition: OptTable.h:39
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
int libDriverMain(ArrayRef< const char *> ARgs)
Definition: LibDriver.cpp:100
COFF object file.
Definition: Magic.h:44
Arg * getLastArg(OptSpecifiers ...Ids) const
Return the last argument matching Id, or null.
Definition: ArgList.h:251
static const char *const Magic
Definition: Archive.cpp:42
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition: Error.h:905
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
void replace_extension(SmallVectorImpl< char > &path, const Twine &extension, Style style=Style::native)
Replace the file extension of path with extension.
Definition: Path.cpp:505
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:727
iterator end() const
Definition: ArrayRef.h:138
StringRef save(const char *S)
Definition: StringSaver.h:29
Defines the llvm::Arg class for parsed arguments.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array...
Definition: ArrayRef.h:179
amdgpu Simplify well known AMD library false Value Value * Arg
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer...
Definition: StringSaver.h:22
bool hasValue() const
Definition: Optional.h:165
Provides a library for accessing information about this process and other processes on the operating ...
static std::string getOutputPath(opt::InputArgList *Args, const NewArchiveMember &FirstMember)
Definition: LibDriver.cpp:58
Entry for a single option instance in the option data table.
Definition: OptTable.h:42
static Expected< NewArchiveMember > getFile(StringRef FileName, bool Deterministic)
Lightweight error class with error context and mandatory checking.
Definition: Error.h:158
bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl< const char *> &Argv, bool MarkEOLs=false, bool RelativeNames=false)
Expand response files on a command line recursively using the given StringSaver and tokenization stra...
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
std::unique_ptr< MemoryBuffer > Buf
Definition: ArchiveWriter.h:25
bool exists(const basic_file_status &status)
Does file exist?
Definition: Path.cpp:1022
static Optional< std::string > GetEnv(StringRef name)
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...
Definition: Magic.h:21