由引入 Google Protobuf 引发的工程管理思考

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ChaffererZ/article/details/50698427

看到标题,很多人可能会在想这个 Google Protobuf (后面简称 PB ) 是一个什么东东,其实最开始我听说的时候也在怀疑,甚至一开始我还以为是之前跟着大牛写服务端功能时使用的 Thrift 混为一谈,深入接触后才发现,其实不然。至于 PB 到底是啥呢?我在这就不详细介绍了,想了解的人可选择传送门

  • 引发思考的场景

应该多端统一开发需求,需要在 Windows 客户端开发中引入 PB 协议,但是由于是体力活,所以想如果能不增加开发人员的休力劳动是一件多么好的事件。

很多人会想,同步协议这个过程并不会多费时,但是,如果说在项目初期或者是在项目重构时引入 PB,当一切都未定论的时候,修改再所难免,这时体力劳动可想而知。我也是基于这个场景设计了一套属于懒人同步协议的方案。

希望对大家要管理一些特殊工程时有所启发。


  • 解决问题思路

在开始讲述方案前,需要了解如下概念:

  1. Visual Studio 中有 Build Event 这一配置项,它有 Pre-Build、Pre-Link 和 Post Build 三个子项;
  2. Visual Studio 中还有 Forced Include File 选项及预编译头文件;
  3. 在我们的日常开发过程中,有时需要充分利用脚本编程,Windows 下有 bat,Linux 下有 shell,在我这些开发过程中都给我带来过巨大的便利。

接下来我们深入剖析我的解决方案。
首先,我们需要编译 PB 文件来生成 C++ 文件,这里需要注意的是在使用 protoc.exe 时最好带上 -I 选项,不然编译可能无法进行。大家都会想到,这里会引入脚本

protoc.exe –cpp_out=”%_OutDirectory%” -I”%_SrcDirectory%” “%%f”

当然文件多时也可以用通配符来处理。可是,天有时总不随人愿,PB 文件有个编译选项 optimize_for,可选 CODE_SIZE、LITE_RUNTIME 等,在服务端开发中需要使用 CODE_SIZE,但是在客户端中因为强迫证根本不想引入过多的信息,所以会选择 LITE_RUNTIME,这就引来一个文件,协议文件不可能存两份,否则带来的危险是未知的。所以我们在编译时需要替换了,通过脚本修改

setlocal enabledelayedexpansion
for /f "delims=" %%i in ('type "%%f"') do (
    set str=%%i
    set str=!str:CODE_SIZE=LITE_RUNTIME!
    echo !str!>>"%%f_tmp"
) 

看似很完美了,但是模块开发的概念又把我们带入了一个新的问题当中,因项项目管理需要,我必需提供 SDK 形式的模块,别人并不需要关心协议的细节,所以我们会想以 DLL 方式提供,这需要为每个类或者方法添加 __declspec(dllexport),这如果说在编译协议之后手动加是不现实的,修改编译命令

protoc.exe –cpp_out=dllexport_decl=FRAME_CLASS:”%_OutDirectory%” -I”%_SrcDirectory%” “%%f”

修改完成后,满怀惊喜的使用脚本,编译,发现 FRAME_CLASS 并没有在生成的 PB C++ 文件中引用到,如何解决,考虑过从 PB 协议上添加,未找到方法,于是从头文件中来思考,如何才能把带有 FRAME_CLASS 宏的文件准确加到生成的 C++ 文件中,通过脚本控制有点难,所以想到了预编译头文件和 Forced Include File 选项,处理如下:

  1. 把带有 FRAME_CLASS 宏的文件包含到预编译头文件中;
  2. 在 Forced Include File 选项中填入预编译头文件。

好的,现在上面的脚本能很好的工作了,也能解决编译时自动编译已经修改的 PB 文件了,将编写好的 bat 文件加入 Pre-Build 选项中,大功告成。


  • 进一步完善解决方案

确实,目前已经完成了半自动化的编译 PB 文件了,但是,在 PB 逐渐完善的时候,第一次编译都重新编译 PB 文件的做法就有点鸡肋甚至有些不可取了,这时又不得不回过头来思考,如何做增量编译?

我所想到的是文件修改时间,因为这是每次修改文件后都会改变的值,也是我们可以最小量保存的中间件。

在处理文件修改时间时,最开始使用 bat 时,发现处理起来不是很方便,所以我又引入了 VB script。这里不作详述。

猜你喜欢

转载自blog.csdn.net/ChaffererZ/article/details/50698427