hi,你好!欢迎访问本站!登录
本站由简数采集腾讯云宝塔系统阿里云强势驱动
当前位置:首页 - 教程 - 杂谈 - 正文 君子好学,自强不息!

高德引擎构建及延续集成手艺演进之路

2019-11-18杂谈搜奇网41°c
A+ A-

 

01 背景

由于导航运用中的舆图衬着、导航等中心功用对机能请求很高,所以高德舆图客户端中大批功用采纳 C++ 完成。跟着营业的飞速生长,仅舆图引擎库就有40多个模块,工程设置极为庞杂,原有的构建及延续集成手艺已没法满足日益增长的需求变化。

除了以百万计的代码行数带来的庞杂度外,高德舆图客户端中的 C++ 引擎库工程(以下简称引擎库)的构建和延续集成还面临以下几个应战:

  • 支撑多团队合作:多团队意味着多操纵体系多 IDE ,下降差别操纵体系和差别 IDE 下的工程设置的难度是重点要处置惩罚的困难之一;
  • 支撑多营业线定制:引擎库为手机、车机、开放平台等营业线供应支撑,而各个营业线的诉求差别,所以须要具有按功用构建的才能;
  • 支撑车机环境:在诸多营业线中,高德舆图有一个异常特别的营业线,即车机(AMAP AUTO)。车机直接面临各大车厂和浩瀚装备商,环境多为定制化,构建东西链形形色色。假如针对每一个车机环境都定制一套构建设置文件,那末其保护本钱将异常高,所以怎样用一套构建设置满足车机的多样化构建需求成为亟需处置惩罚的题目;

别的,由于汗青缘由,引擎库中源码和依靠库混淆,都存放于 Git 堆栈中,如许会带来两个题目:

  • 跟着构建次数不停增添,Git 堆栈越来越大,代码与依靠库检出越来越慢,极大影响当地开辟以及打包效力;
  • 缺少统一治理,依靠关联杂沓,经常涌现由于依靠题目而致使的构建失利,或许虽然构建胜利但运转时发作毛病的状况;

上述的应战和汗青遗留题目严峻障碍了研发效能的提拔。为此,我们对现有的构建及延续集成东西举行了深切的研讨和剖析,并连系本身的营业特征,终究生长出高德舆图 C++ 当地构建东西 Abtor 和延续集成东西 Amap CI 。

 

02 当地构建

 

现有东西剖析

 

C++ 是一门接近底层的言语。差别的硬件、操纵体系、编译器,再加上交织编译,致使 C++ 构建的难度异常高。针对这些题目,C++ 社区涌现出很多优异的构建东西,比方赫赫有名的 Make 和 CMake 。

Make,即 GNU Make ,于1988年宣布,是一个用来实行 Makefile 的东西。Makefile 的基本语法包含目标、依靠和敕令等。运用过程当中,当某些文件变了,只要直接或许间接依靠这些文件的目标才须要从新构建,如许大大提拔了编译速率。

Make 和 Makefile 的组合可以看做项目治理东西,但它们过于基本,在跨平台的运用方面有很高的门坎和较多的限定,别的大项目标构建还会碰到 Makefile 严峻膨胀的题目。

CMake 发生于2000年,是一个跨平台的编译、测试以及打包东西。它将设置文件转化为 Makefile ,并运转 Make 敕令将源码编译成可实行递次或库。CMake 属于 Make 系列,设置文件比 Makefile 具有可读性,支撑跨平台构建,构建机能高。

然则 CMake 也有两项显著不足,一是设置文件的庞杂度远高于别的当代言语,关于 CMake 语法初学者有肯定的进修本钱,二是与差别 IDE 的合营运用不够友爱。

可以看出 Make 和 CMake 的笼统度照样比较低,从而对构建职员的请求太高。为了下降构建本钱,C++ 社区又涌现了一些新的 C++ 构建东西,如今运用较普遍的包含 Google 的 Bazel 和 Ninja ,以及 SCons 。这些东西的特性和不足以下:

经由上述对现有 C++ 构建东西的研讨和剖析,可以得出每一个东西既有所长又有不足的结论。再考虑到高德舆图引擎库工程面临的应战和汗青遗留题目,我们发明以上东西没有一个可以圆满符合营业需求,且革新本钱异常高,所以我们决议基于 CMake 自建 C++ 当地构建东西,即如今引擎库工程运用的 Abtor 。

