Linux环境下共享库调用静态库时symbol lookup error问题求助
Linux下共享库符号查找错误的解决方法
场景(Linux环境):
可执行文件 -> 共享库 -> [xrt静态库] (基于Motif的商业产品)
可执行文件调用共享库,共享库调用xrt静态库。
编译链接步骤
共享库编译链接命令
$ gcc -fPIC --unresolved-symbols=ignore-in-shared-lib -c demo.c # 编译 $ gcc -shared -o libdemo.so demo.o # 链接
注意:共享库调用了xrt静态库的函数,但未链接该静态库
可执行文件链接命令
$ gcc -fPIC --unresolved-symbols=ignore-in-shared-lib main.c -Ixxxx $ gcc -o main main.o -Lxxxx -ldemo -L/opt/xrt/lib -lxrtm -lXpm -lxrt3d -lxrtfield -lxrtgauge -lxrtm -lxrttable -lpdsutil
可执行文件已链接xrt静态库
运行错误
执行可执行文件时出现符号查找错误:
$ ./main ./main: symbol lookup error: /xxx/libdemo.so: undefined symbol: xmXrtTabManagerWidgetClass
静态库符号检查结果
在xrt静态库目录下执行nm命令,结果如下:
$ nm *.a | grep xmXrtTabManagerWidgetClass U xmXrtTabManagerWidgetClass 0000000000000b18 D xmXrtTabManagerWidgetClass U xmXrtTabManagerWidgetClass U xmXrtTabManagerWidgetClass
已知xmXrtTabManagerWidgetClass符号定义在该商业静态库中,以下是可行的解决方法:
解决方法
1. 共享库链接时直接关联xrt静态库
修改共享库的链接命令,将xrt相关静态库直接链接到共享库中:
$ gcc -shared -o libdemo.so demo.o -L/opt/xrt/lib -lxrtm -lXpm -lxrt3d -lxrtfield -lxrtgauge -lxrttable -lpdsutil
这样共享库会内置所需的符号定义,运行时无需依赖可执行文件提供符号,从根源解决未定义符号问题。
2. 让可执行文件导出全局符号供共享库调用
在链接可执行文件时添加-rdynamic参数,该参数会让链接器导出可执行文件的全局符号表,允许动态加载的共享库在运行时从可执行文件中查找未定义的符号:
$ gcc -rdynamic -o main main.o -Lxxxx -ldemo -L/opt/xrt/lib -lxrtm -lXpm -lxrt3d -lxrtfield -lxrtgauge -lxrttable -lpdsutil
3. 调整静态库的链接顺序
Linux链接器按从左到右的顺序查找符号,依赖的库需要放在被依赖的库之后。检查并调整xrt静态库的链接顺序,确保包含xmXrtTabManagerWidgetClass定义的库出现在引用它的库之前。你当前命令中-lxrtm重复出现,可以清理冗余并优化顺序。
4. 精确定位包含符号定义的静态库
通过以下命令找到具体包含xmXrtTabManagerWidgetClass定义的静态库文件:
$ for lib in /opt/xrt/lib/*.a; do echo "检查库文件: $lib"; nm $lib | grep xmXrtTabManagerWidgetClass; done
确认该库被正确加入链接命令,并且顺序符合依赖要求。
内容的提问来源于stack exchange,提问作者HuangHaiFeng
相关产品推荐
相关产品推荐

