假如我要编译a.out,其中:
源文件:./main.c
库文件:./libs/libhiredis.so
库头文件目录:./
目标可执行文件:./a.out
主要理解三个编译选项
1. -L选项: 主要功能:在编译时,指明查找的库路径,形式为: g++ -L./libs -o a.out -lhiredis *.c
2. -Wl选项: syntax to pass an argument to the option. 传递参数给接下来的编译选项,与3选项配合使用
3. -rpath选项, 主要功能:在运行时,会去查找指明的库路径 形式为:g++ -Wl,-rpath=./:libs -lhiredis *.c 或者g++ -Wl,-rpath,./:libs -lhiredis *.c
错误一:如果少了-L选项(g++ -Wl,-rpath=./:libs -lhiredis *.c),编译时报错,找不到相应的库文件:
/usr/bin/ld: cannot find -lhiredis
collect2: ld returned 1 exit status
错误二:如果少了-Wl,-rpath选项(g++ -L./libs -o a.out -lhiredis *.c),运行时报错,运行时无法加载动态库:
./a.out: error while loading shared libraries: libhiredis.so.0.11: cannot open shared object file: No such file or directory
当然,执行如下指令,会提示libhiredis.so.0.11 => not found:
$ldd a.out
linux-vdso.so.1 => (0x00007fff68ba9000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fde4dcbb000)
libhiredis.so.0.11 => not found
正确的编译指令应该为:
$g++ -L./libs -o a.out -lhiredis *.c -Wl,-rpath=./:libs
$ldd a.out
linux-vdso.so.1 => (0x00007fff68ba9000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fde4dcbb000)
libhiredis.so.0.11 => ./libs/libhiredis.so.0.11 (0x00007fde4dab0000)
如果您想更进一步了解动态链接的相关知识:建议您阅读《linux/unix系统编程手册》下册的相关章节