1、起因
今天調(diào)試了一個(gè)程序,發(fā)現(xiàn)symbol lookup error,本想網(wǎng)上找一下方法解決算了怎料找了半天都沒(méi)寫(xiě)根因的文章,好不容易找到一篇類(lèi)似的,竟然要收費(fèi)!
自此打算分析一下,symbol lookup error無(wú)非就是鏈接和庫(kù)的查找問(wèn)題。
先說(shuō)我的應(yīng)用場(chǎng)景(簡(jiǎn)化):
主程序(main)調(diào)用A(libefg.so)庫(kù),A庫(kù)調(diào)用B庫(kù)(libabc.so),main沒(méi)有直接調(diào)用B庫(kù)。
運(yùn)行main程序的時(shí)候盡然報(bào)symbol lookup error!明明我的libabc.so也在同級(jí)目錄。
./main: symbol lookup error: ./libefg.so: undefined symbol: _Z9print_abcv
2、分析
2.1 代碼結(jié)構(gòu)
編寫(xiě)B(tài)庫(kù)libabc.so,包含test_abc.cpp和test_abc.h
2.1.1 libabc.so
// test_abc.cpp
#include "test_abc.h"
void print_abc()
{
printf("abc\n");
}
// test_abc.h
#ifndef __TEST_ABC__
#define __TEST_ABC__ 1
#include <stdlib.h>
#include <stdio.h>
void print_abc();
#endif /* ifndef __TEST_ABC__ */
2.1.2 libefg.so
// 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 /* ifndef __TEST_EFG__ */
2.1.3 main
// main.cpp
#include "test_efg.h"
int main(int argc, char *argv[])
{
printf("main...\n");
print_def();
return 0;
}
2.2 代碼編譯
cat Makefile
all:
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: clean
clean:
rm -rf libabc.so libefg.so main
編譯完成后運(yùn)行報(bào)錯(cuò)
main...
output def
./main: symbol lookup error: ./libefg.so: undefined symbol: _Z9print_abcv
納悶了,明明libabc.so 和libefg.so都在本目錄,不可能找得到libefg找不到libabc。
使用ldd查看二進(jìn)制文件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)
原來(lái)不只是找不到,而是壓根沒(méi)有l(wèi)ibabc.so,可以看到libefg.so是可以認(rèn)到的了,難怪沒(méi)有abc的符號(hào),再次確認(rèn)了一下-labc也是已經(jīng)加入了。
這次嘗試去掉-labc看看能否編譯通過(guò)
g++ main.cpp -L. -Wl,-rpath=./ -lefg -o main
竟然毫無(wú)壓力的通過(guò)了。所以abc的符號(hào)在libefg上。
我們?cè)倩仡^看看libefg的編譯參數(shù)
g++ test_efg.cpp -shared -fPIC -o libefg.so
這也沒(méi)提醒我們鏈接libabc啊,因此嘗試讓libefg加上libabc的依賴(lài)
g++ test_efg.cpp -shared -fPIC -o libefg.so -Wl,-rpath=./ -L. -labc
再次整編譯,運(yùn)行正常!
2.3 CMake
以下寫(xiě)法是可以生成庫(kù)和執(zhí)行文件,但是運(yùn)行還是出錯(cuò)。
cmake_minimum_required(VERSION 2.8)
set(name cmain)
project(name)
link_directories(${CMAKE_CURRENT_SOURCE_DIR})
## add libabc
add_library(abc SHARED test_abc.cpp)
## add libefg
add_library(efg SHARED test_efg.cpp)
## add main
add_executable(${name} main.cpp)
target_link_libraries(${name} efg abc)
改為以下的寫(xiě)法,libefg增加libabc的支持后正常文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-686363.html
cmake_minimum_required(VERSION 2.8)
set(name cmain)
project(name)
link_directories(${CMAKE_CURRENT_SOURCE_DIR})
## add libabc
add_library(abc SHARED test_abc.cpp)
## add libefg
add_library(efg SHARED test_efg.cpp)
target_link_libraries(efg abc)
## add main
add_executable(${name} main.cpp)
target_link_libraries(${name} efg abc)
3. 結(jié)論
通過(guò)上述可以看到,中間的so(libefg)被main引用,main并不直接引用libabc的,所以中間編譯的so也要加入相應(yīng)的依賴(lài),即使它能正常編譯通過(guò),實(shí)際是它找不到libabc的符號(hào)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-686363.html
到了這里,關(guān)于Linux 動(dòng)態(tài)庫(kù)跨庫(kù)調(diào)用 symbol lookup error原因詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!