前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >c++大型工程构建演化

c++大型工程构建演化

原创
作者头像
沛然爸爸爱打码
修改2020-03-29 19:41:40
1.5K0
修改2020-03-29 19:41:40
举报

一、简介

在过去服务器后端开发一直是c++绝对称霸的领域,但是随着近些年互联网时的快速发展,产品的快速迭代,c++的开发的效率不高的问题使得越来越多的初创公司在技术选型的时候抛弃它而转向了go,go语言的易用性无疑的其能得到青睐的重要原因,尤其是其go module支持的现代语言包管理方式,使得其比c++更让人容易接受。

腾讯视频的后台经过这么些年的发展,沉淀下来了很多的基础库,包括视频包基础封装库、常用字符串处理工具库等等,公共库的管理模式经历了很多个版本的演进,其实伴随着公共库管理的升级也就是视频后台基础开发栈的升级发展。

下面介绍腾讯视频后台服务器端开发模式历经的几个阶段,以及每个阶段遇到的问题,从各个阶段发展中可以看到c++工程构建的一整部演化史。

二、makefile/make原始阶段

在这个阶段很原始,主要解决以下两个问题:

  1. 公共库怎么统一管理
  2. 业务怎么使用公共库

2.1 开发模式

在这个阶段,视频后台开发是以组为单元,每个组有一台实体开发机,每个组员有一个对应自己英文名的普通账号,通过这个账号在这台实体机上面完成代码的开发工作。

每个用户没有基本的权限管理和使用限制,经常出现磁盘满的问题,cpu被某个进程打满的问题。

2.2 公共库统一管理

在视频实体机开发年代,有一个最原始的母机,里面有所有的视频公共库代码和编译好的.a静态库文件,母机通过crontab的方式每天凌晨给各个组的开发机通过rsync命令同步公共库,达到各个组使用的公共库是同一个版本。

2.3 业务怎么使用公共库

公共库统一放到一个目录,定时更新,公共库里面有一个makefile.comm文件,该文件定义好公共库对外的宏,程序直接使用这个宏来达到包含指定库的目的,通过预定义宏的方式可以向开发者屏蔽公共库的升级操作导致目录变更导致编译找不到文件的问题。定义参考:

代码语言:txt
复制
#一级路径目录变量的定义
PATH_ROOT    = /usr/local
PATH_COMMLIB = $(PATH_ROOT)/commlib
PATH_PLATFORMLIB = $(PATH_COMMLIB)/platformlib

#视频基础lib库
INC_BASELIB = -I$(PATH_PLATFORMLIB)/baselib/baselib.v1.0.0/include
LIB_COMM_OI = -L$(PATH_PLATFORMLIB)/baselib/baselib.v1.0.0/lib -lcomm_oi

#异步jce接口,就是个jce文件生成的
INC_JCE      = -I$(PATH_PLATFORMLIB)/jce/jce.v1.0.0 -DCOMMLIB_JCE_VER=100
ifdef INC_JCE_2.0
INC_JCE      = -I$(PATH_PLATFORMLIB)/jce/jce.v2.0.0 -DCOMMLIB_JCE_VER=200
endif
ifdef INC_JCE_3.0
INC_JCE      = -I$(PATH_PLATFORMLIB)/jce/jce.v3.0.1 -DCOMMLIB_JCE_VER=300
endif

#同步jce接口
INC_JCEAPI   = -I$(PATH_PLATFORMLIB)/jceapi/jceapi.v1.0.0/include -DCOMMLIB_JCEAPI_VER=100
LIB_JCEAPI   = -L$(PATH_PLATFORMLIB)/jceapi/jceapi.v1.0.0/lib -lvinvoker
ifdef INC_JCEAPI_2.0
INC_JCEAPI   = -I$(PATH_PLATFORMLIB)/jceapi/jceapi.v2.0.0/include -DCOMMLIB_JCEAPI_VER=200
LIB_JCEAPI   = -L$(PATH_PLATFORMLIB)/jceapi/jceapi.v2.0.0/lib -lvinvoker
endif
ifdef INC_JCEAPI_2.1
INC_JCEAPI   = -I$(PATH_PLATFORMLIB)/jceapi/jceapi.v2.1.0/include -DCOMMLIB_JCEAPI_VER=210
LIB_JCEAPI   = -L$(PATH_PLATFORMLIB)/jceapi/jceapi.v2.1.0/lib -lvinvoker
endif

2.4 小结

  1. 学习成本高,makefile编译方式原始,新同学学习成本很高,编译复杂的后台服务基本是靠从别的地方拷贝makefile的方式来实现;
  2. 公共库升级难,遇到库相互依赖导致的符号问题以及二进制兼容真的让人很头疼,出现问题及其难定位;
  3. 公共库升级慢,更新是以天为单位,要想实现即时更新还得人为操作;
  4. 母机这种单一实体机的管理方式,存在硬件故障的风险。

三、cmake半开化阶段

3.1 开发模式

这个时候伴随着公司内部推荐云开发主机,基本上线了人手一台开发机,视频统一提供机器的初始化工具,实现公共库的初始化,其实和实体机一样的模式,公共库还是统一管理,下发到每个人的机器上面,其实这个阶段和实体机开发并没有什么本质的区别。

3.2 公共库组织

伴随着后台开发框架的升级改造,视频后台在spp提供的网络封装基础上封装了一个spp_rpc的业务开发框架,整个框架利用cmake来进行编译管理,cmake相比makefile简介的语法,很大程度上释放了开发人员的生产力。公共库也伴随着框架的改造输出cmake的引用变量。cmake.comm定义如下:

