HarmonyOS Next构建工具 lycium 原理介绍

HarmonyOS Next构建工具 lycium 原理介绍

在这里插入图片描述

背景介绍

HarmonyOS Next中很多系统API是以C++接口提供,如果要使用C++接口,必须要使用NAPI在ArkTS与C++间交互,这种场景在使用DevEco-Studio中集成的交叉编译工具,以及cmake构建工具就完全够用了。但是针对一些三方库迁移的场景,比如ffmpeg、openssl等,如果自己配置编译环境和脚本比较麻烦,进行交叉编译的过程中较关注的问题是:不同编译构建方式如何进行交叉编译、不同的编译构建平台如何配置交叉编译的环境、不同的交叉编译架构如何配置以及交叉编译后的产物如何进行测试验证。当前开源的C/C++三方库编译方式多样化,以下为主流的几种交叉编译方式:

  • cmake 编译构建。
  • configure 编译构建方式。
  • make 编译构建。
    官方提供了交叉编译构建工具lycium,帮助我们快速构建三方库。

lycium工具介绍

lycium是一款协助开发者通过shell语言实现C/C++三方库快速交叉编译,并在OpenHarmony 系统上快速验证的编译框架工具。开发者只需要设置对应C/C++三方库的编译方式以及编译参数,通过lycium就能快速的构建出能在OpenHarmony 系统运行的二进制文件。

lycium的构建原则是移植过程,不可以改源码(即不patchc/cpp文件,不patch构建脚本)。如移植必须patch,patch必须评审,给出充分理由。(不接受业务patch)

lycium构建工具地址:https://gitee.com/openharmony-sig/tpc_c_cplusplus

使用示例

  1. 编译环境准备:lycium框架支持多种构建方式的三方库,为了保障三方库能正常编译,我们需要保证编译环境中包含以下几个基本编译命令: gcc, cmake, make, pkg-config, autoconf, autoreconf, automake, 如若缺少相关命令,可通过官网下载对应版本的工具包,也可以在编译机上通过命令安装,如若Ubuntu系统上缺少cmake可以通过以下命令安装:sudo apt install cmake
  2. 修改三方库的编译方式以及编译参数,lycium框架提供了HPKBUILD文件供开发者对相应的C/C++三方库的编译配置。具体方法:
    • 在thirdparty目录下新建需要共建的三方库名字pkgname。
    • 将HPKBUILD模板文件拷贝到新建三方库目录下。
    • 根据三方库实际情况修改HPKBUILD模板,文件修改可参考minizip共建。
  3. 快速编译三方库:配置完三方库的编译方式参数后,在lycium目录执行./build.sh pkgname,进行自动编译三方库,并打包安装到当前目录的 usr/pkgname/
    ARCH 目录./build.sh # 默认编译 thirdparty 目录下的多有库,也可以:./build.sh aaa bbb ccc ... # 编译 thirdparty 目录下指定的 aaa bbb ccc ...库 当 aaa 库存在依赖时,必须保证入参中包含依赖,否则 aaa 库不会编译

lycium框架是通过linux shell脚本语言编写的,接下来我们分析构建工具的shell代码,理解构建流程,有助于帮助我们定位编译时遇到的失败问题。

构建脚本原理介绍

lycium框架主要由以下几个部分组成:

  1. HPKBUILD 构建配置
  2. 顶层构建脚本 build.sh
  3. 交叉编译工具链
  4. 测试验证环境
构建流程
1. 构建配置准备

开发者需要在 thirdparty 目录下为待编译的三方库创建目录,并编写 HPKBUILD 构建配置文件。HPKBUILD 文件定义了:

  • 源码获取方式
  • 编译参数配置
  • 依赖关系声明
  • 安装规则

HPKBUILD构建配置文件示例:

