从二进制文件中删除 protobuf c++ 编译的路径字符串
Posted
技术标签:
【中文标题】从二进制文件中删除 protobuf c++ 编译的路径字符串【英文标题】:Remove protobuf c++ compiled path string from binary 【发布时间】:2015-01-19 06:23:20 【问题描述】:当我编译使用 Protobuf 的 c++ 程序,然后在二进制文件上运行 linux strings
命令时,其中一个字符串是生成的 cc
文件的路径,其中包含我的主目录和所有内容。显然我想从二进制文件中删除我的主目录和其他个人信息。
这条路径从何而来,如何防止它进入编译后的二进制文件?
【问题讨论】:
尝试在二进制 en.wikipedia.org/wiki/Strip_%28Unix%29 上运行 strip。也许它只是调试信息。只是猜测.. @Sergey 我有,它没有改变任何东西。不过文件有点小。 【参考方案1】:字符串来自嵌入的 protobuf 描述符,用于执行 protobuf 类型的动态自省。本质上,描述符描述了您的整个.proto
文件。描述符本身以 protobuf 格式编码;见google/protobuf/descriptor.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
如果你不想有描述符
您可以通过在您的.proto
文件中添加以下行来以“精简模式”编译您的原型文件:
option optimize_for = LITE_RUNTIME;
在这种模式下,描述符将根本不包括在内。此外,您可以链接到 protobuf 运行时库的“lite”版本,它比常规版本小得多。但是,许多有用的功能将被禁用。整个反射界面都会消失,任何依赖于反射的东西也会消失。例如TextFormat
,即DebugString()
方法用于将消息转换为文本以进行调试的打印,将被删除,因此调试将更加困难。
【讨论】:
感谢您非常详尽的回答!以上是关于从二进制文件中删除 protobuf c++ 编译的路径字符串的主要内容,如果未能解决你的问题,请参考以下文章