Linux下Makefile,静态库,动态库的实现
Posted ouyang520
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux下Makefile,静态库,动态库的实现相关的知识,希望对你有一定的参考价值。
首先,创建一个文件夹,并在改文件夹下存进如下文件:
cal.h:头文件
#ifndef cal_h #define cal_h int add(int,int); int sub(int,int); int mul(int,int); int div(int,int); int mod(int,int); int sqtr(int,int); #endif
add.c:加法模块
#include"cal.h" int add(int var1, int var2){ return var1 + var2; }
div.c:除法模块
#include"cal.h" int div(int var1,int var2){ return var1 / var2; }
mod.c:取余模块
#include"cal.h" int mul(int var1,int var2){ return var1 * var2; }
sqrt:勾股定理模块
#include"cal.h" int sqrt(int var1,int var2){ return sqrt(var1^2+var2^2); }
mul.c加法模块
#include"cal.h" int mul(int var1,int var2){ return var1 * var2; }
sub.c:减法模块
#include"cal.h" int sub(int var1,int var2){ return var1 - var2; }
testcal.c
#include <stdio.h> #include "cal.h" int main(int argc, char **argv) { int var1; int var2; printf("please input var1:"); scanf("%d",&var1); printf("please input var2:"); scanf("%d",&var2); printf("%d add %d is %d ",var1, var2, add(var1,var2)); printf("%d sub %d is %d ",var1, var2, sub(var1,var2)); printf("%d mul %d is %d ",var1, var2, mul(var1,var2)); printf("%d div %d is %d ",var1, var2, div(var1,var2)); printf("%d mod %d is %d ",var1, var2, mod(var1,var2)); printf("%d sqrt %d is %d ",var1,var2,sqrt(var1,var2)); return 0; }
一:没有库的实现,首先编写makeflie文件:
OBJ=testcal.o add.o sub.o mul.o div.o mod.o sqtr.o testcal:$(OBJ) cal.h gcc $(OBJ) -o testcal testcal.o:testcal.c add.o:add.c sub.o:sub.c mul.o:mul.c div.o:div.c mod.o:mod.c sqrt.o:sqrt.c .PHONY:cleanA clean cleanA: rm testcal $(OBJ) clean: rm $(OBJ)
首先解释一下makeflie文件最重要的第二和第三行代码:testcal表示要生成的目标文件,冒号右边的表示要生成这个文件所要依赖的文件,$(OBJ)表示讲OBJ里的变量取出来。
然后输入make运行,得到以下显示:
[ouyangxi@DESKTOP-QNJ4U2U codeStudy]$ make cc -c -o testcal.o testcal.c cc -c -o add.o add.c cc -c -o sub.o sub.c cc -c -o mul.o mul.c cc -c -o div.o div.c cc -c -o mod.o mod.c gcc testcal.o add.o sub.o mul.o div.o mod.o -o testcal
同时输入ls -l可以查看文件大小
total 44 -rw-rw-rw- 1 ouyangxi ouyangxi 247 Mar 22 14:37 Makefile -rw-rw-rw- 1 ouyangxi ouyangxi 59 Mar 15 22:14 add.c -rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 22 14:38 add.o -rw-rw-rw- 1 ouyangxi ouyangxi 198 Mar 15 22:42 cal.h -rw-rw-rw- 1 ouyangxi ouyangxi 52 Mar 15 22:06 div.c -rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 22 14:38 div.o drwxrwxrwx 1 ouyangxi ouyangxi 512 Mar 21 09:42 libou.a drwxrwxrwx 1 ouyangxi ouyangxi 512 Mar 21 09:46 libou.so drwxrwxrwx 1 ouyangxi ouyangxi 512 Mar 21 09:37 liboyx.a drwxrwxrwx 1 ouyangxi ouyangxi 512 Mar 20 19:40 liboyx.so -rw-rw-rw- 1 ouyangxi ouyangxi 52 Mar 15 22:07 mod.c -rw-rw-rw- 1 ouyangxi ouyangxi 1240 Mar 22 14:38 mod.o -rw-rw-rw- 1 ouyangxi ouyangxi 52 Mar 15 22:32 mul.c -rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 22 14:38 mul.o -rw-rw-rw- 1 ouyangxi ouyangxi 63 Mar 15 22:04 sub.c -rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 22 14:38 sub.o -rwxrwxrwx 1 ouyangxi ouyangxi 8696 Mar 22 14:38 testcal -rw-rw-rw- 1 ouyangxi ouyangxi 568 Mar 18 23:34 testcal.c -rw-rw-rw- 1 ouyangxi ouyangxi 2832 Mar 22 14:38 testcal.o
可以看testcal可执行文件非常小,只有8K大
最后执行可执行文件,使用命令:./testcal
[ouyangxi@DESKTOP-QNJ4U2U codeStudy]$ ./testcal please input var1:6 please input var2:8 begin run:6 add 8 is 14 6 sub 8 is -2 6 mul 8 is 48 6 div 8 is 0 6 mod 8 is 6
二、使用静态库文件,生成静态库。库文件一般以lib为前缀,紧接着是库的名称oyx,扩展名为.a,例如我们这里要创建库名liboyx.a的库,使用命令ar,具体如下:
ar rcs libcal.a add.o sub.o mul.o div.o mod.o
使用静态库,创建库文件的接口文件头文件,本文中是cal.h文件,使用库文件的文件testCal.c包含头文件cal.h文件即可,使用如下命令编译:
gcc -o testCal testCal.c -static -L. -lcal
其中,testcal为最终的可执行文件,testcal.c表示要生成testcal所要依靠的文件,这里还要注意以下-L后面是有.的,千万不要漏掉。
[ouyangxi@DESKTOP-QNJ4U2U liboyx.a]$ ./testcal please input var1:1 please input var2:4 begin run:1 add 4 is 5 1 sub 4 is -3 1 mul 4 is 4 1 div 4 is 0 1 mod 4 is 1
可见,testcal可以编译运行,在来看看这时的testcal的大小:
[ouyangxi@DESKTOP-QNJ4U2U liboyx.a]$ ls -l total 969 -rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 20 19:28 add.o -rw-rw-rw- 1 ouyangxi ouyangxi 198 Mar 20 19:28 cal.h -rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 20 19:28 div.o -rw-rw-rw- 1 ouyangxi ouyangxi 6580 Mar 20 19:30 liboyx.a -rw-rw-rw- 1 ouyangxi ouyangxi 1240 Mar 20 19:28 mod.o -rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 20 19:28 mul.o -rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 20 19:28 sub.o -rwxrwxrwx 1 ouyangxi ouyangxi 958552 Mar 20 19:31 testcal -rw-rw-rw- 1 ouyangxi ouyangxi 568 Mar 20 19:28 testcal.c
虽然静态库使用起来比较方便,其具有良好的远程地址链接性,但是其缺点就是占有的地址空间很大。
三:动态库的实现
先创建一个文件夹方便我们操作,再将所有的.o,testcal.c和cal.h放进这个文件夹
首先运行如下命令:
gcc -shared -fPIC -o liboyx.so add.o sub.o mul.o div.o mod.o
库文件一般以lib为前缀,紧接着是库的名称oyx,扩展名为.so,这样就生成了一个名称为liboyx.so的动态库
然后输入以下命令:
gcc -o testcal testcal.c -L. -loyx
即可生成一个名为testcal的可执行文件,但当我输入./testcal后却发现无法编译,这时再输入以下指令:
export LD_LIBRARY_PATH=$(pwd)
或者
sudo ldconfig /home/munication/WORKM/libDemo/
就可以解决问题了,这是再输入./testcal:
[ouyangxi@DESKTOP-QNJ4U2U liboyx.so]$ export LD_LIBRARY_PATH=$(pwd) [ouyangxi@DESKTOP-QNJ4U2U liboyx.so]$ ./testcal please input var1:1 please input var2:5 begin run:1 add 5 is 6 1 sub 5 is -4 1 mul 5 is 5 1 div 5 is 0 1 mod 5 is 1
可见,可以成功运行,再看看文件大小
[ouyangxi@DESKTOP-QNJ4U2U liboyx.so]$ ls -l total 45 -rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 20 19:36 add.o -rw-rw-rw- 1 ouyangxi ouyangxi 198 Mar 20 19:40 cal.h -rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 20 19:36 div.o -rwxrwxrwx 1 ouyangxi ouyangxi 7664 Mar 20 19:38 liboyx.so -rw-rw-rw- 1 ouyangxi ouyangxi 1240 Mar 20 19:36 mod.o -rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 20 19:36 mul.o -rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 20 19:36 sub.o -rwxrwxrwx 1 ouyangxi ouyangxi 8544 Mar 20 19:40 testcal -rw-rw-rw- 1 ouyangxi ouyangxi 568 Mar 20 19:39 testcal.c -rw-rw-rw- 1 ouyangxi ouyangxi 2832 Mar 20 19:36 testcal.o
可以看见,testcal文件只有8k左右,相比于静态库,动态库生成的可执行文件要小的多,但是动态库其缺点就是要保持远程地址与.o变量地址一致。
附加:在建立动态库的时候要使用gcc -fPIC-c add.c sub.c mul.c div.c mod.c sqrt.c命令确保所以的.o文件都链接到内存上。
以上是关于Linux下Makefile,静态库,动态库的实现的主要内容,如果未能解决你的问题,请参考以下文章