# Contributor: Jeff Han <hanjinfei@foxmail.com>
# Maintainer: Jeff Han <hanjinfei@foxmail.com>
pkgname=FFmpeg
pkgver=n6.0
pkgrel=0
pkgdesc="FFmpeg is a collection of libraries and tools to process multimedia content such as audio, video, subtitles and related metadata."
url="https://github.com/FFmpeg/FFmpeg/"
archs=("armeabi-v7a" "arm64-v8a")
license=("GPL2" "GPL3" "LGPL3" "MIT" "X11" "BSD-styl")
depends=("rtmpdump" "openssl_1_0_2u")
makedepends=()
source="https://github.com/FFmpeg/$pkgname/archive/refs/tags/$pkgver.tar.gz"autounpack=false
downloadpackage=true
buildtools="configure"builddir=$pkgname-${pkgver}
packagename=$builddir.tar.gz
source envset.sh
buildhost=true
arch=
ldflags=prepare() {if [ "$LYCIUM_BUILD_OS" == "Linux" ]thenhostosname=linuxelif [ "$LYCIUM_BUILD_OS" == "Darwi" ]thenhostosname=darwinelseecho "System cannot recognize, exiting"return -1fiif [ $buildhost == true ]thentar -zxf $packagenamecd $builddir./configure --enable-static --enable-shared --disable-doc --disable-htmlpages \--target-os=$hostosname --disable-optimizations --prefix=`pwd`/hostbuild > $publicbuildlog 2>&1$MAKE >> $publicbuildlog 2>&1$MAKE install >> $publicbuildlog 2>&1export LD_LIBRARY_PATH=`pwd`/hostbuild/lib:$LD_LIBRARY_PATHsed -i.bak 's/include $(SRC_PATH)\/tests\/fate\/source.mak/#include $(SRC_PATH)\/tests\/fate\/source.mak/g' tests/Makefile$MAKE check >> $publicbuildlog 2>&1ret=$?buildhost=falsecd $OLDPWDfimkdir $pkgname-$ARCH-buildtar -zxf $packagename -C $pkgname-$ARCH-buildcd  $pkgname-$ARCH-build/$builddirpatch -p1 < ../../FFmpeg_oh_test.patchcd $OLDPWDif [ $ARCH == "armeabi-v7a" ]thensetarm32ENVarch=armldflags="-L${OHOS_SDK}/native/sysroot/usr/lib/arm-linux-ohos"elif [ $ARCH == "arm64-v8a" ]thensetarm64ENVarch=aarch64ldflags="-L${OHOS_SDK}/native/sysroot/usr/lib/aarch64-linux-ohos"elseecho "${ARCH} not support"return -1fireturn $ret
}build() {cd $pkgname-$ARCH-build/$builddirPKG_CONFIG_LIBDIR="${pkgconfigpath}" ./configure "$@" --enable-neon --enable-asm --enable-network \--disable-vulkan --enable-cross-compile --enable-librtmp --disable-x86asm --enable-openssl --enable-protocols \--enable-static --enable-shared --disable-doc --disable-htmlpages --target-os=linux --arch=$arch \--cc=${CC} --ld=${CC} --strip=${STRIP} --host-cc="${CC}" --host-ld="${CC}" --host-os=linux \--host-ldflags=${ldflags} --sysroot=${OHOS_SDK}/native/sysroot > $buildlog 2>&1$MAKE >> $buildlog 2>&1ret=$?cd $OLDPWDreturn $ret
}package() {cd $pkgname-$ARCH-build/$builddir$MAKE install >> $buildlog 2>&1cd $OLDPWD
}checktestfiles() {cd $pkgname-$ARCH-build/$builddir/tests/reftmpdir=("fate" "acodec" "lavf" "lavf-fate" "pixfmt" "seek" "vsynth")for dir in ${tmpdir[*]}dofor file in `ls $dir`doif [ ! -f $dir/$file ]; thencontinuefistr=`cat $dir/$file | grep "\*tests"`if [ ! -z "$str" ]thensed -i.bak 's/\*tests/tests/g' $dir/$filefidonedonecd $OLDPWD
}copyhostbin() {file=$1if [[ -f tests/$file ]] && [[ ! -f tests/$file.${ARCH} ]]thenmv tests/$file tests/$file.${ARCH}cp ../../$builddir/tests/$file tests/$filefi
}check() {cd $pkgname-$ARCH-build/$builddir# disable running cmdsed -i.bak 's/	$(Q)$(SRC_PATH)\/tests\/fate-run.sh/#	$(Q)$(SRC_PATH)\/tests\/fate-run.sh/g' tests/Makefile# disable check git sourcessed -i.bak 's/include $(SRC_PATH)\/tests\/fate\/source.mak/#include $(SRC_PATH)\/tests\/fate\/source.mak/g' tests/Makefile# disable check ffprobe,this use xmllint command, which ohos is not supportsed -i.bak 's/include $(SRC_PATH)\/tests\/fate\/ffprobe.mak/#include $(SRC_PATH)\/tests\/fate\/ffprobe.mak/g' tests/Makefile# change x86 cmd for generate test targetmv ffmpeg ffmpeg.${ARCH}cp ../../$builddir/ffmpeg ./retrytimes=0ret=0while truedo$MAKE check >> $buildlog 2>&1if [ $? -eq 0 ]thenbreak;ficopyhostbin base64copyhostbin audiomatchcopyhostbin audiogencopyhostbin videogencopyhostbin tiny_psnrcopyhostbin tiny_ssimcopyhostbin rotozoomlet retrytimes=$retrytimes+1if [ $retrytimes -gt 4 ]thenret=1breakfidonemv ffmpeg.${ARCH} ffmpegfor file in `ls tests/*.${ARCH}`dotmpfile=${file%.*}mv $file $tmpfiledone# reduction running cmd for real testsed -i.bak 's/#	$(Q)$(SRC_PATH)\/tests\/fate-run.sh/	$(Q)$(SRC_PATH)\/tests\/fate-run.sh/g' tests/Makefilecd $OLDPWDchecktestfilesecho "The test must be on an OpenHarmony device!"# skip running test on host# real test CMD# make checkreturn $ret
}recoverpkgbuildenv() {unset archunset ldflagsif [ $ARCH == "armeabi-v7a" ]thenunsetarm32ENVelif [ $ARCH == "arm64-v8a" ]thenunsetarm64ENVelseecho "${ARCH} not support"return -1fi
}# 清理环境
cleanbuild() {rm -rf ${PWD}/${builddir} ${PWD}/$pkgname-arm64-v8a-build ${PWD}/$pkgname-armeabi-v7a-build #${PWD}/$packagename
}
2. 构建过程

