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" ]
    then
        hostosname=linux
    elif [ "$LYCIUM_BUILD_OS" == "Darwi" ]
    then
        hostosname=darwin
    else
        echo "System cannot recognize, exiting"
        return -1
    fi
    if [ $buildhost == true ]
    then
        tar -zxf $packagename
        cd $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>&1
        export LD_LIBRARY_PATH=`pwd`/hostbuild/lib:$LD_LIBRARY_PATH
        sed -i.bak 's/include $(SRC_PATH)\/tests\/fate\/source.mak/#include $(SRC_PATH)\/tests\/fate\/source.mak/g' tests/Makefile
        $MAKE check >> $publicbuildlog 2>&1
        ret=$?
        buildhost=false
        cd $OLDPWD
    fi

    mkdir $pkgname-$ARCH-build
    tar -zxf $packagename -C $pkgname-$ARCH-build
    cd  $pkgname-$ARCH-build/$builddir
    patch -p1 < ../../FFmpeg_oh_test.patch
    cd $OLDPWD

    if [ $ARCH == "armeabi-v7a" ]
    then
        setarm32ENV
        arch=arm
        ldflags="-L${OHOS_SDK}/native/sysroot/usr/lib/arm-linux-ohos"
    elif [ $ARCH == "arm64-v8a" ]
    then
        setarm64ENV
        arch=aarch64
        ldflags="-L${OHOS_SDK}/native/sysroot/usr/lib/aarch64-linux-ohos"
    else
        echo "${ARCH} not support"
        return -1
    fi

    return $ret
}

build() {
    cd $pkgname-$ARCH-build/$builddir
    PKG_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>&1
    ret=$?
    cd $OLDPWD
    return $ret
}

package() {
    cd $pkgname-$ARCH-build/$builddir
    $MAKE install >> $buildlog 2>&1
    cd $OLDPWD
}

checktestfiles() {
    cd $pkgname-$ARCH-build/$builddir/tests/ref

    tmpdir=("fate" "acodec" "lavf" "lavf-fate" "pixfmt" "seek" "vsynth")
    for dir in ${tmpdir[*]}
    do
        for file in `ls $dir`
        do
            if [ ! -f $dir/$file ]; then
                continue
            fi
            str=`cat $dir/$file | grep "\*tests"`
            if [ ! -z "$str" ]
            then
                sed -i.bak 's/\*tests/tests/g' $dir/$file
            fi
        done
    done

    cd $OLDPWD
}

copyhostbin() {
    file=$1
    if [[ -f tests/$file ]] && [[ ! -f tests/$file.${ARCH} ]]
    then
        mv tests/$file tests/$file.${ARCH}
        cp ../../$builddir/tests/$file tests/$file
    fi
}

check() {
    cd $pkgname-$ARCH-build/$builddir
    # disable running cmd
    sed -i.bak 's/	$(Q)$(SRC_PATH)\/tests\/fate-run.sh/#	$(Q)$(SRC_PATH)\/tests\/fate-run.sh/g' tests/Makefile
    # disable check git sources
    sed -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 support
    sed -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 target
    mv ffmpeg ffmpeg.${ARCH}
    cp ../../$builddir/ffmpeg ./
    retrytimes=0
    ret=0
    while true
    do
        $MAKE check >> $buildlog 2>&1
        if [ $? -eq 0 ]
        then
            break;
        fi

        copyhostbin base64
        copyhostbin audiomatch
        copyhostbin audiogen
        copyhostbin videogen
        copyhostbin tiny_psnr
        copyhostbin tiny_ssim
        copyhostbin rotozoom

        let retrytimes=$retrytimes+1
        if [ $retrytimes -gt 4 ]
        then
            ret=1
            break
        fi
    done

    mv ffmpeg.${ARCH} ffmpeg
    for file in `ls tests/*.${ARCH}`
    do
        tmpfile=${file%.*}
        mv $file $tmpfile
    done

    # reduction running cmd for real test
    sed -i.bak 's/#	$(Q)$(SRC_PATH)\/tests\/fate-run.sh/	$(Q)$(SRC_PATH)\/tests\/fate-run.sh/g' tests/Makefile
    cd $OLDPWD
    checktestfiles

    echo "The test must be on an OpenHarmony device!"
    # skip running test on host
    # real test CMD
    # make check

    return $ret
}

