移植speexdsp到OpenHarmony标准系统②

发布于:2024-04-16 ⋅ 阅读:(19) ⋅ 点赞:(0)

在linux上生成speexdsp的so动态链接库和.a静态链接库

  • make和make install后会生成speexdsp的.so动态链接库和.a静态链接库
make
make install

其中build/lib目录下:

├── libspeexdsp.a                              /*静态库*/
├── libspeexdsp.la                             /*记录同名动态库和静态库相关信息的la文本文件*/
├── libspeexdsp.so -> libspeexdsp.so.1.5.2  
├── libspeexdsp.so.1 -> libspeexdsp.so.1.5.2   /*符号链接*/
├── libspeexdsp.so.1.5.2                       /*动态库*/
└── pkgconfig                                  /*pkgconfig 的 *.pc文件*/
    └── speexdsp.pc

linux下的so、o、lo、a、la文件

  • o: 编译的目标文件
  • a: 静态库,其实就是把若干o文件打了个包
  • so: 动态链接库(共享库) 动态库文件必须以lib开头,以.so结尾
  • lo: 使用libtool编译出的目标文件,其实就是在o文件中添加了一些信息
  • la: 使用libtool编译出的库文件,其实是个文本文件,记录同名动态库和静态库的相关信息

知识拓展

  • 函数库分为静态库*a动态库*.so两种:
    ①静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。
    ②动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。

  • 符号链接(symbolic link)是 Linux 系统中的一种文件,它指向系统中的另一个文件或目录。符号链接类似于 Windows 系统中的快捷方式。

  • 在linux中,*.la是记录同名动态库和静态库相关信息的文本文件。

三、分析speexdsp在标准Linux系统的编译过程文件

  • 分析speexdsp在标准Linux系统的编译过程文件,找到生成so库和测试用的可执行文件所需的.c源代码,头文件路径,cflags编译器标志,所依赖的库。

对比编译前后的speexdsp原生库结构

  • tree工具能以树形的方式显示指定目录的层级结构。
    非绿色字体是编译后生成的文件。

分析原生库下make.am文件

  • make.am是一种比Makefile文件抽象程序更高的编译规则文件。 在里面可以指定生成目录,编译用的源码,编译的时候依赖哪些库,要安装到什么目录。
原生库根目录下的make.am如下
## Process this file with automake to produce Makefile.in. -*-Makefile-*-

# To disable automatic dependency tracking if using other tools than
# gcc and gmake, add the option 'no-dependencies'
AUTOMAKE_OPTIONS = 1.8
ACLOCAL_AMFLAGS = -I m4

pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = speexdsp.pc

EXTRA_DIST = SpeexDSP.spec SpeexDSP.spec.in SpeexDSP.kdevelop speexdsp.pc.in README.blackfin

#Fools KDevelop into including all files
SUBDIRS = libspeexdsp include doc win32 symbian ti   

DIST_SUBDIRS = libspeexdsp include doc win32 symbian ti

rpm: dist
	rpmbuild -ta ${PACKAGE}-${VERSION}.tar.gz

父目录需要包含子目录,在父目录下的Makefile.am中需要添加: SUBDIRS = 子目录。可知speexdsp子目录为libspeexdsp include doc win32 symbian ti 。再逐步查看各个文件夹源码可知只有libspeexdsp ``include文件夹与本次移植有关。所以接下来查看libspeexdsp目录下的make.am文件

子目录libspeexdsp下的make.am
# Disable automatic dependency tracking if using other tools than gcc and gmake
#AUTOMAKE_OPTIONS = no-dependencies

EXTRA_DIST=echo_diagnostic.m

AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include/speex -I$(top_builddir) @FFT_CFLAGS@
/*top_srcdir工程最顶层目录*/
/*top_builddir定义生成目标文件的最上层目录*/

lib_LTLIBRARIES = libspeexdsp.la

# Sources for compilation in the library
if BUILD_KISS_FFT
  FFTSRC=kiss_fft.c _kiss_fft_guts.h kiss_fft.h kiss_fftr.c kiss_fftr.h 
else
if BUILD_SMALLFT
  FFTSRC=smallft.c
else
  FFTSRC=
endif
endif

libspeexdsp_la_SOURCES = preprocess.c jitter.c mdf.c fftwrap.c filterbank.c resample.c buffer.c 
scal.c $(FFTSRC)/*编译libspeexdsp.so需要preprocess.c jitter.c mdf.c fftwrap.c filterbank.c resample.c 
buffer.c scal.c、smallft.c源文件(特别需要注意$(FFTSRC)的存在,因为FFTSRC=smallft.c)*/

/*noinst_HEADERS:这个表示该头文件只是参加可执行文件的编译,而不用安装到安装目录下
。如果需要安装到系统中,可以用 include_HEADERS来代替。*/
noinst_HEADERS = 	arch.h 	bfin.h \
		fixed_arm4.h \
		fixed_arm5e.h 	fixed_bfin.h 	fixed_debug.h 	\
		math_approx.h 		misc_bfin.h 	\
		fftwrap.h \
	filterbank.h fixed_generic.h os_support.h \
	pseudofloat.h smallft.h vorbis_psy.h resample_sse.h resample_neon.h

libspeexdsp_la_LDFLAGS = -no-undefined -version-info/*LDFLAGS:编译时的选项*/ @SPEEXDSP_LT_CURRENT@:@SPEEXDSP_LT_REVISION@:@SPEEXDSP_LT_AGE@
libspeexdsp_la_LIBADD = $(LIBM)

