- 大家好!我来自南京,在OpenHarmony成长计划啃论文俱乐部,与
华为、软通动力、润和软件、拓维信息、深开鸿
等公司一起,学习和研究操作系统技术
,
从今年1月11日加入OpenHarmony俱乐部已经有接近8个月时间了。笔者一直在思考啃论文给我带来了些什么,通过啃论文能为OpenHarmony做些什么。笔者利用大二升大三暑假两个月时间移植了Speexdsp这个三方库到OpenHarmony标准系统,而关于前面的问题我似乎找到了答案,现将啃论文和三方库移植分享经验如下:
由于想要分享的内容较多,为避免读者姥爷们失去看下去的耐心,分享将以连载的方式进行。
往期回顾:啃论文俱乐部——移植speexdsp到OpenHarmony标准系统①
本期为移植speexdsp到OpenHarmony标准系统
的第②期,主要内容如下:
目录

在linux上生成speexdsp的so动态链接库和.a静态链接库
- make和make install后会生成speexdsp的.so动态链接库和.a静态链接库

其中build/lib目录下:
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工具能以树形的方式显示指定目录的层级结构。
非绿色字体是编译后生成的文件。
├── acinclude.m4
├── AUTHORS #speexdsp项目作者信息
├── autogen.sh #autogen.sh脚本配置文件
├── aclocal.m4 #运行aclocal后生成的aclocal.m4文件和一个缓冲文件夹autom4te.cache
├── autom4te.cache
│ ├── output.0
│ ├── output.1
│ ├── output.2
│ ├── requests
│ ├── traces.0
│ ├── traces.1
│ └── traces.2
├── build
│ ├── include
│ │ └── speex
│ │ ├── speexdsp_config_types.h
│ │ ├── speexdsp_types.h
│ │ ├── speex_echo.h
│ │ ├── speex_jitter.h
│ │ ├── speex_preprocess.h
│ │ └── speex_resampler.h
│ ├── lib
│ │ ├── libspeexdsp.a
│ │ ├── libspeexdsp.la
│ │ ├── libspeexdsp.so -> libspeexdsp.so.1.5.2
│ │ ├── libspeexdsp.so.1 -> libspeexdsp.so.1.5.2
│ │ ├── libspeexdsp.so.1.5.2
│ │ └── pkgconfig
│ │ └── speexdsp.pc
│ └── share
│ └── doc
│ └── speexdsp
│ └── manual.pdf
├── ChangeLog#spexxds原生库更新日志(和本次移植无关信息)
├── compile
├── config.guess#这个是在构建环境上运行的一个脚本,它用来猜测构建机的配置环境,因为这个脚本是在构建机上运行,所以它可以动态执行uname等命令来获得构建机的环境,所以我们一般不要指定这个变量,从而让脚本自动获得。
├── config.h#Config.h是自动生成的头文件,是根据配置文件Config.h.in生成的。config.h主要用于代码移植,产生可移植代码。
├── config.h.in#autoheader后形成config.h.in
├── config.log#该文件在执行configure文件时动态生成,包含了一些行号信息,表示一个文件在哪一行执行,以及执行的什么命令,因此可以知道测试是在哪个位置中完成。
├── config.status#这是脚本文件,运行该脚本可以生成一个当前相同的配置,从而避免再次执行configure这个比较庞大的代码。也就是config.log生成的是文本文件,而config.status生成的则是命令脚本文件。
├── config.sub#这个是将host target build变量正则化的一个脚本,它的sub就是substitute的缩写。因为用户提供的build可能并不符合脚本正规的四元组或者三元组的结构,所以这个脚本将它转换为标准的格式,从而可以进行格式化处理。
├── configure#这个是我们需要监测环境的主要入口文件,使用该文件可以生成Makefile文件,它会替换Makefile中需要替换的变量。
├── configure.ac#该文件为autoconfigure文件使用的一个文件,该文件用来生成configure文件,这个文件一般是开发者维护,我们安装该软件的时候只需要执行configure就可以,这个configure.ac我们一般不用理会
├── COPYING
├── depcomp#automake --add-missing命令生成install-sh, missing, depcomp文件
├── doc
│ ├── celpdecoder.eps
│ ├── celpdecoder.odg
│ ├── components.eps
│ ├── components.odg
│ ├── echopath.eps
│ ├── echopath.odg
│ ├── Makefile
│ ├── Makefile.am
│ ├── Makefile.in
│ ├── manual.lyx
│ ├── manual.pdf
│ ├── programming.html
│ ├── refshaping.eps
│ ├── sampledec.c
│ ├── sampleenc.c
│ ├── speexabs.eps
│ ├── speexabs.odg
│ ├── speexanalysis.eps
│ └── speexanalysis.odg
├── Doxyfile
├── html
│ ├── speex.png
│ ├── speex.webprj
│ └── speex.xcf
├── include
│ ├── Makefile
│ ├── Makefile.am
│ ├── Makefile.in
│ └── speex
│ ├── Makefile
│ ├── Makefile.am
│ ├── Makefile.in
│ ├── speexbuffer.h
│ ├── speexdsp_config_types.h
│ ├── speexdspconfigtypes.h.in
│ ├── speexdsptypes.h
│ ├── speexecho.h
│ ├── speexjitter.h
│ ├── speexpreprocess.h
│ └── speexresampler.h
├── INSTALL
├── install−sh#automake --add-missing命令生成install-sh, missing, depcomp文件
├── libspeexdsp
│ ├── arch.h
│ ├── bfin.h
│ ├── buffer.c
│ ├── buffer.lo
│ ├── buffer.o
│ ├── echodiagnostic.m
│ ├── fftwrap.c
│ ├── fftwrap.h
│ ├── fftwrap.lo
│ ├── fftwrap.o
│ ├── filterbank.c
│ ├── filterbank.h
│ ├── filterbank.lo
│ ├── filterbank.o
│ ├── fixedarm4.h
│ ├── fixedarm5e.h
│ ├── fixedbfin.h
│ ├── fixeddebug.h
│ ├── fixedgeneric.h
│ ├── jitter.c
│ ├── jitter.lo
│ ├── jitter.o
│ ├── kissfft.c
│ ├── kissfftguts.h
│ ├── kissfft.h
│ ├── kissfftr.c
│ ├── kissfftr.h
│ ├── libspeexdsp.la
│ ├── Makefile
│ ├── Makefile.am
│ ├── Makefile.in
│ ├── mathapprox.h
│ ├── mdf.c
│ ├── mdf.lo
│ ├── mdf.o
│ ├── miscbfin.h
│ ├── ossupport.h
│ ├── preprocess.c
│ ├── preprocess.lo
│ ├── preprocess.o
│ ├── pseudofloat.h
│ ├── resample.c
│ ├── resample.lo
│ ├── resampleneon.h
│ ├── resample.o
│ ├── resamplesse.h
│ ├── scal.c
│ ├── scal.lo
│ ├── scal.o
│ ├── smallft.c
│ ├── smallft.h
│ ├── smallft.lo
│ ├── smallft.o
│ ├── testdenoise
│ ├── testdenoise.c #测试噪音抑制的文件
│ ├── testdenoise.o
│ ├── testecho
│ ├── testecho.c #测试声学回音消除的文件
│ ├── testecho.o
│ ├── testjitter # 测试抖动的文件
│ ├── testjitter.c
│ ├── testjitter.o
│ ├── testresample
│ ├── testresample2
│ ├── testresample2.c#测试重采样的文件
│ ├── testresample2.o
│ ├── testresample.c#测试重采样的文件
│ ├── testresample.o
│ └── vorbispsy.h
├── libtool
├── ltmain.sh
├── m4
│ ├── libtool.m4
│ ├── lt~obsolete.m4
│ ├── ltoptions.m4
│ ├── ltsugar.m4
│ └── ltversion.m4
├── macosx
│ ├── English.lproj
│ │ └── InfoPlist.strings
│ ├── Info.plist
│ ├── SpeexPrefix.pch
│ ├── SpeexUB.xcodeproj
│ │ └── project.pbxproj
│ └── Speex.xcodeproj
│ └── project.pbxproj
├── Makefile
├── Makefile.am
├── Makefile.in
├── missing#automake --add-missing命令生成install-sh, missing, depcomp文件
├── NEWS
├── README
├── README.blackfin#汇聚式处理器Blackfin是由ADI和Intel公司联合开发的微信号架构(MSA)
├── README.Trimedia#Trimedia 是由Philips公司1996年推出的新一代媒体处理器(Media Processor)芯片。
├── README.win32#Win32是指Microsoft Windows操作系统的32位环境
├── regression−fixes
│ └── 1−resamplerunsignedfix.patch
├── regressions
├── SpeexDSP.kdevelop
├── speexdsp.pc
├── speexdsp.pc.in
├── SpeexDSP.spec
├── SpeexDSP.spec.in
├── stamp-h1
├── symbian
│ ├── bld.inf
│ ├── config.h
│ ├── Makefile
│ ├── Makefile.am
│ ├── Makefile.in
│ └── speex.mmp
├── ti#TI公司DSP芯片
│ ├── config.h
│ ├── Makefile
│ ├── Makefile.am
│ ├── Makefile.in
│ ├── ossupportcustom.h
│ ├── speexC54test
│ │ ├── Makefile
│ │ ├── Makefile.am
│ │ ├── Makefile.in
│ │ ├── speexC54test.cmd
│ │ └── speexC54test.pjt
│ ├── speexC55test
│ │ ├── Makefile
│ │ ├── Makefile.am
│ │ ├── Makefile.in
│ │ ├── speexC55test.cmd
│ │ └── speexC55test.pjt
│ └── speexC64test
│ ├── Makefile
│ ├── Makefile.am
│ ├── Makefile.in
│ ├── speexC64test.cmd
│ └── speexC64test.pjt
├── tmv
│ ├── config.h
│ ├── fftwraptm.h
│ ├── filterbanktm.h
│ ├── fixedtm.h
│ ├── kissfftgutstm.h
│ ├── kissfftrtm.h
│ ├── kissffttm.h
│ ├── mdftm.h
│ ├── misctm.h
│ ├── preprocesstm.h
│ ├── profiletm.h
│ └── speexconfigtypes.h
├── TODO
└── win32
├── config.h
├── libspeexdsp
│ ├── libspeexdsp.dsp
│ ├── libspeexdsp.dsw
│ ├── libspeexdspdynamic.dsp
│ ├── Makefile
│ ├── Makefile.am
│ └── Makefile.in
├── libspeexdsp.def
├── Makefile
├── Makefile.am
├── Makefile.in
├── speex.iss
├── VS2003
│ ├── libspeexdsp
│ │ ├── libspeexdsp.vcproj
│ │ ├── Makefile
│ │ ├── Makefile.am
│ │ └── Makefile.in
│ ├── libspeexdsp.sln
│ ├── Makefile
│ ├── Makefile.am
│ ├── Makefile.in
│ └── tests
│ ├── Makefile
│ ├── Makefile.am
│ ├── Makefile.in
│ ├── testdenoise.vcproj
│ ├── testecho.vcproj
│ └── testresample.vcproj
├── VS2005
│ ├── libspeexdsp
│ │ ├── libspeexdsp.vcproj
│ │ ├── Makefile
│ │ ├── Makefile.am
│ │ └── Makefile.in
│ ├── libspeexdsp.sln
│ ├── Makefile
│ ├── Makefile.am
│ ├── Makefile.in
│ └── tests
│ ├── Makefile
│ ├── Makefile.am
│ ├── Makefile.in
│ ├── testdenoise.vcproj
│ ├── testecho.vcproj
│ └── testresample.vcproj
└── VS2008
├── libspeexdsp
│ ├── libspeexdsp.vcproj
│ ├── Makefile
│ ├── Makefile.am
│ └── Makefile.in
├── libspeexdsp.sln
├── Makefile
├── Makefile.am
├── Makefile.in
└── tests
├── Makefile
├── Makefile.am
├── Makefile.in
├── testdenoise.vcproj
├── testecho.vcproj
└── testresample.vcproj
分析原生库下make.am文件
- make.am是一种比Makefile文件抽象程序更高的编译规则文件。 在里面可以指定生成目录,编译用的源码,编译的时候依赖哪些库,要安装到什么目录。
原生库根目录下的make.am如下
父目录需要包含子目录,在父目录下的Makefile.am中需要添加: SUBDIRS = 子目录。可知speexdsp子目录为libspeexdsp include doc win32 symbian ti 。再逐步查看各个文件夹源码可知只有libspeexdsp
include
文件夹与本次移植有关。所以接下来查看libspeexdsp目录下的make.am文件
子目录libspeexdsp下的make.am
通过分析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目录。
分析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
结论
- 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
。
下期分享内容:将三方库加入到OpenHarmony的编译体系
虽然做好了大佬高产的准备,没想到这么快
纯干货,必须支持
还有很多,在整理ing
期待ing
第三期内容https://ost.51cto.com/posts/16711