从二进制文件中删除protobuf c ++编译的路径字符串

时间:2015-01-19 06:23:20

标签: c++ string protocol-buffers

当我编译使用Protobuf的c ++程序,然后在二进制文件上运行linux strings命令时,其中一个字符串是生成的cc文件的路径,带有我的主目录和一切。显然,我想从二进制文件中删除我的主目录和其他个人信息。

这条路径来自何处,如何阻止它进入已编译的二进制文件?

1 个答案:

答案 0 :(得分:2)

字符串来自嵌入式protobuf描述符,用于执行protobuf类型的动态内省。本质上,描述符描述了整个.proto文件。描述符本身以protobuf格式编码;见google/protobuf/descriptor.proto

现在,描述符通常应该包含您描述的绝对路径。它真的想包含"规范" paths - 即proto文件相对于源代码根的路径名,或者换句话说,是您在该文件的import语句中写入的路径。例如,descriptor.proto自己的规范路径为google/protobuf/descirptor.proto;要导入它,你可以写import "google/protobuf/descriptor.proto";

您的描述符获取完整绝对文件系统路径的原因是因为这是您传递给protoc的路径,并且您没有传递-I标志来告诉protoc源树的根目录所在的位置。由于protoc无法找出源代码的根,因此它会回退到文件系统根目录。

例如,假设您的.proto文件为/home/foo/myproj/src/frobber/baz.proto。假设此路径中的src目录是您的"源根",这意味着您希望人们编写import "frobber/baz.proto";来导入您的proto文件。在这种情况下,您想要像这样调用protoc

protoc -I/home/foo/myproj/src /home/foo/myproj/src/frobber/baz.proto

请注意,如果您从myproj目录运行命令,那么您可能根本不应指定绝对路径:

protoc -Isrc src/frobber/baz.proto

这里的-I标志是源文件名的文本前缀非常重要。 protoc是愚蠢的,只知道如何比较字符串。例如,它不知道当前目录是什么:

# DOES NOT WORK
cd /home/foo/myproj
protoc -I/home/foo/myproj/src src/frobber/baz.proto

它也不能规范化" ..":

# DOES NOT WORK: protoc doesn't collapse "xyz/../".
protoc -Isrc xyz/../src/frobber/baz.proto

然而" .."如果它是一致的,那就没关系,因为protoc只关心前缀匹配:

# OK: Prefix is consistent.
protoc -Ixyz/../src xyz/../src/frobber/baz.proto

如果您不想拥有描述符

您可以在" lite模式下编译原型文件"将以下行放在.proto文件中:

option optimize_for = LITE_RUNTIME;

在此模式下,根本不会包含描述符。此外,您可以链接到" lite" protobuf运行时库的版本,比常规版本小得多。但是,许多有用的功能将被禁用。整个反射界面将消失,任何依赖于反射的东西也将消失。例如,TextFormatDebugString()方法用于将消息转换为文本以进行打印以进行调试的内容将被删除,因此调试将更加困难。