在linux上生成speexdsp的so动态链接库和.a静态链接库
- make和make install后会生成speexdsp的.so动态链接库和.a静态链接库
make
make install
其中build/lib目录下:
代码语言:shell复制├── 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如下
代码语言:shell复制## 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
代码语言:shell复制# 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目录。
代码语言:shell复制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
。
写在最后
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力;
- 关注小编,同时可以期待后续文章ing