当应用程序准备好部署时,我在一个需要可重复构建过程的行业中工作.我最近继承了一个迄今为止一直在开发的应用程序.此应用程序在Linux平台上运行,并使用Google Protocol Buffers(版本2.4.1).遗憾的是,构建过程不可重复,但我已经将协议缓冲区文件生成的输出文件作为应用程序中唯一性的来源(使用md5sum).除了几行之外,.o文件大致相同.
我使用与protobuf版本一起分发的地址簿示例重复了该过程..o文件的差异如下所示.每次生成.o文件时,"878197C9XX"编号都会改变.我想要一个可重复的过程,所以它们总是一样的.
_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
这是第二次运行:
_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
我用来创建.o文件的步骤如下.
从protobuf-2.4.1/examples目录中的addressbook.proto文件开始,使用../bin/protoc --cpp_out =生成addressbook.pb.cc和adressbook.pb.h文件.addressbook.proto..cc和.h文件的md5sum始终相同.
当使用g ++(gcc版本4.1.2 20080704,Red Hat 4.1.2-54)编译.cc/.h文件时,输出文件始终是唯一的.用于g ++的命令是g ++ -m32 -march = i686 -c -I ../src/ addressbook.pb.cc -o addressbook.o.
任何建议或想法将不胜感激.谢谢.
这些是由g ++破坏的匿名命名空间中的C++符号.g ++编译器为每个匿名命名空间生成唯一的名称.唯一的命名空间标识符在每个编译之间都在变化.
幸运的是,您可以使用该-frandom-seed=string
选项来获得可重复的构建.请参阅 确定性二进制(gcc)输出的方法
使用c ++ filt工具去除符号.您将看到第一次和第二次编译都产生相同的有效结果:
$ 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_