Abtor

起首,我们须要诠释一个题目,即 Abtor 是什么?

Abtor 是一个 C++ 跨平台构建东西。Abtor 采纳 Python 编写构建剧本,生成 CMake 设置文件,并经由过程内置 CMake 组件生成构建文件,终究产出可实行递次或库。它笼统出构建形貌,使得庞杂的编译器和连接器对开辟者通明;它供应壮大的内置功用,从而有用的下降开辟者编写构建剧本的难度。

其次,我们须要论述一个题目,即Abtor的构建流程是什么?

如上图所示,Abtor 构建的全部流程为:

  • 编写 Abtor 构建剧本;
  • 剖析 Abtor 构建剧本;
  • 检测依靠关联,辨认争执,并从阿里 OSS 上下载所需依靠;
  • 生成CMakeLists.txt,并经由过程内置的 CMake 生成 Makefile 文件;
  • 编译,链接,生成对应平台的目标文件;
  • 将目标文件宣布到阿里 OSS ;

除此之外,还增添了掌握接见宣布库权限的功用,用于保证宣布库的平安。

末了,我们须要讨论一个题目,即Abtor处置惩罚了什么?

在开篇背景中,我们提到障碍研发效能的一些应战和题目,这就是 Abtor 须要处置惩罚的,所以 Abtor 具有以下特性:

  • 更普遍的跨平台:支撑 MacOS 、iOS、Android、 Linux、Windows、QNX 等平台;
  • 有用的多团队合作:较好得与 IDE 连系,并支撑一套设置生成差别项目工程,从而到达工程设置一致化;
  • 高定制化:支撑东西链及构建参数的天真定制,并经由过程内置东西链设置为车机庞杂的构建供应强有力的支撑;
  • 源码与依靠星散:支撑源码依靠与库依靠,源码经由过程Git治理,构建库存放于阿里云,源码与产品完整星散;
  • 优越的构建机能:疾速构建大型项目,从而进步开辟效力;

从上述特性可看到,Abtor 有用地处置惩罚了已有的构建东西在高德营业中面临的痛点。然则冰冻三尺,非一日之寒,Abtor 也是在不停地完美中,下面重点引见一下 Abtor 生长过程当中碰到的三个题目。

工程设置一致化

在一样平常开辟过程当中,工程项目标调试事变尤其主要。高德舆图客户端中的 C++ 引擎库工程的开辟职员触及几个部门和诸多小组。这些组善于的手艺栈,运用的平台和习气的开辟东西都大为差别。假如针对每一个平台都零丁竖立响应的工程设置,那末事变量及后续保护本钱可想而知。

基于以上缘由,Abtor 内置与 IDE 连系的功用,即开辟者可以经由过程一套设置并连系 Abtor 敕令一键生成工程设置,完成在差别平台的工程设置的一致化。工程设置一致化为引擎库开辟带来以下几个收益:

  • 敕令简朴,下降进修本钱,开辟者只需熟记 abtorw project [IDE name];
  • 设置文件不会由于 IDE 的增添而敏捷膨胀,开辟者替换构建敕令,比方 abtorw project xcode 或许abtorw project vs2015,即可生成对应的项目工程;
  • 有利于部门间的合作及新人的疾速融入,开辟者可以依据喜欢挑选 IDE 举行开辟,大大进步开辟效力;
  • 现在Abtor支撑的IDE有 Xcode、Android Studio、Visual Studio、Qt Creator、CLion等。

 

庞杂车机环境的构建

 

作为高德舆图一条异常主要的营业线,车机面临的构建环境庞杂多变,厂商往往会自行定制东西链。假如每接入一个装备,一切工程项目都须要修正设置文件,那末这个本钱照样异常高的。为了处置惩罚这个题目,Abtor 供应两种做法:

  • 内置东西链设置:关于开辟者完整通明,他不须要修正任何设置即可构建响应平台的产品;
  • 支撑自定义设置插件:开辟者根据划定规矩编写设置插件,构建时 Abtor 会检测插件,并依据设置的东西链及构建参数举行构建;

除此之外,我们对一切的车机环境举行了 Docker 化处置惩罚,并经由过程 Docker 掌握中心统一治理车机 Docker 环境的上线与下线,再应用上述 Abtor 的内置东西链设置功用内置车机构建参数,完成开辟者无感知的环境切换等操纵,有用地处置惩罚了庞杂车机环境的构建题目。

