2

我正在尝试使用 .proto 文件将 C++ 代码编译成单个二进制文件。我目前的流程有两个步骤;

  1. 使用 protoc 从 3 个 .proto 文件生成 C++ 代码。
  2. 将生成的代码和我自己的 C++ 代码编译成一个 .o 文件。

但是,当我尝试在步骤 2 中编译时,生成的代码指定输出为“com/company/B.pb.h”,编译器无法找到该文件,因为该文件位于同一目录中。

我不想手动更改生成的代码导入,因为我觉得应该由 protoc 完成,并且我们还将这些 proto 文件用于其他项目(包括使用相同的 .proto 文件生成 java 代码,这是可行的)。有没有办法在不更改原型导入的情况下指定生成代码的导入?

编辑:一次生成多个文件时,这是 protoc 的问题吗?我应该使用不同的命令吗?

我知道 java 有一些选项,比如指定包或类名,但我找不到 C++ 类似的东西。

option java_multiple_files = true;
option java_package = "com.company.B";
option java_outer_classname = "B";

任何帮助深表感谢。更多详情如下。

目录结构:

.
├── com
│   └── company # generated code
│       ├── A.pb.cc
│       ├── A.pb.h
│       ├── B.pb.cc
│       ├── B.pb.h
│       ├── C.pb.cc
│       └── C.pb.h
├── Parser.cc
├── Parser.h
└── proto
    └── com
        └── company
            ├── A.proto
            ├── B.proto
            └── C.proto

协议命令:(从 . 运行)

protoc --cpp_out=. --proto_path=proto/ com/company/A.proto com/company/B.proto com/company/C.proto

A.proto 片段:

syntax = "proto3";
option optimize_for = SPEED;

package com.company;

import "com/company/B.proto"; # specified as full path re Google's documentation

...

解析器.cc:

#include "parser.h"
...

解析器.h:

#include "com/company/A.pb.h"
#include "com/company/B.pb.h"
#include "com/company/C.pb.h"
...

G++ 命令:

g++ -fPIC -Lprotoc -lprotobuf parser.cc -o parser.so

错误:

fatal error: com/company/B.pb.h: No such file or directory
 #include "com/company/B.pb.h"
          ^~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
4

1 回答 1

0

我从来没有找到一种方法来为 C++ 生成的代码指定输出,但是我找到了一种正确编译代码的方法,而无需做一些笨拙的变通办法,我认为这是我一开始就应该采用的方法。开始:

Step 1,生成的C++代码保持不变,生成路径包含,编译在同一目录下。

第 2 步变成了一个 make 文件(我们使用的是 Ruby Make/Rake 但概念是一样的)makefile 指定;

  • parser.cc 和所有生成的 .cc 文件作为源。
  • $LIBS 标志-fPIC -lprotobuf(注意-Lprotoc 这里没有,我在轨道上进一步遇到了错误。通常是关于未定义的符号)
  • $INCFLAGS `-I$(srcdir)/com/company ```。(这是要包含在编译中的 make 文件的目录)
  • $VPATH $(srcdir)/com/company。(这是要搜索的 make 文件的目录。)

这导致为每个 .proto 文件生成一个 .o 文件,并为 parser.cc 生成一个 .o 文件。然后将它们组合成一个 .so 文件,可以按照我们的意图使用。

如果您遇到类似的问题,请随时提出问题。

于 2020-08-31T05:47:01.033 回答