86

I tried importing a proto file named test1.proto to another proto file named test2.proto using the import statement

import "com/test/test1.proto";

But i get the following error

com/test/test1.proto: File not found.
test2.proto: Import "com/test/test1.proto" was not found or had errors.

I tried in many ways to find the cause of the import error but couldn't. So could someone please tell me the correct way of doing proto file imports in case there is something wrong with the above statement??

Aarish Ramesh
  • 6,745
  • 15
  • 60
  • 105

7 Answers7

74

You have to use the --proto_path command-line flag (aka -I) to tell protoc where to look for .proto files. If you don't provide a path, by default it will only search the current directory. See the documentation (under "Generating Your Classes" at the end of the page), or type protoc --help.

Kenton Varda
  • 41,353
  • 8
  • 121
  • 105
  • 2
    That means should the proto file names alone be mentioned in the import statement? am confused as i get the following error when trying to execute with the import "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 too dumb to figure out when two paths (e.g. absolute and relative) are equivalent (it's harder than you think).".. Please clarify – Aarish Ramesh Jan 16 '14 at 10:02
  • protoc -I=path/to/first/imported/file -I=path/to/second/imported/file --cpp_out=path/where/output/file/should/go path/where/output/file/should/go/nameOfFile.proto – spfursich May 19 '15 at 22:06
  • 36
    If your proto file is, say, `foo/bar/baz/qux.proto`, then your `--proto_path` can be any of `.`, `foo`, `foo/bar`, or `foo/bar/baz`, but it _cannot_ be `corge` nor can it be `/absolute/path/to/foo/bar/baz`, etc. because those are not prefixes of the file name. The idea is that the proto path should specify your "top level source directory", i.e. the directory that all your imports are relative to. So if you import this file as `import "baz/qux.proto"` then your proto path should be `foo/bar`. – Kenton Varda May 20 '15 at 19:16
  • 1
    Where can you mention this protoc path if you are using a precompiled java mavan jar of proto files that you are trying to import? – Righto Nov 16 '17 at 05:58
  • @Righto The protocol compiler, to my possibly-outdated knowledge, cannot read `.proto` files from a `.jar`, sorry. – Kenton Varda Nov 17 '17 at 03:26
  • 1
    "Multiple import directories can be specified by passing the --proto_path option multiple times; they will be searched in order." https://developers.google.com/protocol-buffers/docs/proto3#generating – Nitin Savant Feb 21 '19 at 16:47
37

Just to add, if you are building for .NET and/or you are Visual Studio, you can add an extra attribute to your proto file defination in the .csproj file to specify the Proto Root like so :

<Protobuf Include="Protos\ProtoFile.proto" GrpcServices="None" ProtoRoot="Protos\" /> 

This clears all import and related errors.

Chipo Hamayobe
  • 877
  • 11
  • 13
  • Thank you for this. I've been trying to figure out what I'm missing for hours. – thornhill Mar 18 '20 at 19:00
  • 1
    ProtoRoot must also be the prefix of the Include path for anybody still confused. ProtoRoot should just be a relative path from the .csproj to the directory of protos. Once you do this, you can directly import another proto e.g. import "base.proto"; in some other proto so long as they share the same directory and package. – perustaja Jan 06 '21 at 19:18
  • @perustaja out of curiosity, how does it work with protos that define different packages? – Matthew Heimlich Apr 06 '21 at 16:49
  • @MatthewHeimlich I haven't touched these protos in some time now so sadly I can't say. I can link you to the repository where it works in case you'd like to see that. I haven't checked recently but at that time I could not find strict documentation for this csproj setup anywhere. – perustaja Apr 07 '21 at 16:06
  • This was really useful for me where I had an import file that was a level up from the .proto file, and Visual Studio wasn't finding it. thanks! – tank104 Nov 07 '22 at 20:16
23

If you're using IntelliJ IDEA, go to Preferences -> Protobuf Support and add the path to your .proto file. This would resolve the error.

Impulse The Fox
  • 2,638
  • 2
  • 27
  • 52
Ashlin Karkada
  • 1,320
  • 1
  • 12
  • 20
  • 1
    I can just informate path (folder) on this option in IntelliJ IDEA. Is there a way to work when `.proto` is into `.jar`? I would like to use `google.protobuf.Empty` that is into a jar `..\plugins\protobuf-jetbrains-plugin\lib\protobuf-java-3.6.1-sources.jar` – Muka Jan 10 '19 at 16:33
2

For people running Bazel based projects, add the required proto file in the deps field of the BUILD like this-

native.proto_library(
    name = "test_message"
    srcs = "test_message.proto"
    deps = "//path/to/proto/you_are/importing:test1"

test1 is target name of the test1.proto file just like test_message is the target name of test_message.proto file.

Pavan Manjunath
  • 27,404
  • 12
  • 99
  • 125
  • Responding to an old comment, but... what do I have my import statement as in the .proto file? I can't get it to work, it keeps saying the file can't be found. – Jdban101 Feb 11 '20 at 00:57
1

Lets say, in Unix like environment, the path to the proto files is /home/path/to/the/protos/dir And the proto files have package and import statements such as this:

package protos.dir;
import "protos/dir/sample.proto";

...

Now go to the parent directory of the proto package, and execute the proto compile command such as:

$ cd /home/path/to/the
$ protoc --proto_path=/home/path/to/the --python_out=. /home/path/to/the/protos/dir/*.proto
soupso
  • 592
  • 1
  • 4
  • 20
0

If you are using IntelliJ:

  1. Click on the Maven tab on the right side header.
  2. Click on Reload All Maven objects, it will be represented by a circular symbol.
Aditya
  • 13
  • 5
0

There are a few things to note:

  1. protoc is trying to find com/test/test1.proto from the proto-path (by default it will be the current working directory)
  2. In order to compile test2.proto and for protoc to find com/test/test1.proto from the proto-path, this has to be true: --proto-path="<working_directory; absolute path to wd 1 level above com/test>"
  3. protoc --go_out=pb --go_opt=paths=source_relative --go-grpc_out=pb --go-grpc_opt=paths=source_relative com/test/test2.proto --proto_path=<working_directory>
  4. This way protoc is looking at the <working_directory> level and will be able to find com/test/test1.proto
m0zgen
  • 569
  • 7
  • 20