主入口 build.sh 脚本执行以下步骤:

  1. 解析命令行参数,确定要编译的目标库
  2. 检查编译环境(编译工具链等)
  3. 读取目标库的 HPKBUILD 配置
  4. 按照依赖关系顺序编译各个库
  5. 对每个库执行:
    • 获取源码
    • 配置编译参数
    • 执行编译
    • 安装到指定目录

检查编译环境代码:

# 检测操作系统类型
unames=`uname -s`
osname=${unames:0:5}# 设置根目录
LYCIUM_ROOT=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)# 检查 OHOS_SDK 环境
if [ -z ${OHOS_SDK} ]
thenecho "OHOS_SDK 未设置..."exit 1
fi

依赖管理检测:

# 依赖库暂存文件
depend_tmp_file="/tmp/$USER-lycium_deps-$build_time"
export LYCIUM_DEPEND_PKGNAMES=$depend_tmp_file# 已完成库列表
donelist=()
donelibs=()

核心函数 buildhpk() 实现了构建流程控制:

  1. 任务分轮次执行
  2. 处理依赖关系
  3. 错误处理机制
    主要变量:
  • nextroundlist: 下一轮待构建项目
  • notdonelist: 未完成项目列表
  • buildfalselist: 构建失败项目列表

关键函数说明如下:
checkbuildenv()
检查必要的构建工具是否安装:

  • gcc, cmake, make 等基础工具

  • autoconf, automake 等自动化工具

  • git, curl 等辅助工具 prepareshell()
    为每个构建目录准备必要的脚本:

  • build_hpk.sh: 项目构建脚本

  • envset.sh: 环境设置脚本 makelibsdir()
    管理构建目录:

  • 检查目录有效性

  • 过滤已构建项目

  • 添加到构建队列

3. 交叉编译支持

框架通过以下方式实现交叉编译:

  1. 使用 OpenHarmony NDK 提供的交叉编译工具链
  2. 在 HPKBUILD 中配置交叉编译相关参数
  3. 支持 arm32/arm64/x86 等多架构编译
4. 产物输出

编译产物按照如下结构组织:

usr/└── ${pkgname}/└── ${ARCH}/├── lib/      # 库文件├── include/  # 头文件└── bin/      # 可执行文件
build_hpk.sh构建脚本说明

核心构建函数说明:

1. prepare()

准备构建环境:

  • 宿主机构建(buildhost=true时)
  • 解压源码包
  • 应用补丁
  • 设置交叉编译环境
