1@page packageyaml_user_manual 构建配置 package.yaml 2 3**[更正文档](https://gitee.com/alios-things/documentation/edit/rel_3.3.0/yaml/package.yaml_user_manual.md)**      **[贡献说明](https://help.aliyun.com/document_detail/302301.html)** 4 5package.yaml是组件的配置文件,采用yaml文本的方式,配置组件包含哪些源文件,头文件,宏,以及组件依赖关系等等,替代了传统的makefile文件。 6# 构建规则说明 7yaml语法说明:[https://www.ruanyifeng.com/blog/2016/07/yaml.html](https://www.ruanyifeng.com/blog/2016/07/yaml.html)<br />[https://yaml.org/spec/1.2/spec.html](https://yaml.org/spec/1.2/spec.html)<br /> 8<br />yaml格式校验工具:[https://www.bejson.com/validators/yaml_editor/](https://www.bejson.com/validators/yaml_editor/)<br /> 9<br />package.yaml模板生成:<br />在aos**工作目录**下使用。 当用户想把一个源码目录快速变为一个aos组件时,将组件代码复制到aos内相应的组件目录下,然后使用这个命令,会在`<dir>`目录下生成`package.yaml`文件模板,用户可根据需求再适当的调整修改`package.yaml`文件。 10```makefile 11aos convert <dir> 12``` 13 14 15# 构建文件字段说明 16| package.yaml | 必选 | 说明 | 17| --- | --- | --- | 18| | | | 19| **基本信息** | | | 20| name | Y | 包名称 (符合C语言变量命名规则),长度少于等于64字节 | 21| description | Y | 简洁直白用一句完成组件介绍 | 22| version | Y | 组件版本号,**版本号必须与组件代码仓库的branch或者tag保持一致**。 | 23| type | Y | 组件类型,为:<br />solution,board,chip,arch ,drv_core,drv_peripheral, drv_external_device, kernel, common<br />solution组件放在solutions目录下;<br />board,chip,arch组件放在hardware目录下;<br />drv_core,drv_peripheral, drv_external_device组件放在components/drivers目录下;<br />kernel组件放在kernel目录下;<br />common组件放在components目录下。 | 24| tag | N | 组件分类,缺省值: "''。可以写中文,与代码目录结构和编译无关。 | 25| keywords | N | 标签,会影响到组件被搜索的效果,合理的标签很重要 | 26| author | N | 原作者信息和维护人员信息 | 27| license | N | 源代码的许可证,要确保所有代码、文件的许可证不冲突。 | 28| homepage | N | 组件的主页 | 29| | | | 30| **依赖关系** | | | 31| depends<br /> - comp1: "v1.0" | N | 指定该组件依赖的组件及版本,目前仅支持指定版本:如v1.0。后续将支持>=v1.0, >v1.0, ==v1.0, <=v1.0, <v1.0, !=v1.0等,并且需要用“”号括起来。<br />组件的版本请查询组件的package.yaml里面的version字段。<br />**注:对于solution的组件,可以依赖多个board组件。由board_name指定本次构建所采用的组件。** | 32| depends<br /> - comp1: "v1.0 ? <COND>" | N | 条件依赖,当条件COND=1时,才引入该组件。条件由下文的def_config中宏指定。<br />如果该条件未定义,不会引入该组件。<br />注意“”号的写法,包含了版本号和条件。 | 33| aos_version | N | 组件支持的 OS 的基线版本,缺省值:支持所有版本的OS | 34| | | | 35| **板级信息** | | **注:AliOS Things暂时不考虑异构多CPU的情况** | 36| solution板级配置 | | | 37| board_name | Y | 指定开发板组件名,未设置时,使用depends中 board 第一个组件 | 38| cpu_id | Y | cpu编号,固定为cpu0。 | 39| ld_script | N | 链接时使用的 LD 脚本,未设置时,使用对应的 board 的 LD 脚本 | 40| board板级配置 | | | 41| chip_name | Y | 指定芯片组件名 | 42| ld_script | N | 链接时使用 的LD 脚本,未设置时,使用对应的 chip 的 LD 脚本 | 43| chip板级配置 | | | 44| cpu_name | Y | 该芯片使用的 CPU 型号 | 45| ld_script | Y | 链接时使用 的LD 脚本 | 46| arch_name | N | 芯片架构名称 | 47| flash_program | N | 芯片 FLASH 烧写程序 | 48| program_data_files<br /> - filename: 11.bin <br /> address: 0xB32000<br /> - filename: 22.bin <br /> address: 0xB52000 | N | aos burn默认会烧录编译出来的bin文件,如果需要额外烧录其它文件,可以使用program_data_files配置1个或多个文件。<br />filename:文件名<br />address: 烧录起始地址 | 49| toolchain_prefix | N | 编译器前缀,例如:csky-abiv2-elf。未指定时,根据 cpu_name 来推断编译器前缀 | 50| | | | 51| **编译链接信息** | | | 52| include | N | 组件对外的公共头文件所在的目录,只能是该软件包下的目录,**不能使用外部目录,不能使用外部目录,不能使用外部目录**<br />**对外的头文件目录尽量少于3个** | 53| internal_include | N | 组件内部使用的头文件所在的目录 | 54| cflag | N | 该组件 C 编译器所需要要的编译参数 | 55| cxxflag | N | 该组件 C++ 编译器所需要要的编译参数 | 56| asmflag | N | 该组件 汇编 编译器所需要要的编译参数 | 57| define<br /> AAA: 1<br /> STR: "abc" | N | 该组件内的宏定义<br />以**key: value**方式罗列<br />**不支持**后续加条件,如~~AAA: 1 ? <COND>~~ | 58| libs<br /> - lib1.a | N | 该组件中支持的二进制静态库<br />以**数组**方式罗列 | 59| libs<br /> - lib1.a ? <COND><br /> - lib2.a ? <!COND> | N | 根据条件,引入该组件中支持的二进制静态库<br />**仅包含一个条件**,但是可使用**not**逻辑,即!COND,当COND为0时,引入lib1.a<br />**不需要加引号“”;或者整个加引号,如“**lib1.a ? <COND>**”** | 60| libpath | N | 指定静态库所在的路径(相对于该组件路径) | 61| source_file<br /> - src/*.c | N | 指定参与编译的源代码文件,支持通配符,采用相对路径 | 62| source_file<br /> - src/xx.c ? <COND> | N | 根据条件,引入源代码文件<br />仅包含一个条件,但是可使用not逻辑,即!COND,当COND为0时,引入src/xx.c<br />**不需要加引号“”;或者整个加引号,如“**lib1.a ? <COND>**”** | 63| cflag | N | chip、board或者solution组件里的C编译器选项 | 64| cxxflag | N | chip、board或者solution组件里的C++编译器选项 | 65| asmflag | N | chip、board或者solution组件里的汇编编译器选项 | 66| ldflag | N | chip、board或者solution组件里的链接选项 | 67| prebuild_script | N | 组件编译前执行的脚本文件(带参数运行,参数包含toolchain名称,lib库名称,组件defconfig等)<br />脚本文件可**直接运行**,包含x属性,脚本第一行用#!指明运行脚本的程序,如#!/usr/bin/evn python<br /> | 68| postbuild_script | N | 组件编译后执行的脚本文件(带参数运行,参数包含toolchain名称,lib库名称,和组件defconfig等)<br />脚本文件可**直接运行**,包含x属性,脚本第一行用#!指明运行脚本的程序,如#!/usr/bin/evn python | 69| postimage_script | N | 构建image后执行的脚本文件(带参数运行,参数包含toolchain名称,elf名称)<br />脚本文件可**直接运行**,包含x属性,脚本第一行用#!指明运行脚本的程序,如#!/usr/bin/evn python | 70| | | | 71| **配置信息** | | | 72| def_config | N | 组件的可配置项。<br />当 common 组件、chip 组件、board 组件、solution 组件都存在相同配置时,优先顺序为 :solution > board > chip > arch > (drv_core, drv_peripheral, drv_external_device) > kernel > common<br />**上文中所提到的COND,在组件的def_config中定义,取值为0或1** | 73| | | | 74| **安装信息** | | 导出sdk时使用,将头文件和库文件安装到指定目录,提供给二次开发者。 | 75| dest | | 安装的目的路径 dest是相对路径,通常是相对于AOS 安装目录 | 76| source | | 安装源列表,支持通配符,相对路径<br />详细说明请参考《aos-tools用户手册》。 | 77 78 79 80# 附录 81## prebuild、postbuild、postimage脚本示例 82aos-tools可运行外部脚本,并以"--longopt=value"的方式传入参数: 83 84- prebuild_script: 在组件编译之前运行 85- postbuild_script: 在组件编译完成之后运行 86- postimage_script: 在工程构建完成之后运行 87### python版本 88```python 89#!/usr/bin/env python 90import os, sys, re, codecs 91 92params = sys.argv[1:] 93if os.path.isfile(sys.argv[1]): 94 with codecs.open(sys.argv[1], 'r', 'UTF-8') as fh: 95 params = fh.read().split() 96 97# choose those arguments we wanted, and discard others 98key_value = {} 99pattern = re.compile(r'--(.+?)=(.*)') 100for arg in params: 101 if arg.startswith("--"): 102 match = pattern.match(arg) 103 if match: 104 key = match.group(1) 105 value = match.group(2) 106 if key in ["toolchain", "lib", "target"]: 107 key_value[key] = value 108 109print("the script is %s" % sys.argv[0]) 110print("current dir is %s" % os.getcwd()) 111for key in key_value.keys(): 112 print("%s is %s" %(key, key_value[key])) 113 114# ======================================================= 115# do our work 116 117# ======================================================= 118 119# result 120print("run external script success") 121exit(0) 122 123``` 124### shell版本 125```shell 126#!/usr/bin/env bash 127 128if [ "$(uname)" == "Darwin" ]; then 129 os="Darwin" 130elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then 131 os="Linux" 132elif ["$(expr substr $(uname -s) 1 10)"=="MINGW32_NT"];then 133 os="Win32" 134fi 135echo "os is $os" 136 137if [ -f $1 ]; then 138# read arguments from file, and choose those arguments we wanted 139for word in $(<$1) 140do 141 key=$(echo $word | cut -d '=' -f1) 142 if [ "$os" == "Darwin" ]; then 143 value=$(echo $word | cut -d '=' -f2-) 144 elif [ "$os" == "Linux" ]; then 145 value=$(echo $word | cut -d '=' --complement -f1) 146 else 147 value="" 148 fi 149 case "$key" in 150 --toolchain) toolchain=$value;; 151 --lib) lib=$value;; 152 --target) target=$value;; 153 *) echo "discard option $word";; 154 esac; 155done 156else 157# choose those arguments we wanted, and discard others 158until [ $# -eq 0 ] 159do 160 key=$(echo $1 | cut -d '=' -f1) 161 value=$(echo $1 | cut -d '=' --complement -f1) 162 case "$key" in 163 --toolchain) toolchain=$value;shift;; 164 --lib) lib=$value;shift;; 165 --target) target=$value;shift;; 166 *) echo "discard option $1";shift;; 167 esac; 168done 169fi 170 171echo "the script is $0" 172echo "current dir is $(pwd)" 173echo "toolchain is $toolchain" 174echo "lib is $lib" 175echo "target is $target" 176 177# ======================================================= 178# do our work 179 180# ======================================================= 181 182# result 183echo "run external script success" 184exit 0 185 186``` 187## 制作二次开发SDK 188 189- 编写package.yaml 190 191 在各个组件内部,将需要导出的h文件和预编译库添加到package.yaml的install部分。添加规则如下:<br />例如某个组件A的实际的文件列表如下: 192```tree 193compa 194├── package.yaml 195├── README.md 196├── src 197│ ├── aaa.c 198│ ├── bbb.c 199│ ├── ccc.c 200│ └── ddd.c 201├── include 202│ ├── aaa.h 203│ ├── bbb.h 204│ └── fff 205│ └── ccc.h 206└── interal_include 207│ └── ddd.h 208└── prebuilt 209 └── libeeeee.a 210``` 211的 `build_confg`部分指定了对外头文件和预编译库: 212```yaml 213build_config: 214 include: 215 - include/ 216 libs: 217 - eee 218 libpath: 219 - prebuilt 220``` 221那么install部分如下,其中头文件都放在Include目录下,预编译库都放在lib目录下。 222```yaml 223install: 224 # copy aaa.h bbb.h to aos_sdk/include 225 - dest: "include" 226 source: 227 - *.h 228 # copy fff/ccc.h to aos_sdk/include/fff 229 - dest: "include/fff" 230 source: 231 - fff/*.h 232 # copy drivers/libmcuhaas1000.a to aos_sdk/lib/libmcuhaas1000.a 233 - dest: "lib" 234 source: 235 - prebuilt/libeee.a 236``` 237 238- 在solution目录下执行编译,aos make,编译成功后会将组件编译生成的静态库自动放到aos_sdk/lib目录下。 239- 在solution目录下执行导出,aos sdk,将组件对外头文件和预编译库复制到aos_sdk里的include和lib目录下。 240- 删除out目录,将当前solution目录打包,提供给其他开发者做二次开发。 241## <COND>条件 242在`package.yaml`里面添加组件依赖,或者添加源文件,或者添加预编译库时,经常会使用条件。仅当条件满足时,才引入某个组件,或者添加某个文件,或者添加某个预编译库等等。 243### 单条件 244``` 245depends: 246 - comp1: "v1.0 ? <COND1>" 247source_file: 248 - src/xx.c ? <COND2> 249libs: 250 - lib1.a ? <COND3> 251``` 252此处<>中的内容即条件,是当前组件或其他组件里的`def_config`所定义的宏。当宏为1时,表示条件成立,执行相应的操作:引入某个组件等等。当宏为0,或者未定义时,则不执行相应的操作。 253### 非条件 254``` 255depends: 256 - comp1: "v1.0 ? <!COND1>" 257source_file: 258 - src/xx.c ? <!COND2> 259libs: 260 - lib1.a ? <!COND3> 261``` 262支持使用`!`做逻辑非操作。一个未定义的宏,如果前面加了`!`,则表示条件成立。 263### 与条件 264``` 265depends: 266 - comp1: "v1.0 ? <COND1, COND4, !COND5>" 267source_file: 268 - src/xx.c ? <COND2, COND6> 269libs: 270 - lib1.a ? <COND3, !COND7> 271``` 272支持使用`,`号分隔多个条件,做逻辑与操作,即所有条件都满足,才执行相应的操作。其中每个条件可以加`!`号,做逻辑非操作。 273### 或条件 274``` 275depends: 276 - comp1: "v1.0 ? <COND1>" 277 - comp1: "v1.0 ? <COND4>" 278 - comp1: "v1.0 ? <!COND5>" 279source_file: 280 - src/xx.c ? <COND2> 281 - src/xx.c ? <COND6> 282libs: 283 - lib1.a ? <COND3> 284 - lib1.a ? <!COND7> 285``` 286没有显式使用逻辑或操作的方式。可以参考上面的例子中,将需要或的条件拆成单独一行。 287