交叉编译连接器包含-ldl编译选项,但仍然报错undefined reference to ‘__dlsym‘
问题排查
为TX2交叉编译最新版本的BehaviorTree.Cpp库,使用cmake第一次编译BehaviorTree.Cpp的时候,生成behaviortree_cpp_v3.so时报出警告
warning: Using 'dlopen' in statically linked applications requires at runtime the shared library from the glibc version used for linking
虽然报出了这个警告,但是至少behaviortree_cpp_v3.so是生成出来了,只是后面的几个测试程序生成却报错:
../libbehaviortree_cpp_v3.so: undefined reference to '__dlsym'
../libbehaviortree_cpp_v3.so: undefined reference to '__dlopen'
../libbehaviortree_cpp_v3.so: undefined reference to '__dlclose'
../libbehaviortree_cpp_v3.so: undefined reference to '__dlerror'
不仅如此,将这个有问题的libbehaviortree_cpp_v3.so拿去给自己的程序使用仍然报找不到符号的错误。
去tx2的sysroot中找libdl.so
发现在/lib/aarch64-linux-gnu/libdl.so.2,查看导出动态链接符号
$ objdump -T libdl.so.2
0000000000000000 g DO .text 00000000000000cc GLIBC_2.17 dlsym
0000000000000000 g DO .text 000000000000002c GLIBC_2.17 dladdr
libdl.so则在tx2的sysroot中的/usr/lib/aarch64-linux-gnu/libdl.so
问题出在这里
libdl.so指向了/lib/aarch64-linux-gnu/libdl.so.2,这在TX2目标机上运行是没问题的,但是在host中,根本不存在这个文件。
交叉编译工具链需要的是包含了tx2-sysroot的位置即${tx2-sysroot}/lib/aarch64-linux-gnu/libdl.so.2。
为了能够兼容目标和主机,修正libdl.so符号链接ln -sf ../../../lib/aarch64-linux-gnu/libdl.so.2 libdl.so.2
再次重新编译BehaviorTree.CPP一切正常。
成因
回顾前面在编译libbehaviortree_cpp_v3.so的时候报出的警告
warning: Using 'dlopen' in statically linked applications requires at runtime the shared library from the glibc version used for linking
其实已经提示了,没有找到动态库,作为代替使用了/lib/aarch64-linux-gnu/libdl.a,但静态库的符号默认是位置相关的,并且其符号名也是另外一套规则
$ objdump -t libdl.a
dlsym.o: file format elf64-little
SYMBOL TABLE:
0000000000000000 l .text 0000000000000000 $x
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 w F .text 0000000000000000 dlsym
0000000000000000 *UND* 0000000000000000 __dlsym
看到那个__dlsym了没有
反思
说过无数次不要忽视任何警告,对待警告,就要如同对待错误一样。这次出现的问题再一次印证了这句话。

1万+

被折叠的 条评论
为什么被折叠?



