Solving protoc-gen-go: unable to determine Go import path problem by adding a "M" argument
Asked Answered
S

3

8

Same symptom as protoc-gen-go: unable to determine Go import path for "simple.proto"

For simple proto file with following content.

syntax="proto3";

package main;

message Person {
      string name = 1;
      int32 age = 2; 
}

I am trying to generate go code for it using protoc. I run:

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative simple.proto

I receive following error:

protoc-gen-go: unable to determine Go import path for "simple.proto"

Please specify either:
        • a "go_package" option in the .proto source file, or
        • a "M" argument on the command line.

All the answer there focus on the first option -- adding a "go_package" option in the .proto source file, but I'm looking for the answer for the second option "a "M" argument on the command line".

Same as the comments under https://mcmap.net/q/370589/-correct-format-of-protoc-go_package

I'm looking for ways to change the module path via protoc, to generate Go code for both a client and server that are part of different modules, I tried using go_opt=module but it doesn't work with source_relative.

Is there any ways to make it work by adding "a "M" argument on the command line", instead of adding a "go_package" option in the .proto source file please?

Specifically, for the file of https://github.com/mmcc007/go/blob/master/examples/helloworld/helloworld/helloworld.proto

Here are my failed attempts:

$ protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative --proto_path=examples/helloworld/helloworld helloworld.proto 

protoc-gen-go: unable to determine Go import path for "helloworld.proto"
. . .
--go_out: protoc-gen-go: Plugin failed with status code 1.


$ protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative --proto_path=examples/helloworld/helloworld --go_opt=Mhelloworld.proto=github.com/mmcc007/go/blob/master/examples/helloworld/helloworld helloworld.proto 

protoc-gen-go-grpc: unable to determine Go import path for "helloworld.proto"
. . .
--go_out: protoc-gen-go: Plugin failed with status code 1.

Suppressive answered 4/5, 2022 at 4:27 Comment(8)
Please can you clarify the sentence "to generate Go code for both a client and server that are part of different modules". Do you want to have a module for the client and a module for the server or do you want to compile different files to different import paths? Note that protoc doesn't care about modules, it only generates Go code. How you distribute that code is up to youSelfemployed
Can I ask what's the purpose ? Why not having a separate module for your protos and specify a go_package?Thyrse
@ClémentJean / @blackgreen, put it is way, if I put go_package in the .proto source file, then it'll tie to a specific repo. But for such sample repo, if people to fork it elsewhere, it'll be more convenient to set the import path on cli for protoc, instead of hard-coding it. But regardless for any reason, if the 2nd option is available, I want to know how to make use of it.Suppressive
developers.google.com/protocol-buffers/docs/reference/… provides an example using the -M optionFungistat
@menghanl, yep, that url is part of the error output. If you take a look at the 2nd command in my OP, you can see that I'm following the example using the -M option from the official doc, yet, still getting that "unable to determine Go import path" error.Suppressive
did you find a solution to this?Sawtelle
looked through the code, but it is also in the documentation @Suppressive linked. You only have to find the ; (semicolon) giving you control over the package name (go and go-grpc do not produce the same package name) ::example:: protoc --go-grpc_out=fizz --go-grpc_opt="Mprotopath/buzz.proto=example.com/project/internal/proto;bar,module=example.com/project" protopath/buzz.proto generates fizz/internal/proto/buzz_grpc.pb.go with package bar (i know it is not sensible, only example) ref: github.com/protocolbuffers/protobuf-go/blob/v1.31.0/compiler/…Blither
one of the worst command line tools I have used recently..Haematoxylon
S
9

I found this to be working using --proto_path for easy reference using "THE M FLAG" :-)

protoc --proto_path=./proto \
  --go_out=./go \
  --go_opt=Mhelloworld.proto=example.com/project/protos/fizz \
  ./proto/helloworld.proto

Note: The M before helloworld.proto

Sawtelle answered 27/6, 2022 at 15:27 Comment(4)
I find it very disappointing that your answer is the only source of info I've found that has finally helped me achieve the simple task of choosing where do I want the generated go code to go. The docs are un-findable, and the comments around the web do not really address this simple task. Thank you @Chris G.Mroz
you could check it from this documentation developers.google.com/protocol-buffers/docs/reference/…Trapper
fwiw.- I agree with @Mroz - that blurb in the docs doesn't actually explain whether to use relative path or absolute path in the PROTO_FILE or the GO_IMPORT_PATH - also - the GO_IMPORT_PATH seems to be a weird combination of both namespace and file path. I was never able to get the "-go_opt=M" command line arg to work - and just resorted to dumping the "option go_package = ..." into my .proto files. I had used these same proto files to generate one language - but couldn't get them to work for golang.Compo
In my case M option doesn't work .... it's ok with option go_package but it's doesn't see --go_opt=M... Have no idea why it happeningOpulence
T
3

You need to add the path in the command or in the proto file

syntax = "proto3";

option go_package = "pkg/api";

this is the same for java, and python as well.

option java_package = "pkg/api";
option py_generic_services = "pkg/api";

As for the command

Makefile

PROJ_PATH=${CURDIR}

.PHONY: proto
proto: ## Generate protobuf code
# Compile proto files inside the project.
    protoc api.proto --proto_path=${PROJ_PATH}/proto --go_out=. --go-grpc_out=.
Traipse answered 4/11, 2022 at 6:30 Comment(0)
U
2

For me, after several hours of struggling I found that the M argument only worked when adding it both as go_opt and go-grpc_opt. E.g. for a proto file located in proto/src/another/folder/helloworld.proto:

protoc --proto_path=proto/src \
  --go_out=. \
  --go-grpc_out=. \
  --go_opt=Manother/folder/helloworld.proto=example.com/project/protos/fizz \
  --go-grpc_opt=Manother/folder/helloworld.proto=example.com/project/protos/fizz \
  proto/src/another/folder/helloworld.proto

In this case the file is located in proto/src/another/folder/helloworld.proto

Ure answered 18/10, 2023 at 11:12 Comment(1)
Thanks for the input. It might well be the case now.Suppressive

© 2022 - 2025 — McMap. All rights reserved.