25

I have two proto files inside single directory and I am looking for a way to generate classes from those files in a single command. It seems that this can be accomplished with the --proto_path argument. As per the documentation:

You must provide one or more .proto files as input. Multiple .proto files can be specified at once. Although the files are named relative to the current directory, each file must reside in one of the IMPORT_PATHs [specified by the --proto_path argument] so that the compiler can determine its canonical name.

C:\shekhar\proto_trial>dir
 Volume in drive C is C

 Directory of C:\shekhar\proto_trial

07/25/2014  12:16 PM    <DIR>          .
07/25/2014  12:16 PM    <DIR>          ..
07/25/2014  12:16 PM    <DIR>          java_op
07/25/2014  12:16 PM               230 map.proto
07/23/2014  04:24 PM               161 message.proto
07/25/2014  12:17 PM             1,228 response.proto
               3 File(s)          1,619 bytes
               3 Dir(s)  50,259,398,656 bytes free

I used --proto_path argument as shown below

C:\shekhar\proto_trial>protoc 
                       --proto_path=C:\shekhar\proto_trial 
                       --java_out=C:\shekhar\proto_trial\java_op 
                       *.proto

but I am getting following error

message.proto: File does not reside within any path specified using --proto_path (or -I). 
You must specify a --proto_path which encompasses this file. 
Note that the proto_path must be an exact prefix of the .proto file names -- protoc is unable to figure out when two paths (e.g. absolute and relative) are equivalent (it's harder than you think).

Please suggest some way to compile all the proto files together in single shot.

Shekhar
  • 11,438
  • 36
  • 130
  • 186
  • See https://developers.google.com/protocol-buffers/docs/proto#generating about what the `--proto_path` is used for. The flag that instructs protoc which files to compile is actually just the @filename argument. `--proto_path` is for where to look in order to resolve imports. – Yehuda Makarov Sep 04 '20 at 02:43

7 Answers7

34

Here's an option using find

protoc --js_out=js \
        -Iproto/ \
        $(find proto/google -iname "*.proto")
Cosmin Lehene
  • 787
  • 8
  • 13
  • 4
    This should be the correct answer because all the related `.proto` files need to run with the same command in order for the directories to be correct, if there are sub-directories of `.proto` files. – Dave Mar 30 '19 at 02:10
30

The problem is that you are specifying --proto_path as an absolute path but your proto files as relative paths. You can either drop the --proto_path argument (it defaults to the current directory anyway), or you can do:

protoc --proto_path=C:\shekhar\proto_trial
       --java_out=C:\shekhar\proto_trial\java_op
       C:\shekhar\proto_trial\*.proto
Kenton Varda
  • 41,353
  • 8
  • 121
  • 105
  • 3
    It doesn't work: /main/resources/proto/*.proto: Invalid argument The only solution I found is to add every files one by one on the same line. – Samoht Aug 21 '15 at 08:35
  • 1
    @Samoht It is the shell's responsibility to expand globs (`*`). If you are running the command through a context that doesn't invoke a shell, you may need to expand globs manually. – Kenton Varda Aug 22 '15 at 02:55
  • 1
    It's the shell's responsibility to expand globs _on Unix_. On Windows, it's up to the program receiving the glob. Also, fwiw, I'm running the latest Windows protoc as of 2018-06-19, and protoc does not seem to understand (or make any attempt to expand) globs. – William Jun 19 '18 at 20:41
  • Doh. I guess protoc forgot to link with setargv.obj. That's quite possibly my fault (though not something I have the power to fix anymore). – Kenton Varda Jun 19 '18 at 21:32
  • 1
    Does not work for me on Windows. `protoc` does not recognize *.proto wildcard at `cdm`. – Maxim Zhukov May 17 '19 at 20:36
  • @Kenton I have absolutely no problem compiling a single proto file using all relative directories. But as soon as I replace the file name with *, I get no such file or directory :( – Saeed Nov 08 '19 at 18:29
  • 1
    @Saeed Yes, as described earlier in this thread, this appears to be a bug in the Windows version of protoc. – Kenton Varda Nov 08 '19 at 23:14
6

Commands for Protobuf >= 3.5

It seems to me that the normal command on Windows only worked for Protobuf <= 3.4, and in the newer versions you cannot use the wildcard * but you have to put all the filenames separately. Fortunately it's still easy using a for loop (from here), using relative directories:

for /f %i in ('dir /b proto_trial\*.proto') do protoc proto_trial\%i --java_out=proto_trial\java_op

Alternatively, from here, you could also try to use Git Bash if you have it installed as it could expand the wildcard properly, and then use the command as you have before:

protoc proto_trial\*.proto --java_out=proto_trial\java_op
PHPirate
  • 7,023
  • 7
  • 48
  • 84
1

Download the windows version of the compiler from this link https://github.com/google/protobuf/releases/tag/v3.3.0

Start command prompt from bin folder of the downloaded application. Use the potoc command to generate the classes.

    protoc --proto_path=<Directory name where your proto file is residing> 
           --java_out=<Directory name where you want your output classes to get generated> 
           <absolute path of your protofile with extention>

Use wild character * for multiple protofiles

sa_penguin
  • 459
  • 5
  • 15
1

find . -name "*.proto" | xargs -I {} protoc "{}"

hetal
  • 329
  • 2
  • 5
1

for mac:

protoc --dart_out=grpc:../lib/client **/*.proto
VIPLIKE
  • 146
  • 5
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/34069489) – bramhaag Mar 23 '23 at 20:10
0

Simplest way:

protoc C:\shekhar\proto_trial\*.proto --java_out=C:\shekhar\proto_trial\java_op
Syscall
  • 19,327
  • 10
  • 37
  • 52