代码语言:txt
复制
# 公共库定义
# 一级路径目录变量的定义)
set(PATH_ROOT /usr/local)
set(PATH_COMMLIB ${PATH_ROOT}/commlib)

#二级路径目录变量的定义
set(PATH_PLATFORMLIB ${PATH_COMMLIB}/platformlib)
set(PATH_OLDLIB ${PATH_COMMLIB}/oldlib)
set(PATH_OUTERLIB ${PATH_COMMLIB}/outerlib)
set(PATH_PROTOCOL ${PATH_COMMLIB}/protocol)
set(PATH_SPP_PLUGIN ${PATH_PLATFORMLIB}/spp_plugin/spp_plugin)

#具体目录下的变量定义
#####################Begin define directory: platformlib###########################
set(INC_BASELIB ${PATH_PLATFORMLIB}/baselib/baselib.v1.0.0/include)
set(LIB_COMM_OI ${PATH_PLATFORMLIB}/baselib/baselib.v1.0.0/lib/libcomm_oi.a)

#异步jce接口,就是个jce文件生成的
set(INC_JCE ${PATH_PLATFORMLIB}/jce/jce.v1.0.0)
if (INC_JCE_2.0)
    set(INC_JCE ${PATH_PLATFORMLIB}/jce/jce.v2.0.0)
elseif(INC_JCE_3.0)
    set(INC_JCE ${PATH_PLATFORMLIB}/jce/jce.v3.0.0)
elseif(INC_JCE_3.0.1)
    set(INC_JCE ${PATH_PLATFORMLIB}/jce/jce.v3.0.1)
endif()

add_definitions(-DCOMMLIB_JCEAPI_VER=100)
set(INC_JCEAPI ${PATH_PLATFORMLIB}/jceapi/jceapi.v1.0.0/include)
set(LIB_JCEAPI ${PATH_PLATFORMLIB}/jceapi/jceapi.v1.0.0/lib/libvinvoker.a)
if (INC_JCEAPI_2.0)
    add_definitions(-DCOMMLIB_JCEAPI_VER=200)
    set(INC_JCEAPI ${PATH_PLATFORMLIB}/jceapi/jceapi.v2.0.0/include)
    set(LIB_JCEAPI ${PATH_PLATFORMLIB}/jceapi/jceapi.v2.0.0/lib/libvinvoker.a)
elseif (INC_JCEAPI_2.1)
    add_definitions(-DCOMMLIB_JCEAPI_VER=210)
    set(INC_JCEAPI ${PATH_PLATFORMLIB}/jceapi/jceapi.v2.1.0/include)
    set(LIB_JCEAPI ${PATH_PLATFORMLIB}/jceapi/jceapi.v2.1.0/lib/libvinvoker.a)
endif()

3.3 小结

  1. 语法简单,方便学习和维护
  2. 缺少对外部模块的依赖支持,需要引用外部库的时候还是一样需要先把外部库拷贝到视频自己的公共库。
  3. 公共库还是处于统一管理的模式,存在升级维护的问题,依然没有的概念

四、bazel与时俱进

包管理

随着技术的升级,之前公共库统一管理的方式暴露出来越来越到的问题,同时为了响应BG的中台建设,我们决定对公共库进行一次大的升级改造,把之前在一个文件夹下面庞大的公共库按照功能拆分到一个个的git工程中,原先的公共库统一放到一个git项目组下面,每个独立的库通过bazel改造之后对外提供BAZEL接口,业务直接引用源码的形式获取。

BAZEL化相当于引入了包的概念,不仅仅公共库可以通过包的方式管理,后台的协议同样也通过这种形式组织,这样可以避免之前协议调用通过复制粘贴的方式来获得,这种方式基本可以解决升级中带来的各种问题。

4.1 引用方式

  • WORKSPACE配置
代码语言:txt
复制
git_repository(
    name = "commlib_version_tool",   
    remote = "http://git.code.oa.com/videocommlib/version_tool.git",
    tag = "v1.0.0",  # 选择一个最新稳定版本 
)
  • BUILD配置
代码语言:txt
复制
cc_library(
    name = "", 
    srcs = [""],
    deps = [ 
        "@vcommlib_version_tool:version",
    ]   
)

4.2 小结

  1. bazel学习门槛略高,中文资料比较少

五、总结

腾讯视频后台开发模式的快速迭代适应了最近几年的业务快速变化,改善了开发人员的后台开发模式,由之前的农耕时代跨入到了如今的现代化时代,提升了大家的开发效率,也更新了大家的开发技术栈。

六、参考

对比CMake与Bazel

2019年,抛弃 CMake,用 Bazel / Buck 来构建大型项目吧

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

腾讯视频后台开发长期招人,有意向的直接加微信:544892012

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、简介
  • 二、makefile/make原始阶段
    • 2.1 开发模式
      • 2.2 公共库统一管理
        • 2.3 业务怎么使用公共库
          • 2.4 小结
          • 三、cmake半开化阶段
            • 3.1 开发模式
              • 3.2 公共库组织
                • 3.3 小结
                • 四、bazel与时俱进
                  • 4.1 引用方式
                    • 4.2 小结
                    • 五、总结
                    • 六、参考
                    相关产品与服务
                    云开发 CloudBase
                    云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
                    http://www.vxiaotou.com