基于 Docker 的车机构建主要步骤以下:

  • 东西链装置:平常由厂商供应,我们会将该东西链装置到基本 Docker 镜像中;
  • Docker 宣布:将镜像宣布到 Docker 堆栈;
  • Abtor 适配:一次性适配东西链,并内置设置,开辟者可经由过程 Abtor 版本升级运用该设置;
  • 效劳设置更新:由 Jenkins 治理,支撑分批更新 Abtor 版本,不影响当下编译需求;
  • 效劳监控: 由 Jenkins 治理,定时检测效劳状况,异常态的 Docker 效劳将自动被重启;

基于Docker的车机构建关联图以下:

依靠治理

依靠题目是一切构建东西都避免不了的题目,在这个中,菱形依靠题目尤其罕见。以下图所示,假定 A 依靠了 B 和 C ,B 和 C 又离别依靠了差别版本的 D,而 D 之间只存在很小的差别,这是可以编译经由过程的,但终究在运转时可能会涌现意想不到的题目。

假如没有一种机制来检测,菱形依靠是很难被发明,而发生的效果又多是异常严峻的,比方致使线上涌现大面积的崩溃等。所以依靠题目标剖析与处置惩罚异常主要。

当下,市面上 Java 有比较成熟的依靠治理处置惩罚计划,如 Maven 等,但 C++ 并没有。为此 Abtor 特地竖立依靠治理的机制来确保编译的正确性。

Abtor 的依靠治理是怎样做的呢?这里供应一个思绪供人人参考:

  • 竖立 Abtor 效劳端,用做库宣布,以及处置惩罚依靠关联;
  • 每一个库在云端构建完,都邑把库依靠的版本信息存放于云端数据库中;
  • 当地/云端构建前 Abtor 会剖析出一切依靠库的版本信息;
  • 递归查找这些子库对应的依靠信息,即可罗列出一切依靠库的信息;
  • 检测依靠库列表中是不是存在差别版本号的雷同库名:
  • 假如没有雷同库名,则继承实行构建;
  • 假如有雷同库名,则申明依靠库之间存在争执题目,此时中断构建,并显现争执的库信息,待开辟者处置惩罚完争执后方可继承实行构建;

依据上述思绪,我们保证了库依靠的一致性,避免了菱形依靠题目。别的,假如某个库被别的库所依靠且有更新,那末依靠它的库也应当随之构建,以确保依靠的一致性。这类对依靠构建的触发更新我们放到 Amap CI 上完成,在第三节会举行细致引见。

工程实践

在引见完 Abtor 的一些基本道理后,我们将引见 Abtor 在一样平常开辟中是怎样运用的。

下图是 Abtor 工程项目标目次构造,个中有两类文件是开辟者须要体贴的,一类是源文件目次(src),一类是 Abtor 中心设置文件(abtor.proj)。

abtor_demo
├── ABTOR
│   └── wrapper
│       ├── abtor-wrapper.properties # 设置文件,可指定Abtor版本信息
│       └── abtor-wrapper.py         # 下载Abtor版本并挪用Abtor进口函数
├── abtor.proj                       # Abtor中心设置文件
├── abtorw                           # Linux/Mac下的初始实行剧本
├── abtorw.bat                       # Windows下的初始实行剧本
└── src
    └── main.c                       # 要编译的源文件

 

源文件目次的构造形式与 Make 系列构建东西没有太大区分。下面重点看一下Abtor中心设置文件:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

# 以下内容为python语法

# 指定编译的源码
header_dirs_list = [abtor_path("include")]    # 依靠的头文件目次
binary_src_list = [abtor_path("src/main.c")]  # 源码

cflags = " -std=c99 -W -Wall "
cxxflags = " -W -Wall "

# 指定编译二进制
abtor_ccxx_binary(
  name = 'demo',
  c_flags = cflags,
  cxx_flags = cxxflags,
  deps = ["add:1.0.0.0"],                        # 指定依靠的库信息
  include_dirs = header_dirs_list;
  srcs = binary_src_list
)
 

从上图可以看出,Abtor中心设置文件具有以下几个特性:

  • 采纳Python编写,易上手;
  • 笼统相似 abtor_ccxx_binary 等的构建形貌,下降运用门坎;
  • 供应诸如 abtor_path 等的内置功用,进步开辟效力;

