LLVM  4.0.0
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"
18 #include "llvm/Option/Arg.h"
19 #include "llvm/Option/ArgList.h"
20 #include "llvm/Option/Option.h"
23 #include "llvm/Support/Path.h"
24 #include "llvm/Support/Process.h"
26 
27 using namespace llvm;
28 
29 namespace {
30 
31 enum {
32  OPT_INVALID = 0,
33 #define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11) OPT_##ID,
34 #include "Options.inc"
35 #undef OPTION
36 };
37 
38 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
39 #include "Options.inc"
40 #undef PREFIX
41 
42 static const llvm::opt::OptTable::Info infoTable[] = {
43 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X6, X7, X8, X9, X10) \
44  { \
45  X1, X2, X9, X10, OPT_##ID, llvm::opt::Option::KIND##Class, X8, X7, \
46  OPT_##GROUP, OPT_##ALIAS, X6 \
47  },
48 #include "Options.inc"
49 #undef OPTION
50 };
51 
52 class LibOptTable : public llvm::opt::OptTable {
53 public:
54  LibOptTable() : OptTable(infoTable, true) {}
55 };
56 
57 }
58 
60  const llvm::NewArchiveMember &FirstMember) {
61  if (auto *Arg = Args->getLastArg(OPT_out))
62  return Arg->getValue();
63  SmallString<128> Val = StringRef(FirstMember.Buf->getBufferIdentifier());
65  return Val.str();
66 }
67 
68 static std::vector<StringRef> getSearchPaths(llvm::opt::InputArgList *Args,
69  StringSaver &Saver) {
70  std::vector<StringRef> Ret;
71  // Add current directory as first item of the search path.
72  Ret.push_back("");
73 
74  // Add /libpath flags.
75  for (auto *Arg : Args->filtered(OPT_libpath))
76  Ret.push_back(Arg->getValue());
77 
78  // Add $LIB.
80  if (!EnvOpt.hasValue())
81  return Ret;
82  StringRef Env = Saver.save(*EnvOpt);
83  while (!Env.empty()) {
84  StringRef Path;
85  std::tie(Path, Env) = Env.split(';');
86  Ret.push_back(Path);
87  }
88  return Ret;
89 }
90 
92  ArrayRef<StringRef> Paths) {
93  for (auto Dir : Paths) {
94  SmallString<128> Path = Dir;
95  sys::path::append(Path, File);
96  if (sys::fs::exists(Path))
97  return Path.str().str();
98  }
99  return Optional<std::string>();
100 }
101 
103  SmallVector<const char *, 20> NewArgs(ArgsArr.begin(), ArgsArr.end());
104  BumpPtrAllocator Alloc;
105  StringSaver Saver(Alloc);
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  if (Args.filtered_begin(OPT_INPUT) == Args.filtered_end()) {
125  // No input files. To match lib.exe, silently do nothing.
126  return 0;
127  }
128 
129  std::vector<StringRef> SearchPaths = getSearchPaths(&Args, Saver);
130 
131  std::vector<llvm::NewArchiveMember> Members;
132  for (auto *Arg : Args.filtered(OPT_INPUT)) {
133  Optional<std::string> Path = findInputFile(Arg->getValue(), SearchPaths);
134  if (!Path.hasValue()) {
135  llvm::errs() << Arg->getValue() << ": no such file or directory\n";
136  return 1;
137  }
139  NewArchiveMember::getFile(Saver.save(*Path), /*Deterministic=*/true);
140  if (!MOrErr) {
141  handleAllErrors(MOrErr.takeError(), [&](const llvm::ErrorInfoBase &EIB) {
142  llvm::errs() << Arg->getValue() << ": " << EIB.message() << "\n";
143  });
144  return 1;
145  }
147  sys::fs::identify_magic(MOrErr->Buf->getBuffer());
148  if (Magic != sys::fs::file_magic::coff_object &&
149  Magic != sys::fs::file_magic::bitcode &&
151  llvm::errs() << Arg->getValue()
152  << ": not a COFF object, bitcode or resource file\n";
153  return 1;
154  }
155  Members.emplace_back(std::move(*MOrErr));
156  }
157 
158  std::pair<StringRef, std::error_code> Result =
159  llvm::writeArchive(getOutputPath(&Args, Members[0]), Members,
160  /*WriteSymtab=*/true, object::Archive::K_GNU,
161  /*Deterministic*/ true, Args.hasArg(OPT_llvmlibthin));
162 
163  if (Result.second) {
164  if (Result.first.empty())
165  Result.first = ArgsArr[0];
166  llvm::errs() << Result.first << ": " << Result.second.message() << "\n";
167  return 1;
168  }
169 
170  return 0;
171 }
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool hasValue() const
Definition: Optional.h:125
iterator end() const
Definition: ArrayRef.h:130
void replace_extension(SmallVectorImpl< char > &path, const Twine &extension)
Replace the file extension of path with extension.
Definition: Path.cpp:507
Error takeError()
Take ownership of the stored error.
Base class for error info classes.
Definition: Support/Error.h:46
const char * getArgString(unsigned Index) const override
getArgString - Return the input argument string at Index.
Definition: ArgList.h:357
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:171
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:448
std::pair< StringRef, std::error_code > writeArchive(StringRef ArcName, std::vector< NewArchiveMember > &NewMembers, bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr< MemoryBuffer > OldArchiveBuf=nullptr)
Tagged union holding either a T or a Error.
bool hasArg(OptSpecifier Id) const
Definition: ArgList.h:185
int libDriverMain(ArrayRef< const char * > ARgs)
Definition: LibDriver.cpp:102
Windows compiled resource file (.rc)
Definition: FileSystem.h:266
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
arg_iterator filtered_end() const
Definition: ArgList.h:158
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:138
static Optional< std::string > findInputFile(StringRef File, ArrayRef< StringRef > Paths)
Definition: LibDriver.cpp:91
Provide access to the Option info table.
Definition: OptTable.h:32
static std::string getOutputPath(llvm::opt::InputArgList *Args, const llvm::NewArchiveMember &FirstMember)
Definition: LibDriver.cpp:59
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.
iterator begin() const
Definition: ArrayRef.h:129
void handleAllErrors(Error E, HandlerTs &&...Handlers)
Behaves the same as handleErrors, except that it requires that all errors be handled by the given han...
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:225
iterator_range< arg_iterator > filtered(OptSpecifier Id0=0U, OptSpecifier Id1=0U, OptSpecifier Id2=0U) const
Definition: ArgList.h:162
static const char *const Magic
Definition: Archive.cpp:25
file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
Definition: Path.cpp:999
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
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...
static std::vector< StringRef > getSearchPaths(llvm::opt::InputArgList *Args, StringSaver &Saver)
Definition: LibDriver.cpp:68
StringRef save(const char *S)
Definition: StringSaver.h:26
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:267
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:716
Defines the llvm::Arg class for parsed arguments.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:130
Basic Alias true
Saves strings in the inheritor's stable storage and returns a StringRef with a stable character point...
Definition: StringSaver.h:21
Provides a library for accessing information about this process and other processes on the operating ...
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...
Definition: FileSystem.h:240
Entry for a single option instance in the option data table.
Definition: OptTable.h:35
Arg * getLastArg(OptSpecifier Id) const
Definition: ArgList.cpp:84
static Expected< NewArchiveMember > getFile(StringRef FileName, bool Deterministic)
arg_iterator filtered_begin(OptSpecifier Id0=0U, OptSpecifier Id1=0U, OptSpecifier Id2=0U) const
Definition: ArgList.h:154
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
bool exists(file_status status)
Does file exist?
Definition: Path.cpp:940
std::unique_ptr< MemoryBuffer > Buf
Definition: ArchiveWriter.h:24
static Optional< std::string > GetEnv(StringRef name)