移植speexdsp到OpenHarmony标准系统④

五、在OpenHarmony编译体系下增量编译Speexdsp

建议先增量编译生成三方库的动态链接库和可执行文件,验证是否成功把三方库加入OpenHarmonybian编译体系。

  • 成功编译出so和可执行文件,即成功把三方库加入到ohos编译体系。之后还要验证三方库在ohos运行,功能是否正常。功能正常才能视为移植成功。

推荐增量编译出三方库的动态链接库和测试用例,不推荐的做法是把三方库加入openharmony编译体系后全量编译出烧录ohos用的固件。

  • 第一是因为全量编译ohos对电脑的性能,特别是内存要求比较高(笔者的笔记本上的虚拟机内存给到了32G,对学生开发者来讲,编译ohos的硬件门槛还是有点高的。)增量编译对内存要求不是特别高。(笔者的8G内存二合一笔记本都可以编译出来,并且虚拟机内存只给到了4GB左右
  • 第二是因为全量编译花费时间较多(笔者完整编译出一个固件需要3个小时左右。)增量编译需要的时间相对较少(笔者大概只需要花费9分钟左右

全量编译和增量编译概念

  • 全量编译是将所有文件重新编译,重新生成解决方案就是全量编译
  • 增量编译只对改动的文件进行编译,执行生成解决方案就是增量编译
  • ohos3.2beta1版本开始新增特性,支持64位系统的编译,默认情况下编译的都是32位系统,在编译命令中添加--target-cpu arm64即可构建64位系统,编译so和可执行文件的执行语句更改为:

在源码目录执行如下命令,进行增量编译:

./build.sh --product-name rk3568 --ccache --build-target=speexdsp --target-cpu arm64

加快本地编译的一些参数

编译时,适当选择添加以下的编译参数可以加快编译的过程。

  • 添加–ccache参数:
    • 原理:ccache会缓存c/c++编译的编译输出,下一次在编译输入不变的情况下,直接复用缓存的产物。
    • 安装:
      • 快速安装:执行sudo apt-get install ccache命令。
    • 使用:执行./build.sh --product-name 产品名 --ccache命令。
  • 添加–fast-rebuild参数
    • 原理:编译流程主要分为:preloader->loader->gn->ninja这四个过程,在本地没有修改gn和产品配置相关文件的前提下,添加–fast-rebuild会让你直接从ninja编译开始。
    • 使用:执行./build.sh --product-name 产品名 --fast-rebuild命令。
  • 添加enable_notice_collection=false参数
    • 原理:省略掉收集开源软件模块的license的过程。
    • 使用:执行./build.sh --product-name 产品名 --gn-args --enable_notice_collection=false --ccache命令。
  • 添加–build-target参数
    • 该参数用于指定编译模块,如何找模块的名字:
    • 相关仓下BUILD.gn中关注group、ohos_shared_library、ohos_executable等关键字。
    • ./build.sh --product-name 产品名 --build-target 模块名 --build-only-gn生成build.ninja,然后去该文件中查找相关模块名。
    • 使用:执行./build.sh --product-name 产品名 --build-target ark_js_host_linux_tools_packages命令。

解决编译报错

(笔者理解移植过程肯定不会是一帆风顺的)

执行编译命令后,有部分报错
1.部分头文件缺失报错
‘speexdsp_config_types.h’ file not found

编译找不到third_party/speexdsp/include/speex目录下的speexdsp_config_types.h文件。

../../third_party/speexdsp/include/speex/speexdsp_types.h:122:10: fatal error: 
'speexdsp_config_types.h' file not found

解决办法:

  • speexdsp_types.h 是由linux下编译生成的,因此需要在Linux下编译整个Speexdsp源码,然后把在speexdsp原生库目录下build/include/speex目录生成的speexdsp_types.h文件拷贝到要ohos源码下的third_party/speexdsp/include/speex目录下,

2.json文件语法发生错误。

解决方法:
查看out/rk3568目录下build.log文件,检查源码/build/subsystem_config.json文件语法
笔者出现这个问题的原因是json文件语法发生错误,在subsystem_config.json文件第一行的{没有匹配},添加上去就没问题。

编译成功

解决完编译报错后,再次执行编译命令。

./build.sh --product-name rk3568 --ccache --build-target=speexdsp --target-cpu arm64

编译成功,终端打印信息如下:
下面只选取关键的一小部分,实际打印出来的信息有两千行左右。)

jiajiahao@ubuntu:~/Desktop/OpenHarmony/sources$ ./build.sh --product-name rk3568 --ccache --build-target=speexdsp --target-cpu arm64
++++++++++++++++++++++++++++++++++++++++
2022-09-07 22:03:47
--product-name rk3568 --ccache --build-target=speexdsp --target-cpu arm64
......
······
[OHOS INFO] [1595/1633] STAMP obj/third_party/speexdsp/speexdsp_share.inputdeps.stamp
[OHOS INFO] [1596/1633] CC obj/out/rk3568/obj/third_party/musl/intermidiates/linux/musl_src_ported/src/unistd/soft_musl_src/ttyname_r.o
[OHOS INFO] [1597/1633] CC obj/out/rk3568/obj/third_party/musl/intermidiates/linux/musl_src_ported/src/unistd/soft_musl_src/ualarm.o
[OHOS INFO] [1598/1633] CC obj/out/rk3568/obj/third_party/musl/intermidiates/linux/musl_src_ported/src/unistd/soft_musl_src/unlink.o
[OHOS INFO] [1599/1633] CC obj/out/rk3568/obj/third_party/musl/intermidiates/linux/musl_src_ported/src/unistd/soft_musl_src/unlinkat.o
[OHOS INFO] [1600/1633] CC obj/out/rk3568/obj/third_party/musl/intermidiates/linux/musl_src_ported/src/unistd/soft_musl_src/usleep.o
[OHOS INFO] [1601/1633] CC obj/out/rk3568/obj/third_party/musl/intermidiates/linux/musl_src_ported/src/unistd/soft_musl_src/write.o
[OHOS INFO] [1602/1633] CC obj/out/rk3568/obj/third_party/musl/intermidiates/linux/musl_src_ported/src/unistd/soft_musl_src/writev.o
[OHOS INFO] [1603/1633] CC obj/out/rk3568/obj/third_party/musl/intermidiates/linux/musl_src_ported/src/string/soft_musl_src_nossp/mempcpy.o
[OHOS INFO] [1604/1633] CC obj/out/rk3568/obj/third_party/musl/intermidiates/linux/musl_src_ported/src/string/soft_musl_src_nossp/memset.o
[OHOS INFO] [1605/1633] STAMP obj/third_party/musl/soft_musl_src.stamp
[OHOS INFO] [1606/1633] CC obj/third_party/speexdsp/libspeexdsp/speexdsp_share/buffer.o
[OHOS INFO] [1607/1633] CC obj/third_party/speexdsp/libspeexdsp/speexdsp_share/fftwrap.o
[OHOS INFO] [1608/1633] CC obj/third_party/speexdsp/libspeexdsp/speexdsp_share/filterbank.o
[OHOS INFO] [1609/1633] CC obj/out/rk3568/obj/third_party/musl/intermidiates/linux/musl_src_ported/src/env/soft_musl_src_nossp/__libc_start_main.o
[OHOS INFO] [1610/1633] CC obj/third_party/speexdsp/libspeexdsp/speexdsp_share/scal.o
[OHOS INFO] [1611/1633] ASM obj/out/rk3568/obj/third_party/musl/intermidiates/linux/musl_src_ported/src/thread/aarch64/soft_musl_src_nossp/__set_thread_area.o
[OHOS INFO] [1612/1633] CC obj/out/rk3568/obj/third_party/musl/intermidiates/linux/musl_src_ported/src/env/soft_musl_src_nossp/__init_tls.o
[OHOS INFO] [1613/1633] CC obj/out/rk3568/obj/third_party/musl/intermidiates/linux/musl_src_ported/src/env/soft_musl_src_nossp/__stack_chk_fail.o
[OHOS INFO] [1614/1633] STAMP obj/third_party/musl/soft_musl_src_nossp.stamp
[OHOS INFO] [1615/1633] CC obj/third_party/speexdsp/libspeexdsp/speexdsp_share/jitter.o
[OHOS INFO] [1616/1633] CC obj/third_party/speexdsp/libspeexdsp/speexdsp_share/preprocess.o
[OHOS INFO] [1617/1633] CC obj/third_party/speexdsp/libspeexdsp/speexdsp_share/resample.o
[OHOS INFO] [1618/1633] CC obj/third_party/speexdsp/libspeexdsp/speexdsp_share/mdf.o
[OHOS INFO] [1619/1633] SOLINK obj/third_party/musl/usr/lib/aarch64-linux-ohos/libc.so
[OHOS INFO] [1620/1633] STAMP obj/third_party/musl/soft_shared_libs.stamp
[OHOS INFO] [1621/1633] STAMP obj/build/config/common_deps.stamp
[OHOS INFO] [1622/1633] STAMP obj/build/config/executable_deps.stamp
[OHOS INFO] [1623/1633] STAMP obj/build/config/shared_library_deps.stamp
[OHOS INFO] [1624/1633] CC obj/third_party/speexdsp/libspeexdsp/speexdsp_share/smallft.o
[OHOS INFO] [1625/1633] SOLINK speexdsp/speexdsp/libspeexdsp_share.z.so
[OHOS INFO] [1626/1633] LINK speexdsp/speexdsp/testdenoise
[OHOS INFO] [1627/1633] LINK speexdsp/speexdsp/testecho
[OHOS INFO] [1628/1633] LINK speexdsp/speexdsp/testjitter
[OHOS INFO] [1629/1633] LINK speexdsp/speexdsp/testresample
[OHOS INFO] [1630/1633] LINK speexdsp/speexdsp/testresample2
[OHOS INFO] [1631/1633] STAMP obj/out/rk3568/build_configs/speexdsp/speexdsp/speexdsp_info.stamp
[OHOS INFO] [1632/1633] ACTION //out/rk3568/build_configs/speexdsp/speexdsp:speexdsp(//build/toolchain/ohos:ohos_clang_arm64)
[OHOS INFO] [1633/1633] STAMP obj/out/rk3568/build_configs/speexdsp/speexdsp/speexdsp.stamp
[OHOS INFO] ---------------------------------------------
[OHOS INFO] ccache summary:
[OHOS INFO] cache hit (direct)  : 0
[OHOS INFO] cache hit (preprocessed)  : 0
[OHOS INFO] cache miss  : 1340
[OHOS INFO] hit rate:  0.00% 
[OHOS INFO] mis rate: 100.00% 
[OHOS INFO] ---------------------------------------------
[OHOS INFO] c targets overlap rate statistics
[OHOS INFO] subsystem       	files NO.	percentage	builds NO.	percentage	overlap rate
[OHOS INFO] aafwk           	      25	0.9%	      25	0.9%	1.00
[OHOS INFO] arkui           	      11	0.4%	      11	0.4%	1.00
[OHOS INFO] bundlemanager   	      45	1.5%	      45	1.5%	1.00
[OHOS INFO] communication   	     197	6.7%	     197	6.7%	1.00
[OHOS INFO] hiviewdfx       	      32	1.1%	      32	1.1%	1.00
[OHOS INFO] securec         	      78	2.7%	      78	2.7%	1.00
[OHOS INFO] speexdsp        	      14	0.5%	      14	0.5%	1.00
[OHOS INFO] startup         	      46	1.6%	      46	1.6%	1.00
[OHOS INFO] third_party     	    1065	36.3%	    1065	36.3%	1.00
[OHOS INFO] thirdparty      	    1065	36.3%	    1065	36.3%	1.00
[OHOS INFO] utils           	      58	2.0%	      58	2.0%	1.00
[OHOS INFO] zxing-cpp-1.2.0 	     117	4.0%	     117	4.0%	1.00
[OHOS INFO] 
[OHOS INFO] c overall build overlap rate: 1.00
[OHOS INFO] 
[OHOS INFO] 
[OHOS INFO] rk3568 build success
[OHOS INFO] cost time: 0:02:24
=====build  successful=====

验证编译结果

编译speexdsp生成的动态链接库和测试用的可执行程序,在openharmony源码目录的out/rk3568下。

out/rk3568/speexdsp目录结构如下:

├── libspeexdsp_share.z.so # 动态链接库
├── testdenoise            # 测试用例 
├── testecho               # 测试用例 
├── testjitter             # 测试用例 
├── testresample           # 测试用例 
└── testresample2          # 测试用例 

六、API接口导出

在源码third_party/speexdsp目录下新建export_api文件夹。

1.在export_api目录下新建allHeads.h文件

该头文件中包含所有库对外导出的头文件。speexdsp有5个测试程序testdenoise、testecho、testjitter、testresample、testresample2。

查看这五个测试程序的源文件testdenoise.c、testecho.c、testjitter.c、testresample.c、testresample2.c。

其用到的libspeexdsp_share.z.so的头文件如下:

#include "speex_preprocess.h"
#include "speex_echo.h"
#include "speex_jitter.h"
#include "speex_resampler.h"

2.新增allDySos目录,该目录下放置生成的动态库:

3、新增allTests目录,该目录下放置所有生成的测试文件:

4、新建自动化测试脚本export_interface.sh,如下所示:

其中cxx="0"表示根据.c文件进行导出,cxx="1"则表示根据.cpp文件进行导出(如果导出c++的三方库的api接口,使用该脚本就让cxx=1):

#!/bin/sh
#C库
cxx="0"

mixed_api() {

    while read line
    do
        if [ $cxx != "1" -o "$4" == "1" ];then
            tmp=$line
        else
            tmp=`echo $line | sed "s/(.*$//g" | sed "s/^.*:://g"`
        fi
        res=`cat $2 |grep "$tmp" -F`
        if [ "$res" != "" ];then
            echo "$line" >> $3
        fi
    done < $1
}

remove_standard_api() {
    flag="0"
    while read line
    do
        tmp1=`echo $line |grep ".*#.*\/usr\/"`
        tmp2=`echo $line |grep ".*#.*[0-9].*\".*\""`
        if [ "$tmp1" != "" ];then
            flag="0"
        elif [ "$tmp2" != "" ];then
            flag="1"
        elif [ $flag == "1" ];then
            echo "$line" >> $2
        fi
    done < $1
}

src1="allHeads.h"
src2="allDySos"
src3="allTests"

if [ $cxx == "1" ];then
    flags_D="-DC"
    flags_DU="-DCu"
    CC=g++
else
    flags_D="-D"
    flags_DU="-Du"
    CC=gcc
fi

if [ ! -e $src1 ];then
    echo "$src1 is not exist!"
    exit 1
fi

if [ ! -e $src2 ];then
    echo "$src2 is not exist!"
    exit 1
fi

if [ ! -e $src3 ];then
    echo "$src3 is not exist!"
    exit 1
fi

rm -rf $src1.i* $src2.txt $src3.txt export_api.txt tested_api.txt

$CC -E $* $src1 -o $src1.i

if [ "$?" != "0" ];then
    exit 1
fi

remove_standard_api $src1.i $src1.i.tmp

nm $src2/* $flags_D | sort -u | grep " T " | sed "s/^.* T //g" >> $src2.txt
nm $src3/* $flags_DU | sort -u | sed "s/^.* U //g" >> $src3.txt

mixed_api $src2.txt $src1.i.tmp export_api.txt 0
mixed_api export_api.txt $src3.txt  tested_api.txt 1

rm -rf $src1.i* $src2.txt $src3.txt

执行脚本导出api接口

执行该脚本导出api接口时,需要给脚本传入编译头文件的参数。(运行此api接口导出脚本在PC端)

  • 例如./export_interface.sh -I 头文件所在路径 -D宏定义(编译所有动态库时,cflags/cflags_cc中的参数)
    • 头文件所在路径为绝对路径
    • D宏定义指的是(编译所有动态库时,cflags/cflags_cc中的参数)

笔者导出speexdsp API接口,在export_api文件夹下打开终端输入了如下命令:

chmod 777 export_interface.sh
./export_interface.sh -I/home/jiajiahao/Desktop/OpenHarmony/sources/third_party/speexdsp/include/speex 

结果是生成export_api.txt(导出so对外api接口)与testd_api.txt(导出测试程序所用到so对外导出api接口 )。

export_api.txt文件内容如下:

speex_preprocess_state_init
speex_preprocess_state_destroy
speex_preprocess
speex_preprocess_run
speex_preprocess_estimate_update
speex_preprocess_ctl
jitter_buffer_init
jitter_buffer_ctl
jitter_buffer_reset
jitter_buffer_destroy
jitter_buffer_put
jitter_buffer_get
jitter_buffer_get_another
jitter_buffer_update_delay
jitter_buffer_get_pointer_timestamp
jitter_buffer_tick
jitter_buffer_remaining_span
speex_echo_state_init
speex_echo_state_init_mc
speex_echo_state_reset
speex_echo_state_destroy
speex_echo_capture
speex_echo_cancellation
speex_echo_playback
speex_echo_cancel
speex_echo_ctl
speex_resampler_init
speex_resampler_init_frac
speex_resampler_set_quality
speex_resampler_set_rate_frac
speex_resampler_destroy
speex_resampler_process_float
speex_resampler_process_int
speex_resampler_process_interleaved_float
speex_resampler_process_interleaved_int
speex_resampler_set_rate
speex_resampler_get_rate
speex_resampler_get_ratio
speex_resampler_get_quality
speex_resampler_set_input_stride
speex_resampler_get_input_stride
speex_resampler_set_output_stride
speex_resampler_get_output_stride
speex_resampler_get_input_latency
speex_resampler_get_output_latency
speex_resampler_skip_zeros
speex_resampler_reset_mem
speex_resampler_strerror
speex_decorrelate_new
speex_decorrelate
speex_decorrelate_destroy

tested_api.txt文件内容如下:

speex_preprocess_state_init
speex_preprocess_state_destroy
speex_preprocess
speex_preprocess_run
speex_preprocess_ctl
jitter_buffer_init
jitter_buffer_reset
jitter_buffer_put
jitter_buffer_get
jitter_buffer_tick
speex_echo_state_init
speex_echo_state_destroy
speex_echo_cancellation
speex_echo_cancel
speex_echo_ctl
speex_resampler_init
speex_resampler_destroy
speex_resampler_process_float
speex_resampler_set_rate
speex_resampler_skip_zeros

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-04-22 20:50:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-22 20:50:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-22 20:50:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-22 20:50:01       20 阅读

热门阅读

  1. ERESOLVE overriding peer dependency npm install错误

    2024-04-22 20:50:01       14 阅读
  2. ChatGPT改写:论文写作新时代

    2024-04-22 20:50:01       16 阅读
  3. LeetCode49字母异位词分组

    2024-04-22 20:50:01       12 阅读
  4. 【JVM】JVM的垃圾回收机制与垃圾回收器的选择

    2024-04-22 20:50:01       13 阅读
  5. 从安装系统到部署datax

    2024-04-22 20:50:01       14 阅读
  6. CS32 C++ programming

    2024-04-22 20:50:01       12 阅读
  7. LeetCode-94-二叉树的中序遍历

    2024-04-22 20:50:01       11 阅读