简体   繁体   English

如何在Linux中使用Google Protobufs确保相同的输出文件(* .o)

[英]How to ensure identical output files (*.o) using Google Protobufs in Linux

I work in an industry that requires a repeatable build process when an application is ready for deployment. 当应用程序准备好部署时,我在一个需要可重复构建过程的行业中工作。 I've recently inherited an application that up until now has been in development. 我最近继承了一个迄今为止一直在开发的应用程序。 This application runs on a linux platform and uses Google Protocol Buffers (version 2.4.1). 此应用程序在Linux平台上运行,并使用Google Protocol Buffers(版本2.4.1)。 The build process is unfortunately not repeatable, but I've singled out the output files generated from the Protocol Buffer files as the source of uniqueness (using md5sum ) in the application. 遗憾的是,构建过程不可重复,但我已经将协议缓冲区文件生成的输出文件作为应用程序中唯一性的来源(使用md5sum )。 The .o files are mostly the same with the exception of a few lines. 除了几行之外,.o文件大致相同。

I repeated the process using the address book example distributed with the protobuf release. 我使用与protobuf版本一起分发的地址簿示例重复了该过程。 The differences in the .o files are listed below. .o文件的差异如下所示。 Each time a .o file is generated the "878197C9XX" number will change. 每次生成.o文件时,“878197C9XX”编号都会改变。 I'd like a repeatable process so they are always the same. 我想要一个可重复的过程,所以它们总是一样的。

_GLOBAL__I__ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_878197C918Person_descriptor_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_878197C918Person_reflection_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_878197C930Person_PhoneNumber_reflection_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_878197C923AddressBook_reflection_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_878197C930protobuf_AssignDescriptorsOnceE
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_878197C932protobuf_AssignDescriptors_once_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_878197C923AddressBook_descriptor_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_878197C918Person_descriptor_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_878197C930Person_PhoneNumber_descriptor_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_878197C928Person_PhoneType_descriptor_E

Here is a second run: 这是第二次运行:

_GLOBAL__I__ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_75C23E1E18Person_descriptor_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_75C23E1E18Person_reflection_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_75C23E1E30Person_PhoneNumber_reflection_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_75C23E1E23AddressBook_reflection_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_75C23E1E30protobuf_AssignDescriptorsOnceEv
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_75C23E1E32protobuf_AssignDescriptors_once_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_75C23E1E23AddressBook_descriptor_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_75C23E1E18Person_descriptor_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_75C23E1E30Person_PhoneNumber_descriptor_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_75C23E1E28Person_PhoneType_descriptor_E

The steps I used to create the .o files are as follows. 我用来创建.o文件的步骤如下。

Starting with the addressbook.proto file in the protobuf-2.4.1/examples directory, the addressbook.pb.cc and adressbook.pb.h files are generated using ../bin/protoc --cpp_out=. 从protobuf-2.4.1 / examples目录中的addressbook.proto文件开始,使用../bin/protoc --cpp_out =生成addressbook.pb.cc和adressbook.pb.h文件 addressbook.proto . addressbook.proto The md5sum of the .cc and .h files are always the same. .cc和.h文件的md5sum始终相同。

When the .cc/.h files are compiled using g++ (gcc version 4.1.2 20080704, Red Hat 4.1.2-54), the output files are always unique. 当使用g ++(gcc版本4.1.2 20080704,Red Hat 4.1.2-54)编译.cc / .h文件时,输出文件始终是唯一的。 The command used for g++ is g++ -m32 -march=i686 -c -I ../src/ addressbook.pb.cc -o addressbook.o . 用于g ++的命令是g ++ -m32 -march = i686 -c -I ../src/ addressbook.pb.cc -o addressbook.o

Any suggestions or ideas would be greatly appreciated. 任何建议或想法将不胜感激。 Thanks. 谢谢。

Those are C++ symbols in an anonymous namespace mangled by g++. 这些是由g ++破坏的匿名命名空间中的C ++符号。 The g++ compiler generates a unique name for each anonymous namespace. g ++编译器为每个匿名命名空间生成唯一的名称。 The unique namespace identifier is changing between each compilation. 唯一的命名空间标识符在每个编译之间都在变化。

Fortunately, you can use the -frandom-seed=string option to get a repeatable build . 幸运的是,您可以使用-frandom-seed=string选项来获得可重复的构建 See On the way to deterministic binariy (gcc) output 请参阅确定性二进制(gcc)输出的方法

Use the c++filt tool to de-mangle the symbols. 使用c ++ filt工具对符号进行去除。 You will see that both your 1st and 2nd compilation yield the same effective result: 您将看到第一次和第二次编译都产生相同的有效结果:

$ head -n3 names.txt
_GLOBAL__I__ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_878197C918Person_descriptor_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_878197C918Person_reflection_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_878197C930Person_PhoneNumber_reflection_E
$ head -n3 names2.txt
_GLOBAL__I__ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_75C23E1E18Person_descriptor_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_75C23E1E18Person_reflection_E
_ZN8tutorial46_GLOBAL__N_addressbook.pb.cc_00000000_75C23E1E30Person_PhoneNumber_reflection_E
$ c++filt < names.txt
global constructors keyed to tutorial::(anonymous namespace)::Person_descriptor_
tutorial::(anonymous namespace)::Person_reflection_
tutorial::(anonymous namespace)::Person_PhoneNumber_reflection_
tutorial::(anonymous namespace)::AddressBook_reflection_
tutorial::(anonymous namespace)::protobuf_AssignDescriptorsOnce
tutorial::(anonymous namespace)::protobuf_AssignDescriptors_once_
tutorial::(anonymous namespace)::AddressBook_descriptor_
tutorial::(anonymous namespace)::Person_descriptor_
tutorial::(anonymous namespace)::Person_PhoneNumber_descriptor_
tutorial::(anonymous namespace)::Person_PhoneType_descriptor_

$ c++filt < names2.txt
global constructors keyed to tutorial::(anonymous namespace)::Person_descriptor_
tutorial::(anonymous namespace)::Person_reflection_
tutorial::(anonymous namespace)::Person_PhoneNumber_reflection_
tutorial::(anonymous namespace)::AddressBook_reflection_
tutorial::(anonymous namespace)::protobuf_AssignDescriptorsOnce()
tutorial::(anonymous namespace)::protobuf_AssignDescriptors_once_
tutorial::(anonymous namespace)::AddressBook_descriptor_
tutorial::(anonymous namespace)::Person_descriptor_
tutorial::(anonymous namespace)::Person_PhoneNumber_descriptor_
tutorial::(anonymous namespace)::Person_PhoneType_descriptor_

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM