没有成员找到时使用cmake construct proto [英] No Member Found when use cmake construct proto

查看:362
本文介绍了没有成员找到时使用cmake construct proto的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望使用proto并由cmake管理。

I wish to use proto and managed by cmake.

示例项目可以显示这里

文件如下

.
├── app1
│   ├── app1.cpp
│   └── app1.proto
├── CMakeLists.txt
├── common
│   ├── bar
│   │   ├── bar.proto
│   │   └── CMakeLists.txt
│   └── foo
│       ├── CMakeLists.txt
│       └── foo.proto
└── README.md

如果我想生成一些cpp文件,我只需使用命令

If I wanna just generate some cpp files, I can just use command

$ protoc --cpp_out=build common/bar/bar.proto
$ protoc --cpp_out=build common/foo/foo.proto

虽然,如果我使用cmake,它总是报告错误如下:

While, if I use cmake, it always report a error as follow :

[ 14%] Running C++ protocol buffer compiler on foo.proto
Scanning dependencies of target FooLib
[ 28%] Building CXX object common/foo/CMakeFiles/FooLib.dir/foo.pb.cc.o
Linking CXX static library libFooLib.a
[ 28%] Built target FooLib
[ 42%] Running C++ protocol buffer compiler on bar.proto
Scanning dependencies of target BarLib
[ 57%] Building CXX object common/bar/CMakeFiles/BarLib.dir/bar.pb.cc.o
/Users/yu/Workspace/res/proto/project/build/common/bar/bar.pb.cc:79:5: error: no member named 'protobuf_AddDesc_common_2ffoo_2ffoo_2eproto' in the global namespace
  ::protobuf_AddDesc_common_2ffoo_2ffoo_2eproto();
  ~~^
1 error generated.
make[2]: *** [common/bar/CMakeFiles/BarLib.dir/bar.pb.cc.o] Error 1
make[1]: *** [common/bar/CMakeFiles/BarLib.dir/all] Error 2
make: *** [all] Error 2

任何帮助都很感激。

推荐答案

我不太熟悉cmake,对于我来说,在您的proto文件跨多个目录的情况下,cmake的 PROTOBUF_GENERATE_CPP 被破坏。

I'm not too familiar with cmake, so I could be missing something, but it appears to me that cmake's PROTOBUF_GENERATE_CPP is broken in the case where your proto files span multiple directories.

cmake执行以下命令以生成 code> PROTOBUF_GENERATE_CPP 位于 common / foo / CMakeLists.txt foo.pb。* :

When PROTOBUF_GENERATE_CPP is placed in common/foo/CMakeLists.txt, cmake executes the following command to generate foo.pb.*:

cd /home/kenton/test/cmake-proto/common/foo &&
    /usr/bin/protoc --cpp_out /<project-dir>/common/foo \
        -I /<project-dir>/common/foo -I /<project-dir> \
        /<project-dir>/common/foo/foo.proto

PROTOBUF_GENERATE_CPP 放置在顶层 CMakeLists.txt 中时,cmake执行以下命令以生成 foo.pb。*

When PROTOBUF_GENERATE_CPP is placed in the top-level CMakeLists.txt, cmake executes the following command to generate foo.pb.*:

/usr/bin/protoc --cpp_out /<project-dir> \
    -I /<project-dir>/common/foo -I /<project-dir> \
    /<project-dir>/common/foo/foo.proto

这两个都是错误的。具体来说, -I /< project-dir> / common / foo 标志不应该存在。 -I 仅应用于指定源树的。只有 -I /< project-dir> 正确。再次,这似乎是cmake中的一个错误,因为AFAICT没有文档化的方式使它做正确的事情。

Both of these are wrong. Specifically, the flag -I /<project-dir>/common/foo should not be there. -I should only be used to specify the root of the source tree. Only -I /<project-dir> is correct. Again, this appears to be a bug in cmake, since AFAICT there is no documented way to make it do the right thing.

这是混淆Protobuf编译器,因为它使用该文件相对于根目录的路径来决定其规范名称。在你的情况下, foo.proto 的规范名称应该是 common / foo / foo.proto ,因为这是所有其他文件用于导入它的名称。符号 protobuf_AddDesc_common_2ffoo_2ffoo_2eproto 是从这个规范名称构建的(你可以看到规范名称是编码的,使用 _xx 转义 / 字符)。不幸的是,因为cmake通过 -I /< project-dir> / common / foo protoc 编译器认为 foo.proto 的规范名称只是 foo.proto ,没有前缀(因为它认为 /< project-dir> / common / foo 是源根目录,因为不正确的 -I )。当其他文件导入 foo.proto 时,这会导致问题,因为在这些其他文件中,协议编译器认为规范名称是 common / foo / foo。 proto 。因此,它会生成不匹配的代码。

This is confusing the Protobuf compiler because it uses the file's path relative to the root directory to decide its canonical name. In your case, foo.proto's canonical name should be common/foo/foo.proto, because this is the name that all other files use to import it. The symbol protobuf_AddDesc_common_2ffoo_2ffoo_2eproto is constructed from this canonical name (you can see the canonical name is encoded in it, using _xx as escapes for / and . characters). Unfortunately, because cmake is passing -I /<project-dir>/common/foo to protoc, the protobuf compiler concludes that foo.proto's canonical name is simply foo.proto, with no prefix (because it thinks that /<project-dir>/common/foo is the source root directory, due to the incorrect -I flag). This causes problems when other files import foo.proto, because in those other files the protocol compiler believes that the canonical name is common/foo/foo.proto. So, it generates mismatching code.

这是FindProtobuf的文档。它不包含对这个问题的任何讨论,这使我怀疑作者不知道它是破碎的。然而,这似乎非常令人惊讶,因为cmake被广泛使用,这个代码是岁。也许文档只是不完整?我建议提交一个错误。

Here is the documentation for FindProtobuf. It does not contain any discussion of this issue, which makes me suspect that the authors are not aware that it is broken. However, this would seem very surprising since cmake is widely-used and this code is years old. Perhaps the documentation is simply incomplete? I would suggest filing a bug.

这篇关于没有成员找到时使用cmake construct proto的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