Beispiel #1
0
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;
}
Beispiel #2
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;
}
Beispiel #3
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;
}