2. build()

执行构建过程:

  • 配置构建参数
  • 执行configure配置
  • 执行make编译
  • 返回构建结果
3. package()

安装打包:

  • 执行make install
  • 生成最终安装包
4. check()

测试验证:

  • 修改测试配置
  • 准备测试环境
  • 执行测试用例
  • 处理测试结果
5. 环境管理函数
  • recoverpkgbuildenv()
    • 清理编译环境变量
    • 恢复原始环境
  • cleanbuild()
    • 清理构建目录
    • 删除临时文件

总结

本文介绍了HarmonyOS Next跨平台构建脚本功能、使用、以及原理,介绍了构建脚本相关的shell代码等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/6507.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式的艺术-职责链模式

行为型模式的名称、定义、学习难度和使用频率如下表所示&#xff1a; 1.如何理解职责链模式 最常见的职责链是直线型&#xff0c;即沿着一条单向的链来传递请求。链上的每一个对象都是请求处理者&#xff0c;职责链模式可以将请求的处理者组织成一条链&#xff0c;并让请求沿着…

js学习笔记(2)

一、函数 1.JavaScript 函数语法 函数就是包裹在花括号中的代码块&#xff0c;前面使用了关键词 function&#xff1a; function functionname() {// 执行代码 } 当调用该函数时&#xff0c;会执行函数内的代码。 可以在某事件发生时直接调用函数&#xff08;比如当用户点…

洛谷刷题1-3

比较巧妙&#xff0c;求最小公倍数&#xff0c;看多少个数一次循环&#xff0c;直接求解就好了&#xff0c;N的数量级比较大&#xff0c;一层循环也会超时&#xff0c;也用了点双指针的想法&#xff08;归并排序&#xff09; 这里很大的问题&#xff0c;主要是cin输入的时候遇到…

2025年数学建模美赛:A题分析(1)Testing Time: The Constant Wear On Stairs

2025年数学建模美赛 A题分析&#xff08;1&#xff09;Testing Time: The Constant Wear On Stairs 2025年数学建模美赛 A题分析&#xff08;2&#xff09;楼梯磨损分析模型 2025年数学建模美赛 A题分析&#xff08;3&#xff09;楼梯使用方向偏好模型 2025年数学建模美赛 A题分…

云原生时代,如何构建高效分布式监控系统

文章目录 一.监控现状二.Thanos原理分析SidecarQuerierStoreCompactor 三.Sidecar or ReceiverThanos Receiver工作原理 四.分布式运维架构 一.监控现状 Prometheus是CNCF基金会管理的一个开源监控项目&#xff0c;由于其良好的架构设计和完善的生态&#xff0c;迅速成为了监控…

每天五分钟深度学习pytorch:基于VGG神经网络完成CAFIR10的识别

本文重点 前面的所有模型我们都是使用VGG跑了mnist数据集,本次我们换一个数据集,我们使用CAFIR数据集,这个数据集我们前面介绍过,它和mnist不一样了,mnist是灰度图,这个是彩色图,所以它的通道数是3,这样我们再构建卷积神经网路的时候,第一个卷积层的输入通道数就应该…

力扣707题(2)——设计链表

#题目 #3,5和6的代码 今天看剩下几个题的代码&#xff0c;1,2,4的代码已经在上篇博客写过了想看的小伙伴移步到&#xff1a; 力扣707题——设计链表-CSDN博客 //第3题头插法 void addAtHead(int val){ //记录头结点ListNode nhead; //新节点的创建,并让它指向原本头结点的后…

STM32_SD卡的SDIO通信_基础读写

本篇将使用CubeMXKeil, 创建一个SD卡读写的工程。 目录 一、SD卡要点速读 二、SDIO要点速读 三、SD卡座接线原理图 四、CubeMX新建工程 五、CubeMX 生成 SD卡的SDIO通信部分 六、Keil 编辑工程代码 七、实验效果 实现效果&#xff0c;如下图&#xff1a; 一、SD卡 速读…

CPU 缓存基础知识

并发编程首先需要简单了解下现代CPU相关知识。通过一些简单的图&#xff0c;简单的代码&#xff0c;来认识CPU以及一些常见的问题。 目录 CPU存储与缓存的引入常见的三级缓存结构缓存一致性协议MESI协议缓存行 cache line 通过代码实例认识缓存行的重要性 CPU指令的乱序执行通过…

