#夏日挑战赛#OpenHarmony编译运行基础及简单实践
一、基础知识
1. 术语
- 组件:可复用的软件单元,它可包含源码、配置文件、资源文件和编译脚本等
- GN:generate ninja的缩写,产生构建项目的ninja文件
- Ninja:是一个比Make更快速的小型构建系统;Ninja is a small build system with a focus on speed
2. GN & Ninja
OpenHarmony的编译构建子系统,基于GN和Ninja搭建。GN和ninja结合起来,完成OpenHarmony操作系统的编译任务。
GN是一种元构建系统,可以生成Ninja构建文件(Ninja build files),最早应用于Chromium项目,目的是取代GNU-Make。这种构建方式有如下优势:
- 可读性更好,更容易编写和维护。
- 速度更快,谷歌官方给的数据是20倍的速度提升。
- 修改GN文件后,执行Ninja构建时会自动更新Ninja构建文件
如果把GN比喻成“针线”,把生成的Ninja文件比喻成“衣服”的“设计图纸”,那么整个编译构建的过程,就是依靠“针线”和“设计图纸”,把“衣服”完整地做出来。
编译构建流程如下: - 读取开发板配置:主要包括开发板使用的编译工具链、编译链接命令和选项等
- 调用gn: 调用gn gen命令,读取产品配置(主要包括开发板、内核、选择的组件等)生成解决方案out目录和ninja文件
- 调用ninja:调用ninja -C out/company/product启动编译
- 系统镜像打包:将组件编译产物打包,制作文件系统镜像
3. QEMU
QEMU是“Quick Emulator”的缩写。
QEMU是一个广泛使用的开源计算机模拟器和虚拟机。QEMU作为模拟器时,可以在一种架构(如x86 PC)下运行另一种架构(如ARM)下的操作系统和程序。
虚拟机是在一个硬件平台上运行多个操作系统,在虚拟机中程序的指令一般就是宿主机的指令集。
模拟器则是通过软件,将模拟出的硬件平台的指令转换为宿主机的指令集。例如,在下面QEMU的实验中,就是在PC的docker运行环境中,模拟了arm_mps2_an386硬件平台,该平台的配置为:
- arm cortex-m4架构
- 1个CPU
- 16M内存
二、在QEMU中模拟运行liteos-m内核测试程序
1. 将gitee代码导入docker中的工程
从gitee下载kpkernel_demo.zip,解压后使用docker cp命令拷贝进docker
docker cp D:\test_harmony\kpkernel_demo 5fbe7dcc94d7:/home/openharmony/device/qemu/arm_mps2_an386/liteos_m/board
2. 修改task_example示例
修改kpkernel_demo上一级目录的BUILD.gn
修改kpkernel_demo目录下的BUILD.gn
修改kpkernel_demo上一级目录的main.c
3. 设置OpenHarmony源码目录和要编译的产品
在VS Code终端输入 hb set,选择qemu_mini_system_demo
输入hb build -f,根据配置信息生成编译指导文件build.ninja,然后进行编译
4.运行示例
在终端输入 ./qemu-run ; 按ctrl-A 后,按X 停止QEMU运行
三、在启航(qihang)开发板上运行程序
1. 将gitee代码导入docker工程
确认docker环境git配置信息正确设置
- docker环境中/root/.ssh/目录中的密钥与gitee设置一致
- 配置docker环境中的gitee用户信息
git config --global user.name "your gitee name"
git config --global user.email "your gitee email"
进入docker环境中的qihang板目录,从gitee仓库clone应用代码
clone成功后,可以看到在device目录下新增了qihang_app目录
2. 修改测试代码
修改/home/openharmony/vendor/isoftstone/qihang/BUILD.gn
修改app\BUILD.gn
import("//build/lite/config/component/lite_component.gni")
#指示编译构建子系统去完成类型为lite_component的、名为qihang_app的构建目标
lite_component("qihang_app") { #构建目标的名称与vendor对应开发板目录下BUILD.gn指示的一致
features = [
"01GPIO:gpio_example", #目录名:静态库名
]
}
lite_component这种类型是在lite_component.gni定义的,用于指示编译构建子系统去编译构建一个组件
修改app\01GPIO\BUILD.gn
static_library("gpio_example") { #静态库名,与上一级BUILD.gn一致
sources = [
"KP_KEY_led/key_led.c", #源文件
]
include_dirs = [ #头文件
"//utils/native/lite/include",
"//kernel/liteos_m/kal",
"//base/iot_hardware/peripheral/interfaces/kits",
]
}
文件app\01GPIO\KP_KEY_led\key_led.c
static void LedExampleEntry(void)
{
attr.name = "LedTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = LED_TASK_STACK_SIZE;
attr.priority = LED_TASK_PRIO;
if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL) {
printf("[LedExample] Falied to create LedTask!\n");
}
}
SYS_RUN(LedExampleEntry);
3. 设置要编译的产品
在VS Code终端输入 hb set,选择qihang
输入hb build -f,编译
- 编译成功后,在目录 /home/openharmony/out/qihang/qihang 输出过程文件及烧录到板端运行的文件Hi3861_wifiiot_app_allinone.bin
- 使用docker cp命令,将bin文件拷贝到windows目录中,使用Hiburn程序进行烧录
四、参考索引
1.构建系统编码规范与最佳实践
https://docs.openharmony.cn/pages/v3.1/zh-cn/device-dev/subsystems/subsys-build-gn-coding-style-and-best-practice.md/
2.标准系统编译构建指导
http://open.weharmonyos.com/zh-cn/device-dev/subsystems/subsys-build-standard-large.html