This is an archive of the discontinued LLVM Phabricator instance.

[llvm-ar] Support multiple dashed options
ClosedPublic

Authored by thomasanderson on Mar 13 2018, 5:20 PM.

Details

Summary

This allows syntax like:
$ llvm-ar -c -r -u file.a file.o

This is in addition to the other formats that are already supported:
$ llvm-ar cru file.a file.o
$ llvm-ar -cru file.a file.o

Diff Detail

Repository
rL LLVM

Event Timeline

thomasanderson created this revision.Mar 13 2018, 5:20 PM

pinging pcc (thakis is OOO)

pcc added a comment.Mar 21 2018, 7:17 PM

Did you consider writing a custom parser as was mentioned on the bug? It really seems like it would make the code better rather than going through these contortions to fit the parsing into llvm::cl.

tools/llvm-ar/llvm-ar.cpp
922 ↗(On Diff #138280)

Note that GNU allows more than one.

pcc added inline comments.Mar 21 2018, 7:18 PM
tools/llvm-ar/llvm-ar.cpp
106 ↗(On Diff #138280)

It would be a shame to lose this usage information.

tools/llvm-ar/llvm-ar.cpp
106 ↗(On Diff #138280)

It's still there. llvm-ar --help now looks like this:
OVERVIEW: LLVM Archiver (llvm-ar)

This program archives bitcode files into single libraries

USAGE: llvm-ar [options] [relpos] [count] <archive-file> [members]...

OPTIONS:

General options:

-M                                - 
-aarch64-neon-syntax              - Choose style of NEON code to emit from AArch64 backend:
  =generic                        -   Emit generic NEON assembly
  =apple                          -   Emit Apple-style NEON assembly
-arm-add-build-attributes         - 
-arm-implicit-it                  - Allow conditional instructions outdside of an IT block
  =always                         -   Accept in both ISAs, emit implicit ITs in Thumb
  =never                          -   Warn in ARM, reject in Thumb
  =arm                            -   Accept in ARM, reject in Thumb
  =thumb                          -   Warn in ARM, emit implicit ITs in Thumb
-enable-packed-inlinable-literals - Enable packed inlinable literals (v2f16, v2i16)
-format                           - Archive format to create
  =default                        -   default
  =gnu                            -   gnu
  =darwin                         -   darwin
  =bsd                            -   bsd
-gpsize=<uint>                    - Global Pointer Addressing Size.  The default size is 8.
-merror-missing-parenthesis       - Error for missing parenthesis around predicate registers
-merror-noncontigious-register    - Error for register names that aren't contigious
-mhvx                             - Enable Hexagon Vector eXtensions
  =v60                            -   Build for HVX v60
  =v62                            -   Build for HVX v62
  =v65                            -   Build for HVX v65
  =                               -   
-mno-compound                     - Disable looking for compound instructions for Hexagon
-mno-fixup                        - Disable fixing up resolved relocations for Hexagon
-mno-pairing                      - Disable looking for duplex instructions for Hexagon
-mwarn-missing-parenthesis        - Warn for missing parenthesis around predicate registers
-mwarn-noncontigious-register     - Warn for register names that arent contigious
-mwarn-sign-mismatch              - Warn for mismatching a signed and unsigned value
-plugin=<string>                  - plugin (ignored for compatibility)
-print-module-scope               - When printing IR for print-[before|after]{-all} always print a module IR

Generic Options:

-help                             - Display available options (-help-hidden for more)
-help-list                        - Display list of available options (-help-list-hidden for more)
-version                          - Display the version of this program

Modifiers (generic):

-c                                - do not warn if the library had to be created
-v                                - be verbose about actions taken

Modifiers (operation specific):

-S                                - do not build a symbol table
-T                                - create a thin archive
-a                                - put file(s) after [relpos]
-b                                - put file(s) before [relpos] (same as [i])
-i                                - put file(s) before [relpos] (same as [b])
-o                                - preserve original dates
-s                                - create an archive index (cf. ranlib)
-u                                - update only files newer than archive contents

Operations:

-d                                - delete file(s) from the archive
-m                                - move file(s) in the archive
-p                                - print file(s) found in the archive
-q                                - append file(s) to the archive
-r                                - replace or insert file(s) into the archive
-t                                - display contents of archive
-x                                - extract file(s) from the archive

Unless you mean the [NsS] on "d" etc. We could add that back in the description if you want.

922 ↗(On Diff #138280)

Ack

In D44452#1045304, @pcc wrote:

Did you consider writing a custom parser as was mentioned on the bug? It really seems like it would make the code better rather than going through these contortions to fit the parsing into llvm::cl.

Yeah, but there's still a lot of general options

-M -
-aarch64-neon-syntax - Choose style of NEON code to emit from AArch64 backend:

=generic                        -   Emit generic NEON assembly
=apple                          -   Emit Apple-style NEON assembly

-arm-add-build-attributes -
-arm-implicit-it - Allow conditional instructions outdside of an IT block

=always                         -   Accept in both ISAs, emit implicit ITs in Thumb
=never                          -   Warn in ARM, reject in Thumb
=arm                            -   Accept in ARM, reject in Thumb
=thumb                          -   Warn in ARM, emit implicit ITs in Thumb

-enable-packed-inlinable-literals - Enable packed inlinable literals (v2f16, v2i16)
-format - Archive format to create

=default                        -   default
=gnu                            -   gnu
=darwin                         -   darwin
=bsd                            -   bsd

-gpsize=<uint> - Global Pointer Addressing Size. The default size is 8.
-merror-missing-parenthesis - Error for missing parenthesis around predicate registers
-merror-noncontigious-register - Error for register names that aren't contigious
-mhvx - Enable Hexagon Vector eXtensions

=v60                            -   Build for HVX v60
=v62                            -   Build for HVX v62
=v65                            -   Build for HVX v65
=                               -

-mno-compound - Disable looking for compound instructions for Hexagon
-mno-fixup - Disable fixing up resolved relocations for Hexagon
-mno-pairing - Disable looking for duplex instructions for Hexagon
-mwarn-missing-parenthesis - Warn for missing parenthesis around predicate registers
-mwarn-noncontigious-register - Warn for register names that arent contigious
-mwarn-sign-mismatch - Warn for mismatching a signed and unsigned value
-plugin=<string> - plugin (ignored for compatibility)
-print-module-scope - When printing IR for print-[before|after]{-all} always print a module IR

I feel like it's easier just to use llvm::cl directly.

pcc added a comment.Mar 22 2018, 10:51 AM

Yeah, but there's still a lot of general options

Most of those options are irrelevant to llvm-ar and should not appear in its help output. The ones that we care about are --format, -M and --plugin, and we can easily parse them ourselves.

In D44452#1045867, @pcc wrote:

Yeah, but there's still a lot of general options

Most of those options are irrelevant to llvm-ar and should not appear in its help output. The ones that we care about are --format, -M and --plugin, and we can easily parse them ourselves.

Ah, that's a good point. If you think it's worth it, I can give the custom parser a try

pcc added a comment.Mar 22 2018, 11:00 AM
In D44452#1045867, @pcc wrote:

Yeah, but there's still a lot of general options

Most of those options are irrelevant to llvm-ar and should not appear in its help output. The ones that we care about are --format, -M and --plugin, and we can easily parse them ourselves.

Ah, that's a good point. If you think it's worth it, I can give the custom parser a try

Please do, at least so that we have a point of comparison.

In D44452#1045877, @pcc wrote:
In D44452#1045867, @pcc wrote:

Yeah, but there's still a lot of general options

Most of those options are irrelevant to llvm-ar and should not appear in its help output. The ones that we care about are --format, -M and --plugin, and we can easily parse them ourselves.

Ah, that's a good point. If you think it's worth it, I can give the custom parser a try

Please do, at least so that we have a point of comparison.

Done in latest revision

Don't land this yet, I'm getting some errors when building Chromium

pcc added inline comments.Mar 22 2018, 6:34 PM
tools/llvm-ar/llvm-ar.cpp
63 ↗(On Diff #139540)

I would lose the "Gener*ptions" headers (here and below), they aren't really providing much information.

893 ↗(On Diff #139540)

No else after return

924 ↗(On Diff #139540)

No else after return

925 ↗(On Diff #139540)

It seems like you should be able to add the remaining arguments to PositionalArgs and break out of the loop, that way the rest of the code doesn't need to worry about it.

936 ↗(On Diff #139540)

Move the parsing of the format type here and use a StringSwitch.

945 ↗(On Diff #139540)

It seems that the correct check here is Options.empty().

thomasanderson marked 6 inline comments as done.

Chrome builds now -- it was an issue with not handling response files

pcc added a comment.Mar 23 2018, 4:55 PM

Looking mostly good.

tools/llvm-ar/llvm-ar.cpp
888 ↗(On Diff #139630)

No else after return.

931 ↗(On Diff #139630)

It looks like this needs to happen before parsing the arguments.

971 ↗(On Diff #139630)

If you move this if statement above line 967, we can remove the check for ranlib from that line.

thomasanderson marked 3 inline comments as done.
pcc accepted this revision.Mar 23 2018, 6:45 PM

LGTM with a few nits. Thanks for working on this.

tools/llvm-ar/llvm-ar.cpp
876 ↗(On Diff #139681)

Can you initialize this vector like this: SmallVector<const char *, 0> Argv(argv, argv + argc);

884 ↗(On Diff #139681)

Is this possible?

This revision is now accepted and ready to land.Mar 23 2018, 6:45 PM
thomasanderson marked an inline comment as done.
thomasanderson marked an inline comment as done.

Also you'll have to land this for me, since I don't have write permissions in the repo

pcc added a comment.Mar 26 2018, 4:16 PM

It looks like the following tests started failing with your change:

LLVM :: Object/archive-GNU64-write.test
LLVM :: Object/mri5.test

Can you please take a look?

In D44452#1048772, @pcc wrote:

It looks like the following tests started failing with your change:

LLVM :: Object/archive-GNU64-write.test
LLVM :: Object/mri5.test

Can you please take a look?

Sure, looking now

Fixed test failures

pcc added inline comments.Mar 26 2018, 6:35 PM
lib/Object/ArchiveWriter.cpp
456 ↗(On Diff #139870)

This parameter was intentionally not exposed by the writeArchive interface because it is for testing purposes only. Probably the easiest thing to do to keep it that way would be to arrange to pass it using an environment variable.

Use environment variable for Object/archive-GNU64-write.test

pcc added a comment.Mar 28 2018, 10:24 AM

r328716

Thanks!

This revision was automatically updated to reflect the committed changes.
thakis added inline comments.Apr 3 2018, 7:54 PM
llvm/trunk/tools/llvm-ar/llvm-ar.cpp
55

This includes a newline at the start of the string, which makes the -help output look a bit weird.

thomasanderson added inline comments.Apr 4 2018, 3:31 PM
llvm/trunk/tools/llvm-ar/llvm-ar.cpp
55

D'oh!

IMO the cleanest way to do this is to replace
const char RanlibHelp[] = R"(
with
const char *RanlibHelp = 1 + R"(

It would be a bit superfluous for me to upload a new CL to fix this considering someone with write permissions in the repo would have to land it for me.