赞
踩
google这是有私心啊,protobuf从某个版本开始,依赖了一个google自己推出的大型组件集,Abseil,有点类似于Boost了,业内用的人,从个人狭窄的圈子来说,应该是不多的,据说google的众贤用的很好。
可是,对于只想白嫖protobuf的笔者来说,protobuf新增对Abseil的依赖,简直是非常麻烦,Abseil 里面包含太多的子组件了,子组件之间的依赖,差点让笔者弃疗。
笔者搞定VC上的protobuf之后,组内伙伴将linux/WSL环境上的protobuf回退到老版本,即不依赖Abseil(需要编译器支持C++17标准,显然ARM上最多支持C++14的交叉编译器搞不定)的那种。
结果现在是双线运行,同一套proto file,默认是用老版本工具生成的 pb.cc/pb.h, VC版本其实仅用于本地,不会在pipeline上跑,每次都是手动再次生成一份。
网上也有部分先吃肉的同行大致介绍了方案。个人也是经历了好几天的折腾,有了一个直接的使用方案,不藏私了,希望对各位小伙伴有帮助。
下载 3.25版本,cmake工具确保已经安装
根据readme ,让你下载abseil你就乖乖照做
有一个命令做了记录,
cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -Dprotobuf_BUILD_TESTS=OFF -SE:/protobuf-3.25.0 -Be:/protobuf-3.25.0/build -G "Visual Studio 17 2022" -T host=x86 -A win32
一番折腾后,sln打开如下(vcpkg工具的先可以不用看,个人是没有走通这条道,浪费了很多时间)
庞大的Abseil 工程让人望而生畏,一路修改各个子项目属性
该编译就编译,有高手将Abseil整成了一个静态库而不是众多原生的静态库集合,这个要表示佩服一下。
Abseil编译的结果如下
附带的utf8_range如下
protobuf有关的工具和库如下
然后的,这些库要用起来
Abseil的库,放到工程子目录 absl下
Protobuf和Abseil的头文件没有好好整理,子项目 Emulator的文件包含路径有了如下两项,
Emulator_ut 是 单元测试专用工程
附加库目录这里其实没有填完整,但是也不是必须
看看链接器的输入项,最有决定性的开始来了
完全展开后
- gmock.lib
- gmock_main.lib
- gtest.lib
- gtest_main.lib
- jsoncpp_static.lib
- libprotobufd.lib
- utf8_range.lib
- utf8_validity.lib
- ../absl\base\Debug\absl_base.lib
- ../absl\strings\Debug\absl_cord.lib
- ../absl\log\Debug\absl_die_if_null.lib
- ../absl\flags\Debug\absl_flags.lib
- ../absl\hash\Debug\absl_hash.lib
- ../absl\log\Debug\absl_log_initialize.lib
- ../absl\base\Debug\absl_log_severity.lib
- ../absl\status\Debug\absl_status.lib
- ../absl\status\Debug\absl_statusor.lib
- ../absl\strings\Debug\absl_strings.lib
- ../absl\synchronization\Debug\absl_synchronization.lib
- ../absl\time\Debug\absl_time.lib
- ../absl\log\Debug\absl_log_internal_check_op.lib
- ../absl\debugging\Debug\absl_leak_check.lib
- ../absl\log\Debug\absl_log_internal_conditions.lib
- ../absl\log\Debug\absl_log_internal_message.lib
- ../absl\log\Debug\absl_log_internal_nullguard.lib
- ../absl\debugging\Debug\absl_examine_stack.lib
- ../absl\log\Debug\absl_log_internal_format.lib
- ../absl\log\Debug\absl_log_internal_proto.lib
- ../absl\log\Debug\absl_log_internal_log_sink_set.lib
- ../absl\log\Debug\absl_log_sink.lib
- ../absl\log\Debug\absl_log_entry.lib
- ../absl\log\Debug\absl_vlog_config_internal.lib
- ../absl\log\Debug\absl_log_internal_fnmatch.lib
- ../absl\flags\Debug\absl_flags_internal.lib
- ../absl\flags\Debug\absl_flags_marshalling.lib
- ../absl\flags\Debug\absl_flags_reflection.lib
- ../absl\flags\Debug\absl_flags_config.lib
- ../absl\flags\Debug\absl_flags_program_name.lib
- ../absl\flags\Debug\absl_flags_private_handle_accessor.lib
- ../absl\flags\Debug\absl_flags_commandlineflag.lib
- ../absl\flags\Debug\absl_flags_commandlineflag_internal.lib
- ../absl\log\Debug\absl_log_globals.lib
- ../absl\log\Debug\absl_log_internal_globals.lib
- ../absl\container\Debug\absl_raw_hash_set.lib
- ../absl\hash\Debug\absl_city.lib
- ../absl\hash\Debug\absl_low_level_hash.lib
- ../absl\container\Debug\absl_hashtablez_sampler.lib
- ../absl\strings\Debug\absl_cordz_info.lib
- ../absl\strings\Debug\absl_cord_internal.lib
- ../absl\strings\Debug\absl_cordz_functions.lib
- ../absl\profiling\Debug\absl_exponential_biased.lib
- ../absl\strings\Debug\absl_cordz_handle.lib
- ../absl\crc\Debug\absl_crc_cord_state.lib
- ../absl\crc\Debug\absl_crc32c.lib
- ../absl\crc\Debug\absl_crc_internal.lib
- ../absl\crc\Debug\absl_crc_cpu_detect.lib
- ../absl\types\Debug\absl_bad_optional_access.lib
- ../absl\base\Debug\absl_strerror.lib
- ../absl\strings\Debug\absl_str_format_internal.lib
- ../absl\debugging\Debug\absl_stacktrace.lib
- ../absl\debugging\Debug\absl_symbolize.lib
- ../absl\debugging\Debug\absl_debugging_internal.lib
- ../absl\debugging\Debug\absl_demangle_internal.lib
- ../absl\synchronization\Debug\absl_graphcycles_internal.lib
- ../absl\synchronization\Debug\absl_kernel_timeout_internal.lib
- ../absl\base\Debug\absl_malloc_internal.lib
- ../absl\strings\Debug\absl_strings_internal.lib
- ../absl\strings\Debug\absl_string_view.lib
- ../absl\base\Debug\absl_spinlock_wait.lib
- ../absl\base\Debug\absl_throw_delegate.lib
- ../absl\numeric\Debug\absl_int128.lib
- ../absl\time\Debug\absl_civil_time.lib
- ../absl\time\Debug\absl_time_zone.lib
- ../absl\types\Debug\absl_bad_variant_access.lib
- ../absl\base\Debug\absl_raw_logging_internal.lib
- %(AdditionalDependencies)
不用感叹添加这些目录费了多少时间。
使用protobuf的时候,可以用编译出来的protoc.exe,也可以用下载版本的,随意。
笔者将 如下目录放置到环境变量path中的时候,还将include整理了一番,之前编译Emulator的时候时候总是提示缺这缺那。
将proto file转化为 c++代码
protoc.exe -I=D:\work\...\Emulator\proto --cpp_out=D:\work\...\Emulator\src *.proto
然后么,添加到Emulator工程中
搞定,后续看看有什么遗漏的,需要的话可以补充。
我们当前用的都是protobuf的比较基础的特性,序列化和反序列化,json互转。
差点忘了,补充一下,新版本的protoc工具生成的文件中(看起来就是原生文件),VC2022下编译不过,如下这个网页中有描述,并且提问者还给出了一个临时解决方案(用老的protoc的就木有问题)
kVTable': redefinition; different storage class
实在对不住,再次尝试一下,居然存在链接问题,已经将log 相关库全部加上,未解决,上次用还是OK的,唉
om.quaero.sw.maco\Middleware\vs2022solution\middleware_ut\x64\Debug\Emulator_ut.lib 和对象 D:\work\workbench\Middleware_DBAccess\com.quaero.sw.maco\Middleware\vs2022solution\middleware_ut\x64\Debug\Emulator_ut.exp
1>EmuCmdExecutor_test.obj : error LNK2019: 无法解析的外部符号 "private: void __cdecl absl::log_internal::LogMessage::CopyToEncodedBuffer<0>(class std::basic_string_view<char,struct std::char_traits<char> >)" (??$CopyToEncodedBuffer@$0A@@LogMessage@log_internal@absl@@AEAAXV?$basic_string_view@DU?$char_traits@D@std@@@std@@@Z),函数 "public: class absl::log_internal::LogMessage & __cdecl absl::log_internal::LogMessage::operator<<<19>(char const (&)[19])" (??$?6$0BD@@LogMessage@log_internal@absl@@QEAAAEAV012@AEAY0BD@$$CBD@Z) 中引用了该符号
1>EmuCmdExecutor_test.obj : error LNK2019: 无法解析的外部符号 "public: __cdecl absl::log_internal::LogMessageFatal::LogMessageFatal(char const *,int,class std::basic_string_view<char,struct std::char_traits<char> >)" (??0LogMessageFatal@log_internal@absl@@QEAA@PEBDHV?$basic_string_view@DU?$char_traits@D@std@@@std@@@Z),函数 "public: class Emul_UI_proto::ErpcCmdReply const & __cdecl google::protobuf::internal::RepeatedPtrFieldBase::Get<class google::protobuf::RepeatedPtrField<class Emul_UI_proto::ErpcCmdReply>::TypeHandler>(int)const " (??$Get@VTypeHandler@?$RepeatedPtrField@VErpcCmdReply@Emul_UI_proto@@@protobuf@google@@@RepeatedPtrFieldBase@internal@protobuf@google@@QEBAAEBVErpcCmdReply@Emul_UI_proto@@H@Z) 中引用了该符号
1>EmuCmdExecutor_test.obj : error LNK2019: 无法解析的外部符号 "class absl::Status __cdecl google::protobuf::json::JsonStringToMessage(class std::basic_string_view<char,struct std::char_traits<char> >,class google::protobuf::Message *,struct google::protobuf::json::ParseOptions const &)" (?JsonStringToMessage@json@protobuf@google@@YA?AVStatus@absl@@V?$basic_string_view@DU?$char_traits@D@std@@@std@@PEAVMessage@23@AEBUParseOptions@123@@Z),函数 "class absl::Status __cdecl google::protobuf::json::JsonStringToMessage(class std::basic_string_view<char,struct std::char_traits<char> >,class google::protobuf::Message *)" (?JsonStringToMessage@json@protobuf@google@@YA?AVStatus@absl@@V?$basic_string_view@DU?$char_traits@D@std@@@std@@PEAVMessage@23@@Z) 中引用了该符号
类似于如下问题
https://github.com/protocolbuffers/protobuf/issues/12292
听人劝,吃饱饭,换成了
protobuf-3.20.1
https://github.com/protocolbuffers/protobuf/releases?page=6
暂时和Abseil说再会,等下次必须用的时候再来尝试
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。