经由过程以上的对源文件目次构造及 Abtor 中心设置文件编写,我们就完成了项目标Abtor设置化,接着可以经由过程Abtor内置的敕令构建、宣布或直接生成项目工程。我们置信,纵然开辟者不是很通晓构建道理,依旧可以无障碍地运用Abtor举行构建与宣布。

 

03 延续集成

 

面临的题目

以下图所示,全部开辟事变流程可分为几个阶段:编码->构建->集成->测试->托付->布置。在运用Abtor处置惩罚当地构建碰到的一系列应战与题目后,我们最先将眼光转移到了全部延续集成阶段。

 

 

延续集成是指软件个人研发的部份向软件团体部份托付,频仍举行集成以便更快地发明个中的毛病。它源自极限编程(XP),是 XP最初的12种实践之一。关于引擎库来讲,延续集成计划应当具有一次性批量构建差别平台差别架构目标文件的才能,同时也应当具有运维治理和音讯治理的才能等。

最初高德引擎库运用 Jenkins 举行延续集成。由于引擎库开辟采纳在 Git 堆栈上拉取分支的体式格局举行版本治理,所以每次版本迭代都须要手动竖立 Jenkins Job,修正响应剧本,别的还须要分外搭建一个依靠库关联的 Jenkins Job 做联动编译。

假定有100个项目,那末每一个版本迭代都须要手动建立101个 Jenkins Job 。每次版本迭代都反复相似的操纵,中心须要大批的谐和事变,跟着迭代版本越来越多,这些 Jenkins Job 变得不可保护。这是 Jenkins 延续集成计划在高德引擎库开辟过程当中碰到的异常严峻的题目。

基于上述缘由,我们迫切得须要如许一个延续集成体系:开辟者不必保护Jenkins,不须要布置构建环境,可以不相识构建细节,只须要经由过程某个触发事宜就可以构建出一切平台的目标文件。因而我们决议自建延续集成平台,即 Amap CI。

Amap CI

Amap CI 平台运用Gitlab的Git Webhook完成延续集成。个中,Gitlab 吸收开辟者的 tag push 事宜,回调 CI平台的背景效劳,然后背景效劳依据构建机械的运转状况举行使命的分发。当构建使命较多时,CI平台会守候直到有构建资本才举行使命的再分派。

Amap CI 平台由使命治理、Jenkins治理、构建治理、关照治理、网页前端展现等几部份构成,团体架构图以下:

 

 

经由过程 Amap CI 平台,我们到达了以下几个目标:

  • 可扩容:一切构建机械经由过程注册的体式格局接入,构建机械扩容变得异常轻易,减轻构建峰值带来的压力;
  • 可视化:Abtor Server 关于开辟者是通明的。CI 平台与 Abtor Server 交互,为开辟者供应争执搜检、依靠检察及库下载等可视化功用;
  • 智能化: CI 平台内置规范的 Jenkins Job 构建模板。开辟者不感知这些模板,也不必做任何的修正。他们只须要经由过程 Git 提交一个 tag 信息即可完成全平台的构建,从而完成一键打 tag 构建;
  • 自动化:效劳剖析 Gitlab hook tag 的 push 信息并拉取代码,然后剖析对应的设置文件和要构建的一切平台信息。依据这些信息CI平台分派构建机械,并实行 Abtor 敕令举行构建与宣布。一切这些皆自动完成;
  • 立即性:构建启动后会发送钉钉音讯,音讯除了提要信息外还附加了构建的链接等,开辟者可以点击链接跟踪进度状况。构建胜利或失利也都邑发送音讯,从而使得开辟者可以实时举行下一步事变或处置惩罚构建毛病;
  • 可扩大:CI平台供应可扩大的对接体式格局,轻易高德或阿里的别的平台对接,比方泰坦平台、CT平台、Aone等,从而完成编码、构建、测试和宣布的开辟闭环;

在上述目标中,对 Amap CI 平台最主要的是自动化,下面我们重点引见一下自动化中的整树联动编译。

整树联动编译

在第二部份中我们提到了一个题目,即假如某个库被别的库所依靠且有更新,那末依靠它的库也应当随之构建,以确保依靠的一致性,这是构建自动化的症结点之一。Amap CI 采纳整树联动编译的计划来处置惩罚这个题目。

