LLVM: lib/ToolDrivers/llvm-lib/LibDriver.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
33#include
34
35using namespace llvm;
37
38namespace {
39
40#define OPTTABLE_STR_TABLE_CODE
41#include "Options.inc"
42#undef OPTTABLE_STR_TABLE_CODE
43
44enum {
45 OPT_INVALID = 0,
46#define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),
47#include "Options.inc"
48#undef OPTION
49};
50
51#define OPTTABLE_PREFIXES_TABLE_CODE
52#include "Options.inc"
53#undef OPTTABLE_PREFIXES_TABLE_CODE
54
57#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
58#include "Options.inc"
59#undef OPTION
60};
61
63public:
64 LibOptTable()
65 : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable,
67};
68}
69
73 return std::string(Val);
74}
75
78 std::vector Ret;
79
80 Ret.push_back("");
81
82
83 for (auto *Arg : Args->filtered(OPT_libpath))
85
86
88 if (!EnvOpt)
89 return Ret;
91 while (!Env.empty()) {
93 std::tie(Path, Env) = Env.split(';');
94 Ret.push_back(Path);
95 }
96 return Ret;
97}
98
99
103
104 if (std::error_code EC = MB.getError()) {
105 llvm::errs() << "cannot open file " << Path << ": " << EC.message() << "\n";
106 return nullptr;
107 }
108
109 return std::move(*MB);
110}
111
117 return std::string(Path);
118 }
119 return "";
120}
121
123 if (!E)
124 return;
126 llvm::errs() << "error opening '" << File << "': " << EIB.message() << '\n';
127 exit(1);
128 });
129}
130
132
133 std::unique_ptr B;
134 for (auto *Arg : Args.filtered(OPT_INPUT)) {
135
137 Arg->getValue(), false, false);
139
141 B = std::move(MaybeBuf.get());
142 break;
143 }
144 }
145
146
147 if ()
148 return;
149
152 fatalOpenError(std::move(Err), B->getBufferIdentifier());
153
154 std::vector Names;
158 Names.push_back(NameOrErr.get());
159 }
162 fatalOpenError(std::move(Err), B->getBufferIdentifier());
163}
164
166 std::error_code EC;
168 if (!Obj)
169 return Obj.takeError();
170
177 "unknown machine: " + std::to_string(Machine));
178 }
179
181}
182
185 if (!TripleStr)
187
189 switch (T.getArch()) {
201 default:
203 "unknown arch in target triple: " + *TripleStr);
204 }
205}
206
209 if (LibMachine == FileMachine)
210 return true;
211
212
213 switch (LibMachine) {
220 default:
221 return false;
222 }
223}
224
225static void appendFile(std::vector &Members,
229
234 << ": not a COFF object, bitcode, archive, import library or "
235 "resource file\n";
236 exit(1);
237 }
238
239
240
241
242
247
250 if (!ChildMB) {
252 llvm::errs() << MB.getBufferIdentifier() << ": " << EIB.message()
253 << "\n";
254 });
255 exit(1);
256 }
257
258 appendFile(Members, LibMachine, LibMachineSource, *ChildMB);
259 }
260
262 return;
263 }
264
265
266
267
268
269
270
271
276 if (!MaybeFileMachine) {
279 llvm::errs() << MB.getBufferIdentifier() << ": "
280 << EIB.message() << "\n";
281 });
282 exit(1);
283 }
285
286
287
288
289
295 << " conflicts with inferred library machine type,"
296 << " use /machine:arm64ec or /machine:arm64x\n";
297 exit(1);
298 }
299 LibMachine = FileMachine;
300 LibMachineSource =
302 .str();
303 } else if ((LibMachine, FileMachine)) {
306 << " conflicts with library machine type "
307 << machineToStr(LibMachine) << LibMachineSource << '\n';
308 exit(1);
309 }
310 }
311 }
312
313 Members.emplace_back(MB);
314}
315
319
320
323 ArgsArr = NewArgs;
324
325 LibOptTable Table;
326 unsigned MissingIndex;
327 unsigned MissingCount;
329 Table.ParseArgs(ArgsArr.slice(1), MissingIndex, MissingCount);
330 if (MissingCount) {
331 llvm::errs() << "missing arg value for \""
332 << Args.getArgString(MissingIndex) << "\", expected "
333 << MissingCount
334 << (MissingCount == 1 ? " argument.\n" : " arguments.\n");
335 return 1;
336 }
337 for (auto *Arg : Args.filtered(OPT_UNKNOWN))
339 << "\n";
340
341
342 if (Args.hasArg(OPT_help)) {
343 Table.printHelp(outs(), "llvm-lib [options] file...", "LLVM Lib");
344 return 0;
345 }
346
347
349 for (auto *Arg : Args.filtered(OPT_ignore))
351
352
353 std::string OutputPath;
354 if (auto *Arg = Args.getLastArg(OPT_out)) {
356 }
357
359 std::string LibMachineSource;
360 if (auto *Arg = Args.getLastArg(OPT_machine)) {
364 return 1;
365 }
366 LibMachineSource =
367 std::string(" (from '/machine:") + Arg->getValue() + "' flag)";
368 }
369
370
371 if (Args.hasArg(OPT_deffile)) {
372
373 if (OutputPath.empty()) {
374 llvm::errs() << "no output path given\n";
375 return 1;
376 }
377
379 llvm::errs() << "/def option requires /machine to be specified" << '\n';
380 return 1;
381 }
382
383 std::unique_ptr MB =
384 openFile(Args.getLastArg(OPT_deffile)->getValue());
385 if (!MB)
386 return 1;
387
388 if (!MB->getBufferSize()) {
389 llvm::errs() << "definition file empty\n";
390 return 1;
391 }
392
395
396 if (!Def) {
397 llvm::errs() << "error parsing definition\n"
399 return 1;
400 }
401
402 std::vector NativeExports;
403 std::string OutputFile = Def->OutputFile;
404
405 if (isArm64EC(LibMachine) && Args.hasArg(OPT_nativedeffile)) {
406 std::unique_ptr NativeMB =
407 openFile(Args.getLastArg(OPT_nativedeffile)->getValue());
408 if (!NativeMB)
409 return 1;
410
411 if (!NativeMB->getBufferSize()) {
412 llvm::errs() << "native definition file empty\n";
413 return 1;
414 }
415
418
419 if (!NativeDef) {
420 llvm::errs() << "error parsing native definition\n"
422 return 1;
423 }
424 NativeExports = std::move(NativeDef->Exports);
425 OutputFile = std::move(NativeDef->OutputFile);
426 }
427
430 false, NativeExports)) {
433 });
434 return 1;
435 }
436 return 0;
437 }
438
439
440
441 if (!Args.hasArgNoClaim(OPT_INPUT) && !Args.hasArg(OPT_llvmlibempty)) {
442 if (!IgnoredWarnings.contains("emptyoutput")) {
443 llvm::errs() << "warning: no input files, not writing output file\n";
444 llvm::errs() << " pass /llvmlibempty to write empty .lib file,\n";
445 llvm::errs() << " pass /ignore:emptyoutput to suppress warning\n";
446 if (Args.hasFlag(OPT_WX, OPT_WX_no, false)) {
447 llvm::errs() << "treating warning as error due to /WX\n";
448 return 1;
449 }
450 }
451 return 0;
452 }
453
454 if (Args.hasArg(OPT_lst)) {
456 return 0;
457 }
458
459 std::vector SearchPaths = getSearchPaths(&Args, Saver);
460
461 std::vector<std::unique_ptr> MBs;
463 std::vector Members;
464
465
466 for (auto *Arg : Args.filtered(OPT_INPUT)) {
467
469 if (Path.empty()) {
471 return 1;
472 }
473
474
475
476
477
478
479
480
481 if (!Seen.insert(Path).second)
482 continue;
483
484
486 Path, false, false);
489
490
491 appendFile(Members, LibMachine, LibMachineSource, MBRef);
492
493
494 MBs.push_back(std::move(*MOrErr));
495 }
496
497
498 if (OutputPath.empty()) {
499 if (!Members.empty()) {
501 } else {
502 llvm::errs() << "no output path given, and cannot infer with no inputs\n";
503 return 1;
504 }
505 }
506
507 bool Thin = Args.hasArg(OPT_llvmlibthin);
508 if (Thin) {
513 if (PathOrErr)
514 Member.MemberName = Saver.save(*PathOrErr);
515 }
516 }
517 }
518
519
520 std::reverse(Members.begin(), Members.end());
521
522 auto Symtab = Args.hasFlag(OPT_llvmlibindex, OPT_llvmlibindex_no,
523 true)
524 ? SymtabWritingMode::NormalSymtab
525 : SymtabWritingMode::NoSymtab;
526
528 OutputPath, Members, Symtab,
530 true, Thin, nullptr, COFF::isArm64EC(LibMachine))) {
533 });
534 return 1;
535 }
536
537 return 0;
538}
Defines the llvm::Arg class for parsed arguments.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
COFF::MachineTypes Machine
static bool machineMatches(COFF::MachineTypes LibMachine, COFF::MachineTypes FileMachine)
static Expected< COFF::MachineTypes > getBitcodeFileMachine(MemoryBufferRef MB)
static Expected< COFF::MachineTypes > getCOFFFileMachine(MemoryBufferRef MB)
static std::string getDefaultOutputPath(const NewArchiveMember &FirstMember)
static std::string findInputFile(StringRef File, ArrayRef< StringRef > Paths)
static void doList(opt::InputArgList &Args)
static std::vector< StringRef > getSearchPaths(opt::InputArgList *Args, StringSaver &Saver)
std::unique_ptr< MemoryBuffer > openFile(const Twine &Path)
static void appendFile(std::vector< NewArchiveMember > &Members, COFF::MachineTypes &LibMachine, std::string &LibMachineSource, MemoryBufferRef MB)
static void fatalOpenError(llvm::Error E, Twine File)
Provides a library for accessing information about this process and other processes on the operating ...
StringSet - A set-like wrapper for the StringMap.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
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.
Allocate memory in an ever growing pool, as if by bump-pointer.
Base class for error info classes.
virtual std::string message() const
Return the error message as a string.
Represents either an error or a value T.
std::error_code getError() const
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
StringRef getBufferIdentifier() const
StringRef getBuffer() const
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
constexpr bool empty() const
empty - Check if the string is empty.
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
StringRef save(const char *S)
StringSet - A wrapper for StringMap that provides set-like functionality.
bool contains(StringRef key) const
Check if the set contains the given key.
std::pair< typename Base::iterator, bool > insert(StringRef key)
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
iterator_range< child_iterator > children(Error &Err, bool SkipInternal=true) const
static Expected< std::unique_ptr< COFFObjectFile > > create(MemoryBufferRef Object)
A concrete instance of a particular driver option.
std::string getAsString(const ArgList &Args) const
Return a formatted version of the argument and its values, for diagnostics.
const char * getValue(unsigned N=0) const
Specialization of OptTable.
static std::optional< std::string > GetEnv(StringRef name)
@ IMAGE_FILE_MACHINE_ARM64
@ IMAGE_FILE_MACHINE_UNKNOWN
@ IMAGE_FILE_MACHINE_AMD64
@ IMAGE_FILE_MACHINE_ARM64EC
@ IMAGE_FILE_MACHINE_R4000
@ IMAGE_FILE_MACHINE_I386
@ IMAGE_FILE_MACHINE_ARM64X
@ IMAGE_FILE_MACHINE_ARMNT
bool isAnyArm64(T Machine)
bool isArm64EC(T Machine)
@ C
The default llvm calling convention, compatible with C.
bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl< const char * > &Argv)
A convenience helper which supports the typical use case of expansion function call.
void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver, SmallVectorImpl< const char * > &NewArgv, bool MarkEOLs=false)
Tokenizes a string of Windows command line arguments, which may contain quotes and escaped quotes.
Expected< COFFModuleDefinition > parseCOFFModuleDefinition(MemoryBufferRef MB, COFF::MachineTypes Machine, bool MingwDef=false, bool AddUnderscores=true)
Error writeImportLibrary(StringRef ImportName, StringRef Path, ArrayRef< COFFShortExport > Exports, COFF::MachineTypes Machine, bool MinGW, ArrayRef< COFFShortExport > NativeExports={})
Writes a COFF import library containing entries described by the Exports array.
bool exists(const basic_file_status &status)
Does file exist?
void replace_extension(SmallVectorImpl< char > &path, const Twine &extension, Style style=Style::native)
Replace the file extension of path with extension.
bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
This is an optimization pass for GlobalISel generic memory operations.
file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
Error writeArchive(StringRef ArcName, ArrayRef< NewArchiveMember > NewMembers, SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr< MemoryBuffer > OldArchiveBuf=nullptr, std::optional< bool > IsEC=std::nullopt, function_ref< void(Error)> Warn=warnToStderr)
int libDriverMain(ArrayRef< const char * > ARgs)
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
Expected< std::string > getBitcodeTargetTriple(MemoryBufferRef Buffer)
Read the header of the specified bitcode buffer and extract just the triple information.
COFF::MachineTypes getMachineType(StringRef S)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
auto reverse(ContainerTy &&C)
StringRef machineToStr(COFF::MachineTypes MT)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Expected< std::string > computeArchiveRelativePath(StringRef From, StringRef To)
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
std::unique_ptr< MemoryBuffer > Buf
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...
@ coff_import_library
COFF import library.
@ archive
ar style archive file
@ windows_resource
Windows compiled resource file (.res)
@ coff_object
COFF object file.
Entry for a single option instance in the option data table.