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