从二进制文件中删除 protobuf c++ 编译路径字符串 [英] Remove protobuf c++ compiled path string from binary

查看:66
本文介绍了从二进制文件中删除 protobuf c++ 编译路径字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这个路径来自哪里,如何防止它进入编译后的二进制文件?

解决方案

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

现在,描述符通常应该像您描述的那样包含绝对路径.它确实想要包含规范"路径——即,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 很笨,只知道如何比较字符串.例如,它不知道当前目录是什么:

# 不起作用cd/home/foo/myprojprotoc -I/home/foo/myproj/src src/frobber/baz.proto

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

# 不起作用:protoc 不会折叠xyz/../".protoc -Isrc xyz/../src/frobber/baz.proto

然而,如果.."是一致的,那么它是可以的,因为再次 protoc 只关心前缀匹配:

# OK:前缀一致.protoc -Ixyz/../src xyz/../src/frobber/baz.proto

如果你不想有一个描述符

您可以通过在 .proto 文件中放置以下行以精简模式"编译您的 proto 文件:

option optimize_for = LITE_RUNTIME;

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

When I compile my c++ program that uses Protobuf, and then run the linux strings command on the binary, one of the strings is a path to the generated cc file, with my home directory and everything. Obviously I'd like to eliminate my home directory and other personal information from the binary.

Where does this path come from and how can I prevent it from making it into the compiled binary?

解决方案

The string comes from the embedded protobuf descriptor, which is used to perform dynamic introspection of protobuf types. Essentially, the descriptor describes your whole .proto file. The descriptor itself is encoded in protobuf format; see google/protobuf/descriptor.proto.

Now, the descriptor normally should not contain absolute paths like you describe. It really wants to contain "canonical" paths -- that is, the path name of the proto file relative to the source code root, or in other words, the path that you'd write in an import statement for that file. For instance, descriptor.proto's own canonical path is google/protobuf/descirptor.proto; to import it, you would write import "google/protobuf/descriptor.proto";.

The reason your descriptors are getting the full absolute filesystem path is because that is the path that you are passing to protoc, and you are not passing a -I flag to tell protoc where the root of your source tree is. Since protoc can't figure out the root of the source code, it is falling back to the file system root.

For instance, say your .proto file is /home/foo/myproj/src/frobber/baz.proto. Say that the src directory in this path is your "source root", meaning that you want people to write import "frobber/baz.proto"; to import your proto file. In that case, you want to invoke protoc like this:

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

Note that if you are running the command from, say, the myproj directory, then you probably shouldn't specify an absolute path at all:

protoc -Isrc src/frobber/baz.proto

It is very important that the -I flag here is a textual prefix of the source file name. protoc is dumb and only knows how to compare strings. It doesn't, for instance, know what the current directory is:

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

And it also cannot canonicalize "..":

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

However ".." is OK if it's consistent, because again protoc only cares about a prefix match:

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

If you'd rather not have a descriptor

You can compile your proto files in "lite mode" by placing the following line in your .proto file:

option optimize_for = LITE_RUNTIME;

In this mode, descriptors will not be included at all. Additionally, you can link against the "lite" version of the protobuf runtime library, which is much smaller than the regular version. However, many useful features will be disabled. The whole reflection interface will be gone, and anything that depends on reflection will be gone as well. For example, TextFormat, which is what the DebugString() method uses to convert messages into text to print for debugging, will be removed, therefore debugging will be harder.

这篇关于从二进制文件中删除 protobuf c++ 编译路径字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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