Android.mk 链接库时undefined reference to的错误处理

我们在编译Android JNI的时候,经常要链接一些其他的开源库,总是会碰到undefined reference to的问题。

一般编译器报 “undefined reference to”的错误是以下几种情况。

1 没有指定对应的库(.o/.a/.so) 

使用了库中定义的实体,但没有指定库(-lXXX)或者没有指定库路径(-LYYY),会导致该错误, 

在Android.mk中 用LDFLAGS参数来定义库(-lXXX)和 (-LYYY)的

例如:
当前模块编译,依赖于 libxxx, libxxx2库,但是 libxxx 又依赖于 libxxx2, 这种情况时 需要对依赖的库的顺序进行调整
LOCAL_STATIC_LIBRARIES := \  
    ...  
    libxxx \
    libxxx2 \

2 连接库参数的顺序不对 

在默认情况下,对于-l 使用库的要求是越是基础的库越要写在后面,无论是静态还动态 

在实际使用的过程中,发现-D参数的使用,也会导致undefined reference to”的错误,推荐大家如果想在做宏控制的时候,把-D参数放到最后

3 gcc/ld 版本不匹配 
gcc/ld的版本的兼容性问题,由于gcc2 到 gcc3大版本的兼容性存在问题(其实gcc3.2到3.4也一定程度上存在这样的问题) 当在高版本机器上使用低版本的机器就会导致这样的错误, 这个问题比较常见在32位的环境上, 另外就在32位环境不小心使用了64位的库或者反过来64位环境使用了32位的库. 

这个问题与Linux下几乎一样

4 C/C++相互依赖和链接 
gcc和g++编译结果的混用需要保证能够extern "C" 两边都可以使用的接口,在我们的64位环境中gcc链接g++的库还需要加上 -lstdc++,具体见前文对于混合编译的说明 。 用JNI链接纯C语言的库,extern "C" 必须要包含头文件。
例如: 在 .h 中添加下面代码进行包裹:
#ifdef __cplusplus
extern "C" {
#endif
xxx code
#ifdef __cplusplus
}
#endif
5 运行期报错 

这个问题基本上是由于程序使用了dlopen方式载入.so, 但.so没有把所有需要的库都链接上,具体参加上文中对于静态库和动态库混合使用的说明 

关于执行时动态链接的问题,碰到过很纠结的情况,就是在Android链接的库依赖于我现在当前的库,就变成了你链接我,我再链接你,导致死都编不过,最好撇清这种关系.

当然这种双向依赖的问题也可以解决。
可以参考,动态库双向依赖解决方法: https://blog.csdn.net/u010144805/article/details/80745516


还有一种更简单的方法就是在Android.mk中加入 LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
一句话就可以搞定, 忽略链接错误,但是在运行中可能会出现错误,因为库文件找不到依赖的文件就会报错。

ps:是一种解决方案,但并不适用所有的问题,还是要具体问题具体分析


猜你喜欢

转载自blog.csdn.net/u010144805/article/details/80745279