LLVM  3.7.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-link2 /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, llvm::array_lengthof(infoTable), true) {}
55 };
56 
57 }
58 
59 static std::string getOutputPath(llvm::opt::InputArgList *Args,
60  const llvm::NewArchiveIterator &FirstMember) {
61  if (auto *Arg = Args->getLastArg(OPT_out))
62  return Arg->getValue();
63  SmallString<128> Val = FirstMember.getNew();
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  BumpPtrStringSaver 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  llvm::errs() << "no input files.\n";
126  return 1;
127  }
128 
129  std::vector<StringRef> SearchPaths = getSearchPaths(&Args, Saver);
130 
131  std::vector<llvm::NewArchiveIterator> 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  }
138  Members.emplace_back(Saver.save(*Path),
139  llvm::sys::path::filename(Arg->getValue()));
140  }
141 
142  std::pair<StringRef, std::error_code> Result =
143  llvm::writeArchive(getOutputPath(&Args, Members[0]), Members,
144  /*WriteSymtab=*/true, object::Archive::K_GNU,
145  /*Deterministic*/ true);
146 
147  if (Result.second) {
148  if (Result.first.empty())
149  Result.first = ArgsArr[0];
150  llvm::errs() << Result.first << ": " << Result.second.message() << "\n";
151  return 1;
152  }
153 
154  return 0;
155 }
std::pair< StringRef, std::error_code > writeArchive(StringRef ArcName, std::vector< NewArchiveIterator > &NewMembers, bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic)
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:123
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:450
void replace_extension(SmallVectorImpl< char > &path, const Twine &extension)
Replace the file extension of path with extension.
Definition: Path.cpp:504
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:188
bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl< const char * > &Argv, bool MarkEOLs=false)
Expand response files on a command line recursively using the given StringSaver and tokenization stra...
const char * getArgString(unsigned Index) const override
getArgString - Return the input argument string at Index.
Definition: ArgList.h:347
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:443
int libDriverMain(llvm::ArrayRef< const char * > ARgs)
Definition: LibDriver.cpp:102
ArrayRef< T > slice(unsigned N) const
slice(n) - Chop off the first N elements of the array.
Definition: ArrayRef.h:165
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: ArrayRef.h:31
LLVM_CONSTEXPR size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:247
StringRef filename(StringRef path)
Get filename.
Definition: Path.cpp:548
#define true
Definition: ConvertUTF.c:66
arg_iterator filtered_end() const
Definition: ArgList.h:158
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:135
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
const char * save(const char *S)
Definition: StringSaver.h:28
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:122
iterator_range< arg_iterator > filtered(OptSpecifier Id0=0U, OptSpecifier Id1=0U, OptSpecifier Id2=0U) const
Definition: ArgList.h:162
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
static std::vector< StringRef > getSearchPaths(llvm::opt::InputArgList *Args, StringSaver &Saver)
Definition: LibDriver.cpp:68
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:267
Defines the llvm::Arg class for parsed arguments.
Saves strings in the inheritor's stable storage and returns a stable raw character pointer...
Definition: StringSaver.h:21
Provides a library for accessing information about this process and other processes on the operating ...
Entry for a single option instance in the option data table.
Definition: OptTable.h:35
Arg * getLastArg(OptSpecifier Id) const
Definition: ArgList.cpp:83
StringRef getNew() const
static std::string getOutputPath(llvm::opt::InputArgList *Args, const llvm::NewArchiveIterator &FirstMember)
Definition: LibDriver.cpp:59
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:40
bool exists(file_status status)
Does file exist?
Definition: Path.cpp:845
static Optional< std::string > GetEnv(StringRef name)
bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:110