int llvm::libDriverMain(llvm::ArrayRef<const char*> ArgsArr) { SmallVector<const char *, 20> NewArgs(ArgsArr.begin(), ArgsArr.end()); BumpPtrAllocator Alloc; BumpPtrStringSaver Saver(Alloc); cl::ExpandResponseFiles(Saver, cl::TokenizeWindowsCommandLine, NewArgs); ArgsArr = NewArgs; LibOptTable Table; unsigned MissingIndex; unsigned MissingCount; llvm::opt::InputArgList Args = Table.ParseArgs(ArgsArr.slice(1), MissingIndex, MissingCount); if (MissingCount) { llvm::errs() << "missing arg value for \"" << Args.getArgString(MissingIndex) << "\", expected " << MissingCount << (MissingCount == 1 ? " argument.\n" : " arguments.\n"); return 1; } for (auto *Arg : Args.filtered(OPT_UNKNOWN)) llvm::errs() << "ignoring unknown argument: " << Arg->getSpelling() << "\n"; if (Args.filtered_begin(OPT_INPUT) == Args.filtered_end()) { llvm::errs() << "no input files.\n"; return 1; } std::vector<StringRef> SearchPaths = getSearchPaths(&Args, Saver); std::vector<llvm::NewArchiveIterator> Members; for (auto *Arg : Args.filtered(OPT_INPUT)) { Optional<std::string> Path = findInputFile(Arg->getValue(), SearchPaths); if (!Path.hasValue()) { llvm::errs() << Arg->getValue() << ": no such file or directory\n"; return 1; } Members.emplace_back(Saver.save(*Path), llvm::sys::path::filename(Arg->getValue())); } std::pair<StringRef, std::error_code> Result = llvm::writeArchive(getOutputPath(&Args, Members[0]), Members, /*WriteSymtab=*/true, object::Archive::K_GNU, /*Deterministic*/ true, /*Thin*/ false); if (Result.second) { if (Result.first.empty()) Result.first = ArgsArr[0]; llvm::errs() << Result.first << ": " << Result.second.message() << "\n"; return 1; } return 0; }
int llvm::libDriverMain(int Argc, const char **Argv) { SmallVector<const char *, 20> NewArgv(Argv, Argv + Argc); BumpPtrAllocator Alloc; BumpPtrStringSaver Saver(Alloc); cl::ExpandResponseFiles(Saver, cl::TokenizeWindowsCommandLine, NewArgv); Argv = &NewArgv[0]; Argc = static_cast<int>(NewArgv.size()); LibOptTable Table; unsigned MissingIndex; unsigned MissingCount; std::unique_ptr<llvm::opt::InputArgList> Args( Table.ParseArgs(&Argv[1], &Argv[Argc], MissingIndex, MissingCount)); if (MissingCount) { llvm::errs() << "missing arg value for \"" << Args->getArgString(MissingIndex) << "\", expected " << MissingCount << (MissingCount == 1 ? " argument.\n" : " arguments.\n"); return 1; } for (auto *Arg : Args->filtered(OPT_UNKNOWN)) llvm::errs() << "ignoring unknown argument: " << Arg->getSpelling() << "\n"; if (Args->filtered_begin(OPT_INPUT) == Args->filtered_end()) { llvm::errs() << "no input files.\n"; return 1; } std::vector<llvm::NewArchiveIterator> Members; for (auto *Arg : Args->filtered(OPT_INPUT)) Members.emplace_back(Arg->getValue(), llvm::sys::path::filename(Arg->getValue())); std::pair<StringRef, std::error_code> Result = llvm::writeArchive( getOutputPath(Args.get()), Members, /*WriteSymtab=*/true); if (Result.second) { if (Result.first.empty()) Result.first = Argv[0]; llvm::errs() << Result.first << ": " << Result.second.message() << "\n"; return 1; } return 0; }
int llvm::libDriverMain(ArrayRef<const char *> ArgsArr) { BumpPtrAllocator Alloc; StringSaver Saver(Alloc); // Parse command line arguments. SmallVector<const char *, 20> NewArgs(ArgsArr.begin(), ArgsArr.end()); cl::ExpandResponseFiles(Saver, cl::TokenizeWindowsCommandLine, NewArgs); ArgsArr = NewArgs; LibOptTable Table; unsigned MissingIndex; unsigned MissingCount; opt::InputArgList Args = Table.ParseArgs(ArgsArr.slice(1), MissingIndex, MissingCount); if (MissingCount) { llvm::errs() << "missing arg value for \"" << Args.getArgString(MissingIndex) << "\", expected " << MissingCount << (MissingCount == 1 ? " argument.\n" : " arguments.\n"); return 1; } for (auto *Arg : Args.filtered(OPT_UNKNOWN)) llvm::errs() << "ignoring unknown argument: " << Arg->getSpelling() << "\n"; // Handle /help if (Args.hasArg(OPT_help)) { Table.PrintHelp(outs(), "llvm-lib [options] file...", "LLVM Lib"); return 0; } // If no input files, silently do nothing to match lib.exe. if (!Args.hasArgNoClaim(OPT_INPUT)) return 0; if (Args.hasArg(OPT_lst)) { doList(Args); return 0; } std::vector<StringRef> SearchPaths = getSearchPaths(&Args, Saver); // Create a NewArchiveMember for each input file. std::vector<NewArchiveMember> Members; for (auto *Arg : Args.filtered(OPT_INPUT)) { std::string Path = findInputFile(Arg->getValue(), SearchPaths); if (Path.empty()) { llvm::errs() << Arg->getValue() << ": no such file or directory\n"; return 1; } Expected<NewArchiveMember> MOrErr = NewArchiveMember::getFile(Saver.save(Path), /*Deterministic=*/true); if (!MOrErr) { handleAllErrors(MOrErr.takeError(), [&](const ErrorInfoBase &EIB) { llvm::errs() << Arg->getValue() << ": " << EIB.message() << "\n"; }); return 1; } file_magic Magic = identify_magic(MOrErr->Buf->getBuffer()); if (Magic != file_magic::coff_object && Magic != file_magic::bitcode && Magic != file_magic::windows_resource) { llvm::errs() << Arg->getValue() << ": not a COFF object, bitcode or resource file\n"; return 1; } Members.emplace_back(std::move(*MOrErr)); } // Create an archive file. std::string OutputPath = getOutputPath(&Args, Members[0]); // llvm-lib uses relative paths for both regular and thin archives, unlike // standard GNU ar, which only uses relative paths for thin archives and // basenames for regular archives. for (NewArchiveMember &Member : Members) Member.MemberName = Saver.save(computeArchiveRelativePath(OutputPath, Member.MemberName)); if (Error E = writeArchive(OutputPath, Members, /*WriteSymtab=*/true, object::Archive::K_GNU, /*Deterministic*/ true, Args.hasArg(OPT_llvmlibthin))) { handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) { llvm::errs() << OutputPath << ": " << EI.message() << "\n"; }); return 1; } return 0; }