开辟者在CI平台上竖立对应的版本构建立,构建立中罗列了各个库之间的构建递次,以下图所示。CI平台会依据这棵构建立举行构建,被依靠的库优先构建,完成后再自动触发其上级的库构建,以此类推,终究构成一棵多叉树。在这棵多叉树上,从叶子节点最先按层级递次逐级并发构建对应的库,这就是整树联动编译。

依据上述思绪,我们保证了延续集成时的依靠一致性。开辟者只需体贴本身担任的库,打个 tag ,即可触发作成一切依靠该库的库,从而避免了依靠不一致的题目。

工程实践

在引见完 Amap CI 的一些基本道理后,我们将引见一样平常开辟中应当怎样运用Amap CI。

一个新的工程项目在集成到 Amap CI 平台时,起首须要将CI平台的 web hook 网址增添到 Gitlab 的设置中,然后编写设置文件 CI_CONFIG.json ,至此一个新的项目已集成完成,异常简朴。下面我们重点引见一下 CI_CONFIG.json 。

CI_CONFIG.json 是中心设置文件,一次编写,无需再修正。它的构造以下:

CI_CONFIG.json DEMO:(json)
{
    "mail":"name@alibaba-inc.com",                    # 邮件关照
    "arch":"Android,iOS,Mac,Ubuntu64,Windows",        # 构建的平台
    "build_vars":"-v -V",                             # 构建参数
    "modules":{                                       # 构建的模块列表
        "amap":{                                      # 模块名为amap
            "features":[                              # 功用列表
                {
                    "name":"feature1",                # 设置功用名为feature1
                    "macro":"-DFEATURE_DEMO1=True"    # 宏控:FEATURE_DEMO1
                },
                {
                    "name":"feature2",               # 设置功用名为feature2
                    "macro":"-DFEATURE_DEMO2=True"   # 宏控:FEATURE_DEMO2
                }
            ]
        },
        "auto":{                                    # 模块名为auto
            "features":[                            # 功用列表
                {
                    "name":"feature1",              # 设置功用名为feature1
                    "macro":"-DFEATURE_DEMO1=True"  # 宏控:FEATURE_DEMO1
                },
                {
                    "name":"feature3",             # 设置功用名为feature3
                    "macro":"-DFEATURE_DEMO3=True" # 宏控:FEATURE_DEMO3
                }
            ]
        }
    }
}

 


从上图可以看出,设置文件形貌了邮件关照、构建的平台、构建参数等信息,同时还为多营业线定制供应了优越的支撑。
Amap CI 构建时读取上述文件,剖析差别项目中设置的宏,并经由过程参数传递给 Abtor ,另一方面开辟者在代码中应用这些宏举行代码断绝,构建时会依据这些宏挑选对应的源码举行编译,从而支撑多条营业线差别的需求,到达代码层面的最大复用。

 

现在 Amap CI 接入的项目数有几百个,编译的次数到达几十万次级别,同时在构建机能和构建胜利率方面比拟之前都有了大幅度的进步,如今依旧不停有新的项目接入到构建平台上。可以说 Amap CI 平台是高德舆图客户端 C++ 工程疾速迭代开辟的坚固保证。

 

04 将来瞻望

 

从2016年年中调研现有构建东西算起,到如今三年有余。三年很长,足以让我们将设想变成实际,足以让我们不停完美 Abtor ,足以让我们生长出 Amap CI 。三年又很短,关于一个体系开辟生命周期而言,这仅仅是抽芽阶段,我们的征途才刚刚最先。

 

关于将来,我们的计划是向开辟闭环方向生长,即买通编码、构建、集成、测试、托付和布置等各个环节中的链路,处置惩罚营业开辟闭环的题目,完成全部开辟流程自动化,进一步把开辟者从烦琐的流程中解放出来,使得这些职员有精神去做更有代价的事变。

 

  选择打赏方式
微信赞助

打赏

QQ钱包

打赏

支付宝赞助

打赏

  移步手机端
高德引擎构建及延续集成手艺演进之路

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
未定义标签

本文来源:搜奇网

本文地址:https://www.sou7.cn/282396.html

关注我们:微信搜索“搜奇网”添加我为好友

版权声明: 本文仅代表作者个人观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。请记住本站网址https://www.sou7.cn/搜奇网。

发表评论

选填

必填

必填

选填

请拖动滑块解锁
>>