OpenHarmony平台移植 gifsicle:C/C++ 三方库适配实践(Lycium / tpc_c_cplusplus)

gifsicle 是常用的 GIF 命令行工具:裁剪帧、调延迟、合并与查询信息。把它编进 OpenHarmony,走 SIG 维护的 tpc_c_cplusplus 最省事:交叉编译、多架构、安装前缀都由 Lycium 管,你只要把「下载源码 → 配 host → configure → install」写清楚。

社区里有一篇把这套流程讲得很规整的文章:OpenHarmony 通用 C/C++ 三方库标准化鸿蒙化适配。下面按同一套思路,落到 gifsicle 这种 Autotools + 需 bootstrap 的库上。


1. 仓库里该放什么

tpc_c_cpluspluslycium 负责调度,thirdparty/<库名>/ 下放适配材料。当前主流做法是固定 六个文件(缺什么补什么),模板直接从仓里拷:

lycium/template

文件 作用
HPKBUILD 元数据、prepare / build / package / check / cleanbuild,编译逻辑全在这里
HPKCHECK HPKBUILD 配套:在 OpenHarmony 设备环境 里执行测试,把结果写入日志;具体写法见下文 第 4 节
README.OpenSource 协议、版本、上游地址
README_zh.md 给人看的:怎么编、产物在哪、注意点
SHA512SUM 可选, tarball 校验用
xxx_oh_pkg.patch 可选,源码在 OH 上编不过再补

gifsicle 若未改上游源码,补丁可以先不建HPKBUILD 里把 buildtools 设成 configure


2. gifsicle 要注意的一点

Release 打 tag 的源码树往往 不带生成好的 configure ,要先在源码根目录跑 ./bootstrap.sh (本机装好 autoconf、automake、libtool 等)。这一步放在 prepare() 里最合适:只做一次,后面每个 $ARCH 各自 mkdir 做 out-of-tree 编译。


3. HPKBUILD 示例(对应 v1.96)

把下面整段作为 HPKBUILD 使用(若你所在分支仍要求单独 .sh 文件名,内容原样迁移即可)。

sh 复制代码
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.

pkgname=gifsicle
pkgver=v1.96
pkgrel=0
pkgdesc="Command-line program for creating, editing, and getting information about GIF images and animations."
url="https://github.com/kohler/gifsicle"
archs=("armeabi-v7a" "arm64-v8a")
license=("GPL-2.0")
depends=()
makedepends=()
source="https://github.com/kohler/$pkgname.git"

downloadpackage=false
autounpack=false
buildtools="configure"
builddir=$pkgname-${pkgver:1}
packagename=$builddir.tar.gz

patchflag=false
cloneFlag=true

prepare() {
    if $cloneFlag
    then
        git clone -b $pkgver $source $builddir > $publicbuildlog 2>&1
        if [ $? -ne 0 ]; then
            echo "$pkgname git clone $source error."
            return -1
        fi
        cd $builddir
        # gifsicle 需要生成 configure 脚本
        ./bootstrap.sh >> $publicbuildlog 2>&1
        cloneFlag=false
        cd $OLDPWD
    fi
    mkdir -p $builddir/$ARCH-build
}

build() {
    cd $builddir/$ARCH-build
    ../configure --host=$HOST --prefix=$LYCIUM_ROOT/usr/$pkgname/$ARCH \
        CFLAGS="$CFLAGS -Wno-unused-command-line-argument" \
        LDFLAGS="$LDFLAGS" >> $buildlog 2>&1

    ${MAKE} -j$(nproc) >> $buildlog 2>&1
    ret=$?
    cd $OLDPWD
    return $ret
}

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

check() {
    echo "The test must be on an OpenHarmony device!"
    # 设备上:gifsicle --version
}

cleanbuild() {
    rm -rf ${PWD}/$builddir
}

pkgver=v1.96builddir 展开为 gifsicle-1.96${pkgver:1} 去掉打头的 v)。archs 只列你要支持的 ABI;和 标准化适配文 里写的一样,常见就是 armeabi-v7aarm64-v8a

configure--host=$HOSTCFLAGS / LDFLAGS 由 Lycium 注入,不要改成桌面 gcc。-Wno-unused-command-line-argument 是给 clang 少报一点「传了没用」的参数;你那边若干净,删掉也无妨。

--prefix=$LYCIUM_ROOT/usr/$pkgname/$ARCH 把每个架构的安装根隔开,后面北向拷贝 bin/gifsicle 不容易拿错目录。


4. HPKCHECK:设备侧校验写在哪

HPKBUILD 里的 check() 多数库只放一句 The test must be on an OpenHarmony device! ,因为交叉编出来的二进制在 Linux 编译机上既不能当真跑 OH 环境,也不该和「编过即过」混为一谈。真正要 在 OH 上拉起命令、看退出码 的逻辑,放在同目录的 HPKCHECK 里,由 Lycium 在设备侧走 openharmonycheck() 这一条入口。

习惯写法有三点:

  1. source HPKBUILD > /dev/null 2>&1 :静默再读一遍 HPKBUILD,拿到 pkgnamebuilddirARCH 等与构建一致的变量,避免两处手填不一致。
  2. logfile=...:把标准输出/错误重定向到固定路径,排障时直接 tail 这一份即可。
  3. openharmonycheck() :在这里 cdbuild 阶段生成可执行文件所在目录 ,跑 --version / ctest / make test 等你库能接受的自检;用 res 累加非零 表示失败,最后 return $res