recoverpkgbuildenv() {
    unset arch
    unset ldflags
    if [ $ARCH == "armeabi-v7a" ]
    then
        unsetarm32ENV
    elif [ $ARCH == "arm64-v8a" ]
    then
        unsetarm64ENV
    else
        echo "${ARCH} not support"
        return -1
    fi
}

# 清理环境
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} ]
then
    echo "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代码等。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构(Java)——二叉树

1.概念 二叉树是一种树形数据结构&#xff0c;其中每个节点最多有两个子节点&#xff0c;通常被称为左子节点和右子节点。二叉树可以是空的&#xff08;即没有节点&#xff09;&#xff0c;或者由一个根节点以及零个或多个左子树和右子树组成&#xff0c;其中左子树和右子树也分…

ansible自动化运维实战--script、unarchive和shell模块(6)

文章目录 一、script模块1.1、功能1.2、常用参数1.3、举例 二、unarchive模块2.1、功能2.2、常用参数2.3、举例 三、shell模块3.1、功能3.2、常用参数3.3、举例 一、script模块 1.1、功能 Ansible 的 script 模块允许你在远程主机上运行本地的脚本文件&#xff0c;其提供了一…

【期末速成】Oracle数据库

选择题 从中选 10 道。 Oracle的管理与开发工具不包括&#xff08; D &#xff09;。 A. OEM B. SQL*PLUS C. ONCA D. PHP PHP 是一种编程语言&#xff0c;不是 Oracle 的工具。 下面文件属于物理文件的是&#xff08; C &#xff09;。 A. 概要文件 B. 闪回文件 C. 数据文件 D…

auto的用法

文章目录 一、auto 一、auto 在这里插入代码片在这里插入代码片感谢大家能看到这里&#xff0c;多多支持&#xff01;

UE求职Demo开发日志#7 强化属性完善

1 实现思路设计 定义一个结构体记录技能树一个单元的信息&#xff0c;命名为FStrengthenCellInfo&#xff0c;一个TArray记录技能树整体信息&#xff0c;需要以下信息&#xff1a; 1.TArray前置技能index 2.FString 描述文本 3.TArray<FMyItemInfo>激活需要的物品ID和…

java常量池

目录 1 Class常量池 2 运行时常量池 3 字符串常量池 3.1 为什么要设计字符串常量池 3.2 字符串对象三种创建姿势 3.3 字符串的操作 3.4 字符串的不可变性 4 包装类型常量池 1 Class常量池 class 文件的资源仓库javap命令可以查看class常量池 主要包含字面量和符号引用字面量 由…

C语言-内存管理

1、malloc()函数 用于动态分配一块指定大小的内存&#xff0c;并返回指向这块内存的指针。如果分配失败&#xff0c; 返回 NULL。 int* ptr (int*)malloc(sizeof(int) * 10); // 分配一个包含 10 个整数的内存 if (ptr NULL) {printf("Memory allocation failed!\n&q…

基于ESP32-IDF驱动GPIO输出控制LED

基于ESP32-IDF驱动GPIO输出控制LED 文章目录 基于ESP32-IDF驱动GPIO输出控制LED一、点亮LED3.1 LED电路3.2 配置GPIO函数gpio_config()原型和头文件3.3 设置GPIO引脚电平状态函数gpio_set_level()原型和头文件3.4 代码实现并编译烧录 一、点亮LED 3.1 LED电路 可以看到&#x…

YOLOv5训练自己的数据及rknn部署

YOLOv5训练自己的数据及rknn部署 一、下载源码二、准备自己的数据集2.1 标注图像2.2 数据集结构 三、配置YOLOv5训练3.1 修改配置文件3.2 模型选择 四、训练五、测试六、部署6.1 pt转onnx6.2 onnx转rknn 七、常见错误7.1 训练过程中的错误7.1.1 cuda: out of memory7.1.2 train…

MATLAB 如何避免复杂shp文件对inpolygon的影响

**任务描述&#xff1a;**当我想用inpolygon函数将属于非洲的pixel选出来时&#xff0c;发现因为周边小岛的影响&#xff0c;pixel选取有问题&#xff0c;如下图。 第一种解决办法&#xff1a; 首先将复杂shp文件查分成简单的shp文件&#xff0c;即将不相交的元素分离开 [QGIS…

