-LDirectory
-L 用于指定连接库所需要的搜索路径,后面的参数“Directory”为相对路径或绝对路径
-llibrary
-l 用于指定连接库文件选项例如:-lmylib 如果存在静态库,则意味着需要连接libmylib.a;如果存在动态库,则意味着需要连接libmylib.so
-static
-static 采用静态连接的方式连接程序step1.编译源文件生成目标文件(*.o)
gcc -c -o main.o main.c
step2.连接目标文件,生成可执行程序
gcc main.o -o test //动态连接方式生成可执行程序
gcc main.o -static -o test_static //生成静态连接的可执行程序
生成动态库:
比如:gcc -shared test.o -o libtest_d.so //将test.o文件连接,生成动态库的名称为libtest_d.so
生成动态可执行文件:
gcc test.o -L. -ltest_d -o test_dlib //生成动态连接的可执行程序test_dlib
-L.在连接时搜索库文件的时候包含当前目录;-ltest_d连接名称为libtest_d.so的动态库。
1.编写测试程序:
用vi编写say.c程序如下:
#include "stdio.h"
void say()
{
printf("Say!");
}
用vi编写test.c程序如下:
#include "stdio.h"
void say();
main(){
say();
}
2.静态编译:
2.1. 编译源文件生成目标文件say.o
gcc -c say.c
2.2. 使用静态编译归档命令ar将目标文件编译成say.a静态库文件
ar -r say.a say.o
2.3. 编译test.c文件并连接目标静态库文件say.a生成可执行程序test
gcc test.c say.a -o test (或上一步用名字libsay.a,这里用命令gcc test.c -L. -lsay -o test)
2.4. 测试
file test
test: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux2.2.5, dynamically linked (uses shared libs), not stripped
ldd test
libc.so.6 => /lib/tls/libc.so.6(0x42000000)
/lib/ld-linux.so.2 =>/lib/ld-linux.so.2 (0x40000000)
输出结果让我们看不到任何跟say.a这个我们自己写的静态库的关系.说明程序运行时已经不需要这个静态库了,它已经被ld链接进最终的程序了.
3.动态编译
3.1.
gcc -fPIC -shared say.c -o say.so
3.2.
gcc test.c say.so -o test(如果这里用gcc test.c ./say.so -o test则把say.so的相对路径硬编码进了程序里,ldd查看可知能找到)
3.3.测试
ldd test
(或用gcc -shared -Wall -g say.c -olibsay_d.so;再gcc test.c -L. -lsay_d -o test;最后用ldd test查看)
4.测试结果
ldd test
say.so => not found
libc.so.6 => /lib/tls/libc.so.6(0x42000000)
/lib/ld-linux.so.2 =>/lib/ld-linux.so.2 (0x40000000)
file test
test: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux2.2.5, dynamically linked (uses shared libs), not stripped
如果不出意外的话,会出现say.so => notfound.这时的./test是不能运行的.这是因为默认动态库搜索路径还没有设置,所以找不到say.so在哪,但至少说明程序运行时是需要这个库的.
===========================
.so文件 搜索顺序:
LD_LIBRARY_PATH变量
ld.so.cache (由 ldconfig 生成)
binutils 编译时候指定的 --with-lib-path 参数
还有,如果要让 ldconfig 搜索到相应的 so 文件,文件名必须要是 libXXXX.so 这样的格式才行。
===========================
所以想让上面动态编译的程序能够运行,可以用如下方法将当前路径“.目录”加入搜索范围,或将say.so拷贝至/lib等默认搜索路径:
exportLD_LIBRARY_PATH=.