移植alsa-lib遇到的问题
linux audio alsa lib VERSIONED_SYMBOLS
这两天移植alsa lib时遇到了一个问题,被困住了好久。
做个记录,以后再被同样问题困住。
问题背景是这样的,有个项目,客户要求使用新的alsa-lib库。
到alsa官网上看了下,最新的是1.0.28。
既然可以要用新的,咱们就彻底满足客户,用个最新的。
接下来看看遇到了什么问题。
其实项目中以前也有alsa lib库,毕竟alsa是目前linux系统普遍采用的音频架构。
移植起来其实也没什么麻烦的。
首先,代码搞过来。
然后,执行configure,来生成一堆东东,其中最重要的一个是config.h文件。
一般linux下,应用程序或应用层的库文件,接下来就是make 和make install。
由于我们系统中有自己的make 脚本,所以这两步被我们自己的make 命令所替代。
第一个遇到的问题是:
externals/alsa-lib/src/alisp/alisp.c: In function 'obj_type_str':
externals/alsa-lib/src/alisp/alisp.c:1028:1: error: control reaches end of non-void function [-Werror=return-type]
看错误提示可以知道,这是一个类型非void的函数没有返回值。
但是从[-Werror=return-type]可知,这其实是一个 warning,只是被作为error对待了。
为什么会被作为error对待,因为有-Werror=return-type的配置。
在locl compile flag中,加入-Wno-error=return-type,问题解决。
上面这个问题很快被消灭,下面这个问题则费了我不是血。
问题提示:
/ld: failed to set dynamic section sizes: Bad value
编译是我的弱项,一见到编译问题,就感觉束手无策。
其实万果皆有因。没有无缘无故的错误。
先看了下error之前的编译log,没发现有用的信息。
接下来找度娘帮忙。
也有人遇到过类似问题,看到的一个该问题的解决方案是,其代码中有个函数声明了但没定义,导致了该问题,加上该函数定义,问题解决。
alsa lib的代码不是我写的,有没有声明了但没定义的函数,我也不知道。
alsa lib库的代码量也很可观,检查一遍只能是想想而已。
检查编译log,发现开始有很多warning提示一些宏重复定义了。
通过#ifndef,将这些warning解决。
编译还是有同样的问题。
编译log中还有一些函数参数未被使用的warning,找到这些函数看了下,没发现函数实现有哪个函数没定义(对应前面网上的解决方案)。
是不是在configure的时候有些参数指定的不对,导致有问题?
网上搜了搜别人的移植案例,没发现与我的配置不一致的地方。
既然configure的一个重要功能是生成config.h文件,那就比较下新生成的config.h文件与之去workable版本的config.h文件有什么区别。
比较发现,还是有不少区别。
先用旧的config.h替换过来。
make,通过了!!!
肯定是config.h的问题了。
通过逐类排除,最后发现新的config.h中多了个以下定义:
/* compiled with versioned symbols */
#define VERSIONED_SYMBOLS /**/
把该定义删除,编译就ok了。
用百度搜索该宏,发现有人已经遇到过同样的问题(度娘还是有两下子的):
http://www.android100.org/html/201409/16/65158.html
看到该定义,想起来编译错误之前有一句提示:
libasound.so: version node not found for symbol snd_ctl_elem_info_get_dimension@@ALSA_0.9.3
不过,度娘也只有两下子。
想看看VERSIONED_SYMBOLS的说明,还得靠谷歌。
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0206j/Beijfhhg.html
You can add specially-named symbols to input objects that cause the linker to create symbol versions. These symbols are of the form:
name@version for a non-default version of a symbol
name@@version for a default version of a symbol.
You must define these symbols, at the address of the function or data, as that you want to export. The symbol name is divided into two parts, a symbol name name and a version definition version. The name is added to the dynamic symbol table and becomes part of the interface to the shared object. Version creates a version called ver if it does not already exist and associates name with the version called ver.
For more information on how to create version symbols, see:
Adding symbol versions in the Compiler User Guide
Chapter 2 Writing ARM Assembly Language in the Assembler Guide.
Example 4.6 places the symbols foo@ver1,foo@@ver2, and bar@@ver1 into the object symbol table:
Example 4.6. Creating versioned symbols, embedded symbols
int old_function(void) __asm__("foo@ver1");
int new_function(void) __asm__("foo@@ver2");
int other_function(void) __asm__("bar@@ver1");
The linker reads these symbols and creates version definitions ver1 and ver2. The symbol foo is associated with a non-default version of ver1, and with a default version of ver2. The symbol bar is associated with a default version of ver1.
估计alsa lib中并没有定义foo@ver1和foo@@ver2类似的东东,所以出现了前面的错误。
解决办法即删除:
#define VERSIONED_SYMBOLS
There is no way to create associations between versions with this method.