2025.01春节可用两个带源的TV直播软件

电视直播pro 2.612 论坛的分享: https://tieba.baidu.com/p/9183010315 我的网盘 http://pan.ezdial.cn/nasone/tvbox/%E7%94%B5%E8%A7%86%E7%9B%B4-pro.apk 这个软件挺牛逼的,因为虽然有直播购物,但是里面的频道是真好,有电影解说有电视剧, 最后还能自定义播放源. 唯一不足找…

Ubuntu24.04初始化MySQL报错 error while loading shared libraries libaio.so.1

Ubuntu24.04初始化MySQL报错 error while loading shared libraries: libaio.so.1 问题一&#xff1a;libaio1不存在 # 提示libaio1不存在 [rootzabbix-mysql-master.example.com x86_64-linux-gnu]#apt install numactl libaio1 Reading package lists... Done Building depe…

【Linux】其他备选高级IO模型

其他高级 I/O 模型 以上基本介绍的都是同步IO相关知识点&#xff0c;即在同步I/O模型中&#xff0c;程序发起I/O操作后会等待I/O操作完成&#xff0c;即程序会被阻塞&#xff0c;直到I/O完成。整个I/O过程在同一个线程中进行&#xff0c;程序在等待期间不能执行其他任务。下面…

RV1126+FFMPEG推流项目源码

源码在我的gitee上面&#xff0c;感兴趣的可以自行了解 nullhttps://gitee.com/x-lan/rv126-ffmpeg-streaming-projecthttps://gitee.com/x-lan/rv126-ffmpeg-streaming-project

VMware虚拟机克隆或复制linux后无法上网的解决方案

1.首先转移虚拟机到另一台电脑 【虚拟机转移】超详细的将虚拟机&#xff08;ubuntu&#xff09;从一台电脑复制到另一台电脑教程_虚拟机复制到另一台电脑-CSDN博客 1.先把虚拟机整个文件拷贝到另一台电脑 2。打开vmware&#xff0c;选择打开虚拟机&#xff0c;选择 .vmx 就可…

具有CLI命令和Web界面的WOL

简介 什么是 wol &#xff1f; wol 是一个命令行工具&#xff0c;用于发送唤醒网络上设备的 Wake-On-LAN&#xff08;WOL&#xff09;魔法包。具有命令行界面和网页界面两种功能。本文只介绍了网页界面。 主要特点 功能&#xff1a;通过发送 Wake-On-LAN&#xff08;WOL&…

Vue2:使用sortablejs实现el-table中行拖拽调整顺序

如图,实现拖拽表格中的行来调整行顺序,但是其中的编号仍然是1、2、3、4的顺序,不跟着变化。 实现如下: 一、导入sortablejs import Sortable from "sortablejs";export default { components: {Sortable},data() {return {//数据中的id很重要,拖拽行重新排序…

分布式光纤应变监测是一种高精度、分布式的监测技术

一、土木工程领域 桥梁结构健康监测 主跨应变监测&#xff1a;在大跨度桥梁的主跨部分&#xff0c;如悬索桥的主缆、斜拉桥的斜拉索和主梁&#xff0c;分布式光纤应变传感器可以沿着这些关键结构部件进行铺设。通过实时监测应变情况&#xff0c;能够精确捕捉到车辆荷载、风荷…

智能手机“混战”2025:谁将倒下而谁又将突围?

【潮汐商业评论原创】 “去年做手机比较艰难&#xff0c;几乎每个品牌都在调价、压货&#xff0c;像华为这种以前都不给我们分货的厂商&#xff0c;也开始成为我的主要库存。不过今年开头比较好&#xff0c;20号国补一开始&#xff0c;店里的人流和手机销量就明显涨了不少&…

OpenCV文字绘制支持中文显示

OpenCV版本&#xff1a;4.4 IDE&#xff1a;VS2019 功能描述 OpenCV绘制文本的函数putText()不支持中文的显示&#xff0c;网上很多方法推荐的都是使用FreeType来支持&#xff0c;FreeType是什么呢&#xff1f;FreeType的官网上有介绍 FreeType官网 https://www.freetype.or…