if BUILD_EXAMPLES /*编译测试文件*/ 
noinst_PROGRAMS = testdenoise testecho testjitter testresample testresample2
testdenoise_SOURCES = testdenoise.c
testdenoise_LDADD = libspeexdsp.la@FFT_LIBS@ /*链接需要libspeexdsp.la库文件*/
testecho_SOURCES = testecho.c /*需要的
testecho_LDADD = libspeexdsp.la @FFT_LIBS@ /*链接需要libspeexdsp.la库文件*/
testjitter_SOURCES = testjitter.c
testjitter_LDADD = libspeexdsp.la @FFT_LIBS@ /*链接需要libspeexdsp.la库文件*/
testresample_SOURCES = testresample.c
testresample_LDADD = libspeexdsp.la @FFT_LIBS@ @LIBM@ /*链接需要libspeexdsp.la库文件*/
testresample2_SOURCES = testresample2.c
testresample2_LDADD = libspeexdsp.la @FFT_LIBS@ @LIBM@ /*链接需要libspeexdsp.la库文件*/
endif

通过分析libspeexdsp下的make.am可以知道:

  • 编译出so库需要的.c源文件有preprocess.c jitter.c mdf.c fftwrap.c filterbank.c resample.c
    buffer.c scal.c、smallft.c
  • 编译出so库需要的.h源文件有arch.h bfin.h fixed_arm4.h fixed_arm5e.h fixed_bfin.h fixed_debug.h math_approx.h misc_bfin.h fftwrap.h filterbank.h fixed_generic.h os_support.h pseudofloat.h smallft.h vorbis_psy.h resample_sse.h resample_neon.h
  • 编译出测试用的testdenoise testecho testjitter testresample testresample2可执行文件需要的.c源文件有testdenoise.c testec.c hotestjitter.c testresample.c testresample2.c

分析原生库下Makefile文件

Makefile里有什么?Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。

  • 显式规则。显式规则说明了如何生成一个或多个目标文件。这是由Makefile的书写者明显指出要生成的文件、文件的依赖文件和生成的命令。
  • 隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较简略地书写 Makefile,这是由make所支持的。
  • 变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点像你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
  • 文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。有关这一部分的内容,我会在后续的部分中讲述。
  • 注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用 # 字符,这个就像C/C++中的 // 一样。如果你要在你的Makefile中使用 # 字符,可以用反斜杠进行转义,如: # 。

笔者在speexdsp根目录下的makefile(最基本的Makefile)文件中
搜索关键字CFLAGS找到CFLAGS = -g -O2 -fvisibility=hidden这条语句

分析“make”过程log

以下是执行make命令后在终端显示的部分log,通过分析也可以知道编译so库需要的.c文件均位于libspeexdsp目录。

jiajiahao@ubuntu:~/Desktop/speexdsp-SpeexDSP-1.2.1$ make
make  all-recursive
make[1]: 进入目录“/home/jiajiahao/Desktop/speexdsp-SpeexDSP-1.2.1”
Making all in libspeexdsp
make[2]: 进入目录“/home/jiajiahao/Desktop/speexdsp-SpeexDSP-1.2.1/libspeexdsp”
  CC       preprocess.lo
  CC       jitter.lo
  CC       mdf.lo
  CC       fftwrap.lo
  CC       filterbank.lo
  CC       resample.lo
  CC       buffer.lo
  CC       scal.lo
  CC       smallft.lo
  CCLD     libspeexdsp.la
make[2]: 离开目录“/home/jiajiahao/Desktop/speexdsp-SpeexDSP-1.2.1/libspeexdsp”

分析build安装目录下生成的.pc文件

下图为build/lib/pkgconfig目录的speexdsp.pc文件

*.pc文件的所有参数:
Name: 该模块的名字,比如你的pc名字是xxxx.pc,那么名字最好也是xxxx。
Description: 模块的简单描述。上文pkg-config –list-all命令出来的结果,每个名字后面就是description。
URL: 用户可以通过该URL获得更多信息,或者下载信息。也是辅助的,可要可不要。
Version: 版本号。
Requires: 该模块有木有依赖于其他模块。一般没有。
Requires.private: 该模块有木有依赖于其他模块,并且还不需要第三方知道的。一般也没有。
Conflicts: 有没有和别的模块冲突。常用于版本冲突。比如,Conflicts: bar < 1.2.3,表示和bar模块的1.2.3以下的版本有冲突。
Cflags: 这个就很重要了。pkg-config的参数–cflags就指向这里。主要用于写本模块的头文件的路径。
Libs: 也很重要,pkg-config的参数–libs就指向这里。主要用于写本模块的库/依赖库的路径。
Libs.private: 本模块依赖的库,但不需要第三方知道。

在文件中的第14行中清楚的指出speexdsp依赖-lm这个库。

分析运行configure命令后生成的config.log

从中也可以分析出speexdsp依赖的库-lm 和编译器需要添加的C_FLAGS标记-g -O2 -fvisibility=hidden

configure:9932: checking for cos in -lm
configure:9957: gcc -o conftest -g -O2 -fvisibility=hidden   conftest.c -lm   >&5

结论

  • speexdsp依赖的库为-lm
  • 编译出speexdsp动态链接库需要的.c源文件为preprocess.c jitter.c mdf.c fftwrap.c filterbank.c resample.c buffer.c scal.c、smallft.c。
  • 编译出speexdsp动态链接库需要的.h源文件目录为libspeexdsp
  • 编译出测试用的testdenoise testecho testjitter testresample testresample2可执行文件需要的.c源文件有testdenoise.c testec.c hotestjitter.c testresample.c testresample2.c
  • 编译出测试用的testdenoise testecho testjitter testresample testresample2可执行文件需要的.h源文件目录为根目录下include
  • 编译时需要添加的cflags编译器标志为-o -g -O2 -fvisibility=hidden

为了能让大家更好的学习鸿蒙(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.鸿蒙南向开发方向