文章目录
- 一、前言
- 二、Hvigor脚本文件
- 三、任务与任务依赖图
- 四、多模块管理
- 4.1 静态配置模块
- 五、分模块编译
- 六、配置多目标产物
- 七、配置APP多目标构建产物
- 八、定义 product 中包含的 target
- 九、拓展阅读
一、前言
编译构建工具DevEco Hvigor
(以下简称Hvigor
)是一款基于TS实现的构建任务编排工具,主要提供任务管理机制,包括任务注册编排、工程模型管理、配置管理等关键能力,提供专用于构建和测试应用的流程和可配置设置。
DevEco Studio
使用构建工具Hvigor
来自动执行和管理构建流程,实现应用/元服务构建任务流的执行,完成HAP/APP的构建打包。
Hvigor
可独立于DevEco Studio
运行,这意味着,可以在DevEco Studio
内、命令行工具或是集成服务器上构建应用。无论从命令行工具或是DevEco Studio
上构建项目,构建过程的输出都将相同。
工程结构定义
Hvigor
将工程解析为一个树形结构,项目为树的根节点,项目中的每个模块为树的叶子节点,树最多为两层,模块中不能包含其他模块,在Hvigor
的定义中统称项目或模块为一个node
(节点)。
在构建最开始的初始化阶段,会通过hvigorconfig.ts
文件以及工程级build-profile.json5
文件中的配置来构造出一个树形结构存储项目的工程结构,工程级build-profile.json5
文件和hvigorconfig.ts
文件均可以配置多模块。
二、Hvigor脚本文件
构建的生命周期中,Hvigor
使用两个脚本文件来完成插件、任务以及生命周期hook的注册:
hvigorconfig.ts
:此文件在整个项目中只有根目录下存在一份,不是构建必须的文件并且默认不存在,如有需要可自行创建,此文件被解析执行的时间较早,可用于在Hvigor
生命周期刚开始时操作某些数据。hvigorfile.ts
:此文件在每个node
下都有一份,是构建的必须文件,在此文件中可以注册插件、任务以及生命周期hook
等操作。
三、任务与任务依赖图
Hvigor
是基于任务对项目进行自动化构建的,任务(Task
)是Hvigor
构建过程中的基本工作单元,它定义了构建项目时需要执行的具体工作。任务可以完成多种操作,比如源码编译任务,打包任务或签名任务等。每一种任务的执行逻辑由插件(plugin)提供,插件可以是由hvigor-ohos-plugin
提供的默认任务逻辑,也可以个性化定制。
需要注意的是,任务是存在依赖关系的,Hvigor
在执行任何任务之前会构建任务依赖图,所有任务会形成一个有向无环图(DAG
),如下示例图,任务之间的依赖关系用箭头进行表示:
hvigor
插件(hvigor-ohos-plugin)和hvigorfile.ts
文件中的构建脚本都将通过任务依赖机制对任务依赖图做出影响。
build-profile.json5
文件分为工程级与模块级,其中buildOption
在工程级文件和模块级文件均可配置,其中相同字段以模块级的字段为准,不同字段模块级的buildOption
配置会继承工程级配置
四、多模块管理
模块是应用/元服务的基本功能单元,包含了源代码、资源文件、第三方库及应用/元服务配置文件,Hvigor
支持工程多模块管理。开发者可在工程下的build-profile.json5
配置文件中增加对应模块信息,即可对模块进行工程绑定和管理,或在hvigorconfig.ts
脚本中动态添加或排除某个模块。同时也支持分模块配置、编译和打包。
4.1 静态配置模块
工程级build-profile.json5
配置文件中"modules
"字段,用于记录工程下的模块信息,主要包含模块名称、模块的源码路径以及模块的 target
信息。target
信息主要用于定制多目标构建产物,更多详细信息可参考配置多目标产物章节。
例如以下目录中存在两个模块目录,可在工程根目录下的build-profile.json5
配置文件,添加模块信息,使得模块与工程进行绑定:
其他配置文件:
oh-package.json5
:应用的三方包依赖配置文件local.properties
: 应用本地环境配置文件obfuscation-rules.txt
: 应用模块的混淆规则配置文件consumer-rules.txt:
库模块默认导出的混淆规则文件,会打包到HAR包中;仅支持HAR模块
工程根目录下的build-profile.json5
文件中模块配置示例:
{
"modules": [
{
"name": "module1", // 模块的名称。该名称需与module.json5文件中的module.name保持一致。在FA模型中,对应的文件为config.json。
"srcPath": "./module1" // 模块的源码路径,为模块根目录相对工程根目录的相对路径
},
{
"name": "module2",
"srcPath": "./module2"
}
]
}
五、分模块编译
Hvigor
支持分模块编译和打包。可以通过以下两种方式进行分模块构建:
-
在
DevEco Studio
中,选中需构建的模块目录后,点击Build
菜单栏下的"Make module 'module1
’",其中"module1"根据具体工程模块名称显示; -
在
DevEco Studio
的Terminal中,指定模块进行编译。比如模块类型为entry
,目标产物target
为default
,构建HAP模块,可执行以下命令:hvigorw --mode module -p product=default -p module=module1@default assembleHap
更多构建HAR/HSP包命令,可参考命令行工具章节。
六、配置多目标产物
通常情况下,应用厂商会根据不同的部署环境,不同的目标人群,不同的运行环境等,将同一个应用定制为不同的版本,如国内版、国际版、普通版、VIP版、免费版、付费版等。针对以上场景,DevEco Studio支持通过少量的代码配置以实例化不同的差异版本,在编译构建过程中实现一个应用构建出不同的目标产物版本,从而实现源代码、资源文件等的高效复用。
在了解HarmonyOS应用的多目标构建产物如何定制前,先了解target
和product
的概念:
工程内的每一个Entry/Feature
模块,对应的构建产物为HAP
,HAP
是应用/元服务可以独立运行在设备中的形态。由于在不同的业务场景中,同一个模块可能需要定制不同的功能或资源,因此引入target
的概念。一个模块可以定义多个target
,每个target
对应一个定制的HAP
,通过配置可以实现一个模块构建出不同的HAP
。
一个HarmonyOS工程的构建产物为APP包,APP包用于应用/元服务发布上架应用市场。由于不同的业务场景,需要定制不同的应用包,因此引入product
概念。一个工程可以定义多个product
,每个
对应一个定制化应用包,通过配置可以实现一个工程构建出多个不同的应用包。
每一个Entry/Feature
模块均支持定制不同的target
,通过在模块中的build-profile.json5
文件中实现差异化定制,当前支持HAP包名、设备类型(deviceType
)、源码集(source
)、资源(resource
)、buildOption
配置项(如C++依赖的.so
、混淆配置、abi
类型、cppFlags
等)、分发规则(distributionFilter
)的定制。
定义目标产物target
每一个target对应一个定制的HAP,因此,在定制HAP多目标构建产物前,应提前规划好需要定制的target名称。例如,以ArkTS Stage
模型为例,定义一个免费版和付费版,模块级build-profile.json5
文件示例如下:
{
"apiType": 'stageMode',
"buildOption": {
},
"targets": [ //定义不同的target
{
"name": "default", //默认target名称default
},
{
"name": "free", //免费版target名称
},
{
"name": "pay", //付费版target名称
}
]
}
按照上述target
的定义,在编译构建时,会同时打包生成default、free和pay三个不同的HAP。
七、配置APP多目标构建产物
APP用于应用/元服务上架发布,针对不同的应用场景,可以定制不同的product
,每个product
中支持对bundleName
、bundleType
、签名信息、icon和label
以及包含的target
进行定制。
定义目标产物product
每一个product
对应一个定制的APP包,因此,在定制APP多目标构建产物前,应提前规划好需要定制的product
名称。例如,定义productA和productB。工程级build-profile.json5
文件示例如下:
"app": {
"signingConfigs": [],
"products": [
{
"name": "default",
"signingConfig": "default",
"compatibleSdkVersion": "5.0.2(14)",
"runtimeOS": "HarmonyOS",
"output": {
"artifactName": "customizedProductOutputName-1.0.0" //产物名称为customizedProductOutputName-1.0.0
},
"vendor": "customizedProductVendorName", //供应商名称为customizedProductVendorName
"bundleName": "com.example00.com" //定义default的bundleName信息
},
{
"name": "productA",
"compatibleSdkVersion": "5.0.2(14)",
"runtimeOS": "HarmonyOS",
},
{
"name": "productB",
"compatibleSdkVersion": "5.0.2(14)",
"runtimeOS": "HarmonyOS",
}
],
"buildModeSet": [
{
"name": "debug",
},
{
"name": "release"
}
]
}
在定制product
时,必须存在"default
"的product
,否则编译时会出现错误。
针对每个定义的product
,均可以定制不同的bundleName
,如果product
未定义bundleName
,则采用工程默认的bundleName
。
如果已配置签名,product
产物对应的APP包名为开发者定制的名称;如果未配置签名,product产物对应的APP包名为开发者定制的名称+unsigned。
八、定义 product 中包含的 target
开发者可以选择需要将定义的target
分别打包到哪一个product
中,每个product
可以指定一个或多个target
。
同时每个target
也可以打包到不同的product
中,但是同一个module
的不同target
不能打包到同一个product
中(除非该module
的不同target
配置了不同的deviceType
或distributionFilter/distroFilter
)。
例如,前面定义了default、free和pay三个target,现需要将default target打包到default product中;将free target打包到productA中;将pay target打包到productB中,对应的示例代码如下所示:
{
"app": {
"signingConfigs": [], //此处通过界面配置签名后会自动生成相应的签名配置,本文略
"products": [
{
"name": "default",
"signingConfig": "default",
"compatibleSdkVersion": "5.0.2(14)",
"runtimeOS": "HarmonyOS",
"bundleName": "com.example00.com"
},
{
"name": "productA",
"signingConfig": "productA",
"compatibleSdkVersion": "5.0.2(14)",
"runtimeOS": "HarmonyOS",
"bundleName": "com.example01.com"
},
{
"name": "productB",
"signingConfig": "productB",
"compatibleSdkVersion": "5.0.2(14)",
"runtimeOS": "HarmonyOS",
"bundleName": "com.example02.com"
}
],
"modules": [
{
"name": "entry",
"srcPath": "./entry",
"targets": [
{
"name": "default", //将default target打包到default APP中
"applyToProducts": [
"default"
]
},
{
"name": "free", //将free target打包到productA APP中
"applyToProducts": [
"productA"
]
},
{
"name": "pay", //将pay target打包到productB APP中
"applyToProducts": [
"productB"
]
}
]
}
]
}
九、拓展阅读
- build-profile.json5
- module.json5配置文件