首页 > 代码库 > Android.mk 忽略链接错误

Android.mk 忽略链接错误

LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
一句话就可以搞定,但是在运行中可能会出现错误,因为库文件找不到依赖的文件就会报错。


有关linux下的依赖库知识解释
linux 编译动态链接库 so,避免运行时才发现函数未定义符号的错误(undefined symbol) ld的参数
ldd  查看 elf文件依赖的  so 动态链接库   可以  export LD_LIBRARY_PATH=/path 设置 so文件的路径,
nm   -u    *.so  或者 nm  |grep  U 查看  那些在  动态链接库中的符号。
 "U" The symbol is undefinedundefined的 symbol  这种就是表示 在其他 so动态链接库里面定义的。但是如果你的编译的 是so文件,如果符号不在外部任何so文件里面,默认的配置也不会提示错误。而是编译通过。那个自己忘了定义的符号也在 这  undefined  symbol里面,但是运行时就加载不成功了。
       文档说,这种编译so动态链接库时找不到符号(不在任何外部so文件里面,自己的程序也没有定义)也允许编译通过是有原因的,参见 ld 的man 说明   --allow-shlib-undefined 解释(好像英文版的才完整,中文的man ld不完整 可以直接查看网页 https://sourceware.org/binutils/docs-2.24/ld/Options.html#Options )。就是让你链接时用的一个版本的so,运行时加载用的另外一个版本的so,可能你的加载时的so里面有这个符号,所以就先让你找不到符号也编译通过了。如果是编译exe,这中链接时找不到定义的符号的就直接给你报错了。 so动态链接库就不会报错。其实这种特性应该是比较少用,最好在so链接是碰到这个未找到的符号也是报错的好。
     所以我觉得编译的动态链接库的时候最好加上 --unresolved-symbols=ignore-in-shared-libs  或者  --no-undefined 来检查一下。这样如果是自己的疏忽在 .c 源文件里面忘记的 某函数的定义,,编译的时候就可以提示错误了。
这里有3个参数可以使用--undefined symbols 和 --no-allow-shlib-undefined 参数的作用范围不一样而已,--undefined symbols 针对常规object文件,--no-allow-shlib-undefined针对的是符号在外部的未定义的shared object里面。--unresolved-symbols和--undefined symbols 作用差不多,不过更具体一些。
我们的目的主要是编译一个so动态链接库时,把自己object里面未定义的符号report出来就可以了,用--no-undefined和--unresolved-symbols=ignore-in-shared-libs应该可以的。
ld   的参数,  如果直接用gcc 编译,可以用   -Wl,--no-undefined 这样传过去
gcc -shared -Wl,-soname,libb.so.1,--no-undefined -o libb.so.1.2    objectfile 
gcc -shared -Wl,-soname,libb.so.1,--unresolved-symbols=ignore-in-shared-libs  -o libb.so.1.2   objectfile 

Android.mk 忽略链接错误