aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp')
-rw-r--r--llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp200
1 files changed, 112 insertions, 88 deletions
diff --git a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
index 3357afb..c0f64a2 100644
--- a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
+++ b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
@@ -19,12 +19,15 @@
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/MachOUniversalWriter.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/WithColor.h"
+#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TextAPI/Architecture.h"
#include <map>
@@ -32,83 +35,64 @@
using namespace llvm;
using namespace llvm::object;
+using namespace llvm::opt;
+
+// Command-line option boilerplate.
+namespace {
+enum ID {
+ OPT_INVALID = 0, // This is not an option ID.
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ OPT_##ID,
+#include "Opts.inc"
+#undef OPTION
+};
-class NewArchiveMemberList;
-typedef std::map<uint64_t, NewArchiveMemberList> MembersPerArchitectureMap;
-
-cl::OptionCategory LibtoolCategory("llvm-libtool-darwin Options");
+#define PREFIX(NAME, VALUE) \
+ static constexpr StringLiteral NAME##_init[] = VALUE; \
+ static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
+ std::size(NAME##_init) - 1);
+#include "Opts.inc"
+#undef PREFIX
+
+static constexpr opt::OptTable::Info InfoTable[] = {
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ { \
+ PREFIX, NAME, HELPTEXT, \
+ METAVAR, OPT_##ID, opt::Option::KIND##Class, \
+ PARAM, FLAGS, OPT_##GROUP, \
+ OPT_##ALIAS, ALIASARGS, VALUES},
+#include "Opts.inc"
+#undef OPTION
+};
-static cl::opt<std::string> OutputFile("o", cl::desc("Specify output filename"),
- cl::value_desc("filename"),
- cl::cat(LibtoolCategory));
+class LibtoolDarwinOptTable : public opt::GenericOptTable {
+public:
+ LibtoolDarwinOptTable() : GenericOptTable(InfoTable) {}
+};
+} // end anonymous namespace
-static cl::list<std::string> InputFiles(cl::Positional,
- cl::desc("<input files>"),
- cl::cat(LibtoolCategory));
+class NewArchiveMemberList;
+typedef std::map<uint64_t, NewArchiveMemberList> MembersPerArchitectureMap;
-static cl::opt<std::string>
- ArchType("arch_only",
- cl::desc("Specify architecture type for output library"),
- cl::value_desc("arch_type"), cl::cat(LibtoolCategory));
+static std::string OutputFile;
+static std::vector<std::string> InputFiles;
+static std::optional<std::string> ArchType;
enum class Operation { None, Static };
-
-static cl::opt<Operation> LibraryOperation(
- cl::desc("Library Type: "),
- cl::values(
- clEnumValN(Operation::Static, "static",
- "Produce a statically linked library from the input files")),
- cl::init(Operation::None), cl::cat(LibtoolCategory));
-
-static cl::opt<bool> DeterministicOption(
- "D", cl::desc("Use zero for timestamps and UIDs/GIDs (Default)"),
- cl::init(false), cl::cat(LibtoolCategory));
-
-static cl::opt<bool>
- NonDeterministicOption("U", cl::desc("Use actual timestamps and UIDs/GIDs"),
- cl::init(false), cl::cat(LibtoolCategory));
-
-static cl::opt<std::string>
- FileList("filelist",
- cl::desc("Pass in file containing a list of filenames"),
- cl::value_desc("listfile[,dirname]"), cl::cat(LibtoolCategory));
-
-static cl::list<std::string> Libraries(
- "l",
- cl::desc(
- "l<x> searches for the library libx.a in the library search path. If"
- " the string 'x' ends with '.o', then the library 'x' is searched for"
- " without prepending 'lib' or appending '.a'"),
- cl::Prefix, cl::cat(LibtoolCategory));
-
-static cl::list<std::string> LibrarySearchDirs(
- "L",
- cl::desc(
- "L<dir> adds <dir> to the list of directories in which to search for"
- " libraries"),
- cl::Prefix, cl::cat(LibtoolCategory));
-
-static cl::opt<std::string> DependencyInfoPath(
- "dependency_info",
- cl::desc("Write an Xcode dependency info file describing the dependencies "
- "of the created library"),
- cl::cat(LibtoolCategory));
-
-static cl::opt<bool>
- VersionOption("V", cl::desc("Print the version number and exit"),
- cl::cat(LibtoolCategory));
-
-static cl::opt<bool> NoWarningForNoSymbols(
- "no_warning_for_no_symbols",
- cl::desc("Do not warn about files that have no symbols"),
- cl::cat(LibtoolCategory), cl::init(false));
-
-static cl::opt<bool> WarningsAsErrors("warnings_as_errors",
- cl::desc("Treat warnings as errors"),
- cl::cat(LibtoolCategory),
- cl::init(false));
-
-static cl::opt<std::string> IgnoredSyslibRoot("syslibroot", cl::Hidden);
+static Operation LibraryOperation = Operation::None;
+
+static bool DeterministicOption;
+static bool NonDeterministicOption;
+static std::string FileList;
+static std::vector<std::string> Libraries;
+static std::vector<std::string> LibrarySearchDirs;
+static std::string DependencyInfoPath;
+static bool VersionOption;
+static bool NoWarningForNoSymbols;
+static bool WarningsAsErrors;
+static std::string IgnoredSyslibRoot;
static const std::array<std::string, 3> StandardSearchDirs{
"/lib",
@@ -288,14 +272,15 @@ public:
if (Error E = AddMember(*this, FileName)())
return std::move(E);
- if (!ArchType.empty()) {
+ std::string Arch = ArchType.value_or("");
+ if (!Arch.empty()) {
uint64_t ArchCPUID = getCPUID(C.ArchCPUType, C.ArchCPUSubtype);
if (Data.MembersPerArchitecture.find(ArchCPUID) ==
Data.MembersPerArchitecture.end())
return createStringError(std::errc::invalid_argument,
"no library created (no object files in input "
"files matching -arch_only %s)",
- ArchType.c_str());
+ Arch.c_str());
}
return std::move(Data);
}
@@ -383,7 +368,7 @@ private:
// If -arch_only is specified then skip this file if it doesn't match
// the architecture specified.
- if (!ArchType.empty() && !acceptFileArch(FileCPUType, FileCPUSubtype)) {
+ if (ArchType && !acceptFileArch(FileCPUType, FileCPUSubtype)) {
return Error::success();
}
@@ -426,7 +411,7 @@ private:
// If -arch_only is specified then skip this file if it doesn't match
// the architecture specified.
- if (!ArchType.empty() &&
+ if (ArchType &&
!acceptFileArch(*FileCPUTypeOrErr, *FileCPUSubTypeOrErr)) {
return Error::success();
}
@@ -649,16 +634,58 @@ static Error createStaticLibrary(LLVMContext &LLVMCtx, const Config &C) {
return writeUniversalBinary(*Slices, OutputFile);
}
+static void parseRawArgs(int Argc, char **Argv) {
+ LibtoolDarwinOptTable Tbl;
+ llvm::BumpPtrAllocator A;
+ llvm::StringSaver Saver{A};
+ opt::InputArgList Args =
+ Tbl.parseArgs(Argc, Argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {
+ llvm::errs() << Msg << '\n';
+ std::exit(1);
+ });
+
+ if (Args.hasArg(OPT_help)) {
+ Tbl.printHelp(llvm::outs(), "llvm-libtool-darwin [options] <input files>",
+ "llvm-libtool-darwin");
+ std::exit(0);
+ }
+
+ InputFiles = Args.getAllArgValues(OPT_INPUT);
+ Libraries = Args.getAllArgValues(OPT_libraries);
+ LibrarySearchDirs = Args.getAllArgValues(OPT_librarySearchDirs);
+
+ if (const opt::Arg *A = Args.getLastArg(OPT_outputFile))
+ OutputFile = A->getValue();
+
+ if (const opt::Arg *A = Args.getLastArg(OPT_archType))
+ ArchType = std::make_optional(A->getValue());
+
+ if (const opt::Arg *A = Args.getLastArg(OPT_fileList))
+ FileList = A->getValue();
+
+ if (const opt::Arg *A = Args.getLastArg(OPT_dependencyInfoPath))
+ DependencyInfoPath = A->getValue();
+
+ if (const opt::Arg *A = Args.getLastArg(OPT_ignoredSyslibRoot))
+ IgnoredSyslibRoot = A->getValue();
+
+ LibraryOperation =
+ Args.hasArg(OPT_static) ? Operation::Static : Operation::None;
+ DeterministicOption = Args.hasArg(OPT_deterministicOption);
+ NonDeterministicOption = Args.hasArg(OPT_nonDeterministicOption);
+ VersionOption = Args.hasArg(OPT_version);
+ NoWarningForNoSymbols = Args.hasArg(OPT_noWarningForNoSymbols);
+ WarningsAsErrors = Args.hasArg(OPT_warningsAsErrors);
+}
+
static Expected<Config> parseCommandLine(int Argc, char **Argv) {
Config C;
- cl::ParseCommandLineOptions(Argc, Argv, "llvm-libtool-darwin\n");
+ parseRawArgs(Argc, Argv);
if (LibraryOperation == Operation::None) {
if (!VersionOption) {
- std::string Error;
- raw_string_ostream Stream(Error);
- LibraryOperation.error("must be specified", "", Stream);
- return createStringError(std::errc::invalid_argument, Error.c_str());
+ return createStringError(std::errc::invalid_argument,
+ "-static option: must be specified");
}
return C;
}
@@ -669,10 +696,8 @@ static Expected<Config> parseCommandLine(int Argc, char **Argv) {
: std::make_unique<DependencyInfo>(DependencyInfoPath);
if (OutputFile.empty()) {
- std::string Error;
- raw_string_ostream Stream(Error);
- OutputFile.error("must be specified", "o", Stream);
- return createStringError(std::errc::invalid_argument, Error.c_str());
+ return createStringError(std::errc::invalid_argument,
+ "-o option: must be specified");
}
if (DeterministicOption && NonDeterministicOption)
@@ -693,13 +718,13 @@ static Expected<Config> parseCommandLine(int Argc, char **Argv) {
return createStringError(std::errc::invalid_argument,
"no input files specified");
- if (ArchType.getNumOccurrences()) {
- if (Error E = validateArchitectureName(ArchType))
+ if (ArchType) {
+ if (Error E = validateArchitectureName(ArchType.value()))
return std::move(E);
std::tie(C.ArchCPUType, C.ArchCPUSubtype) =
MachO::getCPUTypeFromArchitecture(
- MachO::getArchitectureFromName(ArchType));
+ MachO::getArchitectureFromName(ArchType.value()));
}
GlobalDependencyInfo->write("llvm-libtool-darwin " LLVM_VERSION_STRING,
@@ -710,7 +735,6 @@ static Expected<Config> parseCommandLine(int Argc, char **Argv) {
int main(int Argc, char **Argv) {
InitLLVM X(Argc, Argv);
- cl::HideUnrelatedOptions({&LibtoolCategory, &getColorCategory()});
Expected<Config> ConfigOrErr = parseCommandLine(Argc, Argv);
if (!ConfigOrErr) {
WithColor::defaultErrorHandler(ConfigOrErr.takeError());