1、起因 今天调试了一个程序,发现symbol lookup error,本想网上找一下方法解决算了怎料找了半天都没写根因的文章,好不容易找到一篇类似的,竟然要收费! 自此打算分析一下,symbol lookup error无非就是链接和库
今天调试了一个程序,发现symbol lookup error,本想网上找一下方法解决算了怎料找了半天都没写根因的文章,好不容易找到一篇类似的,竟然要收费!
自此打算分析一下,symbol lookup error无非就是链接和库的查找问题。
先说我的应用场景(简化):
主程序(main)调用A(libefg.so)库,A库调用B库(libabc.so),main没有直接调用B库。
运行main程序的时候尽然报symbol lookup error!明明我的libabc.so也在同级目录。
./main: symbol lookup error: ./libefg.so: undefined symbol: _Z9print_abcv
编写B库libabc.so,包含test_abc.cpp和test_abc.h
// test_abc.cpp#include "test_abc.h"void print_abc(){ printf("abc\n");}
// test_abc.h#ifndef __TEST_ABC__#define __TEST_ABC__ 1#include #include void print_abc();#endif
// test_efg.cpp#include "test_efg.h"void print_def(){ printf("output def\n"); print_abc();}
// test_efg.h#ifndef __TEST_EFG__#define __TEST_EFG__ 1#include "test_abc.h"void print_def();#endif
// main.cpp#include "test_efg.h"int main(int arGC, char *argv[]){ printf("main...\n"); print_def(); return 0;}
cat Makefileall: g++ test_abc.cpp -shared -fPIC -o libabc.so g++ test_efg.cpp -shared -fPIC -o libefg.so g++ main.cpp -L. -Wl,-rpath=./ -lefg -o main -labc.PHONY: cleanclean: rm -rf libabc.so libefg.so main
编译完成后运行报错
main...output def./main: symbol lookup error: ./libefg.so: undefined symbol: _Z9print_abcv
纳闷了,明明libabc.so 和libefg.so都在本目录,不可能找得到libefg找不到libabc。
使用ldd查看二进制文件main,看看是不是找不到libabc
ldd ./main linux-vdso.so.1 (0x00007ffd069b1000) libefg.so => ./libefg.so (0x00007f0c19bc7000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0c195b7000) /lib64/ld-linux-x86-64.so.2 (0x00007f0c199a8000)
原来不只是找不到,而是压根没有libabc.so,可以看到libefg.so是可以认到的了,难怪没有abc的符号,再次确认了一下-labc也是已经加入了。
这次尝试去掉-labc看看能否编译通过
g++ main.cpp -L. -Wl,-rpath=./ -lefg -o main
竟然毫无压力的通过了。所以abc的符号在libefg上。
我们再回头看看libefg的编译参数
g++ test_efg.cpp -shared -fPIC -o libefg.so
这也没提醒我们链接libabc啊,因此尝试让libefg加上libabc的依赖
g++ test_efg.cpp -shared -fPIC -o libefg.so -Wl,-rpath=./ -L. -labc
再次整编译,运行正常!
以下写法是可以生成库和执行文件,但是运行还是出错。
cmake_minimum_required(VERSioN 2.8)set(name cmain)project(name)link_directories(${CMAKE_CURRENT_SOURCE_DIR})## add libabcadd_library(abc SHARED test_abc.cpp)## add libefgadd_library(efg SHARED test_efg.cpp)## add mainadd_executable(${name} main.cpp)target_link_libraries(${name} efg abc)
改为以下的写法,libefg增加libabc的支持后正常
cmake_minimum_required(VERSION 2.8)set(name cmain)project(name)link_directories(${CMAKE_CURRENT_SOURCE_DIR})## add libabcadd_library(abc SHARED test_abc.cpp)## add libefgadd_library(efg SHARED test_efg.cpp)target_link_libraries(efg abc)## add mainadd_executable(${name} main.cpp)target_link_libraries(${name} efg abc)
通过上述可以看到,中间的so(libefg)被main引用,main并不直接引用libabc的,所以中间编译的so也要加入相应的依赖,即使它能正常编译通过,实际是它找不到libabc的符号。
来源地址:https://blog.csdn.net/princeofdream/article/details/130567185
--结束END--
本文标题: Linux 动态库跨库调用 symbol lookup error原因详解
本文链接: https://lsjlt.com/news/415283.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-03-01
2024-03-01
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0