gifsicle 是单可执行文件,用 --version--help 做烟测足够;若你后面要测「读一张 GIF 再优化」,把样例图放进设备可读路径,在同一函数里追加命令即可。

下面是一份与上文 HPKBUILD 对齐的 HPKCHECK 示例(可执行文件路径按 gifsicle 常见 out-of-tree 产物放在 $ARCH-build/src ;若你本地 **makegifsicle 生成在 $ARCH-build 根目录,把 cd 改成对应目录即可)。

sh 复制代码
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.

source HPKBUILD > /dev/null 2>&1    # 导入 HPKBUILD 文件
logfile=${LYCIUM_THIRDPARTY_ROOT}/${pkgname}/${pkgname}_${ARCH}_${OHOS_SDK_VER}_test.log

# 在 OH 环境执行测试的接口
openharmonycheck() {
    res=0
    # 指向 build 阶段生成的可执行文件所在目录
    cd $builddir/$ARCH-build/src

    echo "--- Testing gifsicle version ---" >> ${logfile} 2>&1
    ./gifsicle --version >> ${logfile} 2>&1
    if [ $? -ne 0 ]; then
        echo "gifsicle --version execution failed" >> ${logfile} 2>&1
        res=1
    fi

    # 进阶测试:尝试对一个内置或生成的临时 GIF 进行信息读取(或者简单的优化操作)
    # 如果环境中有测试图片,可以进行如下测试:
    echo "--- Testing gifsicle functional check ---" >> ${logfile} 2>&1
    # 仅仅打印帮助信息作为功能可用性检查
    ./gifsicle --help > /dev/null 2>&1
    if [ $? -ne 0 ]; then
        echo "gifsicle basic command failed" >> ${logfile} 2>&1
        res=1
    fi

    cd $OLDPWD
    return $res
}

若模板里还带空的 checkprepare() ,保留 return 0 即可,与官方 lycium/template 一致。


5. 编译与产物路径

tpc_c_cplusplus/lycium 下按 README 调用 build.sh (参数一般是库目录名 gifsicle)。编完后看:

text 复制代码
lycium/usr/gifsicle/armeabi-v7a/
lycium/usr/gifsicle/arm64-v8a/

可执行文件在各自的 bin/gifsicle 。是否有额外 .so 依赖,用 readelf -d 看一眼 NEEDED 即可;很多场景下就是一个单文件。


6. 设备上怎么验

交叉编阶段无法在编译机上完整模拟 OH 行为,HPKBUILDcheck() 保持占位即可。要形成可归档的测试结果,走 第 4 节 HPKCHECK :Lycium 在设备上跑完 openharmonycheck() 后看 logfile 里是否出现 gifsicle --version--help 的正常输出、退出码是否为 0。

手工抽查时,把对应 ABI 的 gifsicle 放到设备可执行路径后执行 gifsicle --version,与日志结论应一致。


7. 协议

gifsicle 为 GPL-2.0。随应用或系统镜像分发二进制时,按 GPL 要求保留版权与源码可得性,公司内部再让合规过一眼。


8. 排错备忘

  • bootstrap.sh 失败 :多半缺 autoconf / automake / libtool,把主机开发包装全。
  • configure 找不到编译器 :SDK 与 Lycium 环境没进当前 shell,按 docs 里步骤 source 一遍。
  • 设备上 exec format error :装错 ABI,arm32arm64 目录别混用。
  • HPKCHECKcd .../src 失败或找不到 ./gifsicle :先看 $ARCH-build 下实际产物路径 (有的在根目录、有的在 src/ ),改 openharmonycheck 里的 cd 即可。

9. 延伸阅读

仓库与规范

文章与社区实践

最后,欢迎加入开源鸿蒙开发者社区交流:https://harmonypc.csdn.net/

相关推荐
云泽80832 分钟前
C++11 核心特性全解:列表初始化、右值引用与移动语义实战
开发语言·c++
AI进化营-智能译站1 小时前
ROS2 C++开发系列12-用多态与虚函数构建可扩展的ROS2机器人行为模块
开发语言·c++·ai·机器人
iCxhust1 小时前
微机原理实践教程(C语言篇)---A002流水灯
c语言·开发语言·单片机·嵌入式硬件·51单片机·课程设计·微机原理
Morwit2 小时前
QML组件之间的通信方案(暴露子组件)
c++·qt·职场和发展
qeen872 小时前
【数据结构】建堆的时间复杂度讨论与TOP-K问题
c语言·数据结构·c++·学习·
图码2 小时前
如何用多种方法判断字符串是否为回文?
开发语言·数据结构·c++·算法·阿里云·线性回归·数字雕刻
xmdy58662 小时前
Flutter+开源鸿蒙实战|智安盾电商溯源平台Day1 项目搭建与整体方案拆解
flutter·开源·harmonyos
handler012 小时前
Linux 内核剖析:进程优先级、上下文切换与 O(1) 调度算法
linux·运维·c语言·开发语言·c++·笔记·算法
zhouwy1132 小时前
Linux进程与线程编程详解
linux·c++
热心网友俣先生3 小时前
2026年第二十三届五一数学建模竞赛C题超详细解题思路+各问题可用模型推荐+部分模型结果展示
c语言·开发语言·数学建模