[llvm-libtool-darwin] Add support for -V option

The -V option in cctools' libtool prints out the version number and
performs any specified operation. Add this option to LLVM's version.
cctools is more forgiving of invalid command lines when -V is specified,
but I think it's better to give errors instead of silently producing no
output.

Unfortunately, when -V is present, options that would otherwise be
required aren't anymore, so we need to perform some manual argument
validation.

Reviewed By: alexshap

Differential Revision: https://reviews.llvm.org/D86359
This commit is contained in:
Shoaib Meenai 2020-08-21 10:49:59 -07:00
parent d32d86bc38
commit 5c9a439cf0
4 changed files with 57 additions and 6 deletions

View File

@ -10,7 +10,7 @@
# RUN: not llvm-libtool-darwin -static %t.input 2>&1 | \
# RUN: FileCheck %s --check-prefix=NO-OUTPUT
# NO-OUTPUT: for the -o option: must be specified at least once!
# NO-OUTPUT: for the -o option: must be specified
## Missing argument to -o:
# RUN: not llvm-libtool-darwin -static %t.input -o 2>&1 | \
@ -22,7 +22,7 @@
# RUN: not llvm-libtool-darwin -static %t.input -o %t.lib1 -o %t.lib2 2>&1 | \
# RUN: FileCheck %s --check-prefix=DOUBLE-OUTPUT
# DOUBLE-OUTPUT: for the -o option: must occur exactly one time!
# DOUBLE-OUTPUT: for the -o option: may only occur zero or one times!
## Input file not found:
# RUN: not llvm-libtool-darwin -static -o %t.lib %t.missing 2>&1 | \

View File

@ -2,4 +2,4 @@
# RUN: not llvm-libtool-darwin -o %t.lib %t.input 2>&1 | \
# RUN: FileCheck %s --check-prefix=MISSING-OPERATION
# MISSING-OPERATION: Library Type: option: must be specified at least once!
# MISSING-OPERATION: Library Type: option: must be specified

View File

@ -0,0 +1,25 @@
## Test the -V flag, which prints the version number to stdout. It also allows
## for no operation to be specified, but if an operation is specified, it should
## still occur and regular argument parsing errors should be surfaced (unlike
## cctools libtool, which silences all argument parsing errors when -V is
## specified).
## Test -V by itself
# RUN: llvm-libtool-darwin -V | FileCheck %s
## The specific version number, vendor string, etc. will differ across
## environments, so this is the most specific we can get.
# CHECK: LLVM version
## Parsing errors should not be surfaced when no operation is specified
# RUN: llvm-libtool-darwin -V -D -U | FileCheck %s
## Regular errors should occur when an operation is specified
# RUN: not llvm-libtool-darwin -V -static 2>&1 | FileCheck --check-prefix=ERROR %s
# ERROR: for the -o option: must be specified
## A valid command line should print the version and perform the operation
# RUN: yaml2obj %S/Inputs/input1.yaml -o %t-input1.o
# RUN: yaml2obj %S/Inputs/input2.yaml -o %t-input2.o
# RUN: llvm-libtool-darwin -static -o %t.lib %t-input1.o %t-input2.o -V | FileCheck %s
# RUN: llvm-libtool-darwin -static -o %t2.lib %t-input1.o %t-input2.o
# RUN: cmp %t.lib %t2.lib

View File

@ -32,7 +32,7 @@ typedef std::map<uint64_t, std::vector<NewArchiveMember>>
cl::OptionCategory LibtoolCategory("llvm-libtool-darwin Options");
static cl::opt<std::string> OutputFile("o", cl::desc("Specify output filename"),
cl::value_desc("filename"), cl::Required,
cl::value_desc("filename"),
cl::cat(LibtoolCategory));
static cl::list<std::string> InputFiles(cl::Positional,
@ -44,14 +44,14 @@ static cl::opt<std::string> ArchType(
"arch_only", cl::desc("Specify architecture type for output library"),
cl::value_desc("arch_type"), cl::ZeroOrMore, cl::cat(LibtoolCategory));
enum class Operation { Static };
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::Required, cl::cat(LibtoolCategory));
cl::init(Operation::None), cl::cat(LibtoolCategory));
static cl::opt<bool> DeterministicOption(
"D", cl::desc("Use zero for timestamps and UIDs/GIDs (Default)"),
@ -81,6 +81,10 @@ static cl::list<std::string> LibrarySearchDirs(
" libraries"),
cl::ZeroOrMore, cl::Prefix, cl::cat(LibtoolCategory));
static cl::opt<bool>
VersionOption("V", cl::desc("Print the version number and exit"),
cl::cat(LibtoolCategory));
static const std::array<std::string, 3> StandardSearchDirs{
"/lib",
"/usr/lib",
@ -444,6 +448,23 @@ static Expected<Config> parseCommandLine(int Argc, char **Argv) {
Config C;
cl::ParseCommandLineOptions(Argc, Argv, "llvm-libtool-darwin\n");
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 C;
}
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());
}
if (DeterministicOption && NonDeterministicOption)
return createStringError(std::errc::invalid_argument,
"cannot specify both -D and -U flags");
@ -483,8 +504,13 @@ int main(int Argc, char **Argv) {
return EXIT_FAILURE;
}
if (VersionOption)
cl::PrintVersionMessage();
Config C = *ConfigOrErr;
switch (LibraryOperation) {
case Operation::None:
break;
case Operation::Static:
if (Error E = createStaticLibrary(C)) {
WithColor::defaultErrorHandler(std::move(E));