Linux动态库和静态库的制作和使用

207 阅读2分钟

我们知道,C语言的编译过程可以分为下面几个步骤:

gcc -E hello.c -o hello.i  1.预处理  文件展开及宏展开
gcc -S hello.i -o hello.s  2.编译  将预处理之后的.i文件生成.s汇编文件
gcc -c hello.s -o hello.o  3.汇编  将.s汇编文件生成.o目标文件
gcc hello.o -o hello_elf   4.链接  将.o文件链接成目标文件

实际使用时,我们很可能会用到静态库和动态库,下面就来详细讲讲这两者的制作和使用方式。

静态编译和动态编译区别: 1、动态编译使用动态库,静态编译使用静态库 2、静态编译要把静态库文件打包到可执行程序中,动态编译不会把动态库文件打包到可执行程序中,它只是编译链接关系。

动态库

 gcc hello.c -o hello 

使用动态库文件进行编译,动态库并没有被编译到可执行程序当中去,在运行可执行程序的时候,根据链接关系去动态库中加载代码。 

制作动态库: gcc -shared mylib.c -o libtestlib.so 

编译程序: 

方法一: gcc mytest.c libtestlib.so -o mytest 

方法二: gcc mytest.c -o mytest -L/home/teacher -ltestlib -I/home/teacher 

以上两种方式编译通过,运行时出错,编译时找到了库函数,但链接时找不到,执行以下操作: export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH 表示将当前路径./加到搜索路径中去,运行时链接动态库就会从当前路径中去寻找动态库 

方法三: 将库文件和头文件放到系统默认指定的路径下(库文件默认的路径是/lib或者是/usr/lib,头文件默认的路径是/usr/include),此时就不需要设定环境变量了 

sudo mv libtestlib.so /usr/lib  
sudo mv mylib.h /usr/include  
gcc mytest.c -o mytest -ltestlib

静态库

gcc -static hello.c -o hello

使用静态库文件进行编译,可执行文件体积大,但运行时不需要依赖额外的库文件。 

制作静态库: 

gcc -c mylib.c -o mylib.o  
ar rc libtestlib.a mylib.o 

注意:静态库起名的时候必须以lib开头,以.a结尾 

编译程序: 

方法一: gcc -static mytest.c libtestlib.a -o mytest 

方法二: 比如将libtestlib.a和mylib.h移动到/home/teacher下(mv libtestlib.a mylib.h /home/teacher) 

gcc -static mytest.c -o mytest -L/home/teacher -ltestlib -I/home/teacher
-L指定库文件的路径  
-l指定找哪个库,取lib和.a之间的部分  
-I指定头文件的路径 

方法三: 将库文件和头文件放到系统默认指定的路径下(库文件默认的路径是/lib或者是/usr/lib,头文件默认的路径是/usr/include)

sudo mv libtestlib.a /usr/lib
sudo mv mylib.h /usr/include
gcc -static mytest.c -o mytest -ltestlib

注意: 

上面将静态库和动态库都放在了/usr/lib下,那么链接(gcc mytest.c -o mytest -ltestlib)的到底是动态库还是静态库呢? 

  • 当静态库和动态库重名的时候,系统优先链接动态库,或者可以加入-static指定使用静态库