【博客之星】年度总结:在云影与墨香中探寻成长的足迹

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、年度回顾 1、创作历程 2、个人成长 3、个人生活与博客事业 二、技术总结 1、赛道选择 2、技术工具 3、实战项目 三、前景与展望 1、云原生未来…

2024 自主创业事业小结和2025展望

一 2024创业事业小结&#xff1a; 1.1 2024 自主创业项目小结&#xff1a; 2024年我们小团队主要做了两大类的项目&#xff1a; 1&#xff0c;工业类 在工业领域的项目&#xff0c;我们做了3个落地的视觉集成项目。 1.1 旋转角度的测量&#xff1a; 由于是外包项目&#…

Redis使用基础

1 redis介绍 Redis&#xff08;Remote Dictionary Server )&#xff0c;即远程字典服务 ! 是完全开源的&#xff0c;遵守 BSD 协议&#xff0c;是一个高性能的 key-value 数据库。 使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并…

激光雷达和相机早期融合

通过外参和内参的标定将激光雷达的点云投影到图像上。 • 传感器标定 首先需要对激光雷达和相机&#xff08;用于获取 2D 图像&#xff09;进行外参和内参标定。这是为了确定激光雷达坐标系和相机坐标系之间的转换关系&#xff0c;包括旋转和平移。通常采用棋盘格等标定工具&…

HMV Challenges 022 Writeup

题目地址&#xff1a;https://hackmyvm.eu/challenges/challenge.php?c022 首先猜测是否为图片隐写&#xff0c;无果 盲猜图片上的小鸟是某种带符号的隐写 去这个网站找找看&#xff1a;https://www.dcode.fr/chiffres-symboles 找到了 参照原图片鸟儿的姿态选择并排放 所…

FPGA与ASIC:深度解析与职业选择

IC&#xff08;集成电路&#xff09;行业涵盖广泛&#xff0c;涉及数字、模拟等不同研究方向&#xff0c;以及设计、制造、封测等不同产业环节。其中&#xff0c;FPGA&#xff08;现场可编程门阵列&#xff09;和ASIC&#xff08;专用集成电路&#xff09;是两种重要的芯片类型…

【前端】Hexo 建站指南

文章目录 前言生成站点本地测试部署云端参考 前言 更好的阅读体验&#xff1a;https://blog.dwj601.cn/FrontEnd/Hexo/build-your-own-website-with-hexo/ 笔记记多了&#xff0c;想要分享给同学们一起交流进步&#xff0c;该怎么办&#xff1f;想要搭建一个属于自己的知识库…

抛弃node和vscode,如何用记事本开发出一个完整的vue前端项目

写这篇文章的初衷并不是要大家真的不用node和vscode&#xff0c;说实话前端发展成今天这样&#xff0c;在实际开发中确实离不开node和vscode这类工具了&#xff0c;但往往工具用多了我们自己也成了一个工具人&#xff01; 这篇文章的缘由 最近在开发wordpress插件的时候&…

Gin 学习笔记

教程地址&#xff1a;https://www.bilibili.com/video/BV1FV4y1C72M?spm_id_from333.788.videopod.sections&vd_source707ec8983cc32e6e065d5496a7f79ee6 01-项目搭建 各常用目录的说明&#xff1a; https://github.com/golang-standards/project-layout/blob/master/REA…

麒麟操作系统服务架构保姆级教程(十四)iptables防火墙四表五链和防火墙应用案例

如果你想拥有你从未拥有过的东西&#xff0c;那么你必须去做你从未做过的事情 防火墙在运维工作中有着不可或缺的重要性。首先&#xff0c;它是保障网络安全的关键防线&#xff0c;通过设置访问控制规则&#xff0c;可精准过滤非法网络流量&#xff0c;有效阻挡外部黑客攻击、恶…

双目立体校正和Q矩阵

立体校正 对两个摄像机的图像平面重投影&#xff0c;使二者位于同一平面&#xff0c;而且左右图像的行对准。 Bouguet 该算法需要用到双目标定后外参(R&#xff0c;T) 从上图中可以看出&#xff0c;该算法主要分为两步&#xff1a; 使成像平面共面 这个办法很直观&#xff…