程序代码在编译的时候没问题,但是在运行的时候报错:
./bin: symbol lookup error: ./bin: undefined symbol: xxx
百度了一下,貌似是程序运行时使用的动态库和编译时makefile 指定链接的动态库不同所致。用ldd查看文件使用到的库,有很多,但是仔细看 undefined symbol: 后的一串文字:
_ZN10xxx8xxxEPKcz
这里面会说明是哪个符号没有定义(xxx代替),找出这个符号所在的库,修改一下运行时的动态库搜索路径,使之和makefile指定的链接路径一致,就没有问题了。
简单演示
代码目录为:
|-- lib
| |-- func.cpp
| |-- func.h
| `-- makefile
|-- main.cpp
|-- makefile
`-- test.sh
1、头文件func.h
void test();
void test1();
2、源文件func.cpp:
#include <iostream>
#include "func.h"
void test()
{
std::cout << "test ok" << std::endl;
}
void test1()
{
std::cout << "test1 ok" << std::endl;
}
3、main函数:
#include <iostream>
#include "func.h"
int main()
{
test();
test1();
}
4、顶层makefile:
target=main
lib=-L./lib/ -lfunc
OBJ=./lib/func.o
FUNCLIB=./lib/libfunc.so
INCLUDE=-I./lib
$(target): main.cpp $(FUNCLIB)
g++ -ggdb3 main.cpp -o $@ $(INCLUDE) $(lib)
$(FUNCLIB):$(OBJ)
g++ -fPIC -shared $^ -o $@
$(OBJ):./lib/func.cpp
g++ -c -fPIC -ggdb3 -o $@ $^
clean:
rm -rf $(target) $(OBJ) $(FUNCLIB)
5、测试脚本test.sh:
export LD_LIBRARY_PATH=./lib
./main
编译(在顶层目录make)后,脚本执行结果为:
test ok
test1 ok
这里没有问题。
现在将func.cpp的一个函数注释掉:
头文件func.h:
void test();
//void test1();
源文件func.cpp:
#include <iostream>
#include "func.h"
void test()
{
std::cout << "test ok" << std::endl;
}
//void test1()
//{
// std::cout << "test1 ok" << std::endl;
//}
单独在lib目录下创建一个makefile:
target=libfunc.so
obj=func.o
$(target):$(obj)
g++ -shared -fPIC -o $@ $^
$(obj):func.cpp
g++ -fPIC -c $^ -o $@
clean:
rm -rf $(target) $(obj)
编译,此时libfunc.so文件更新了
再回到上次目录,执行脚本,此时就会报错:
test ok
./main: symbol lookup error: ./main: undefined symbol: _Z5test1v
从 undefined symbol 后面的信息来看,是test1没有定义,所以根据这个定位到是库文件libfunc.so的问题,这个问题是编译时用到的动态库,和运行时不一致,导致的错误。
参考: