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,静态库,动态库的实现的主要内容,如果未能解决你的问题,请参考以下文章

C开发编译与调试

Ubuntu下makefile及gcc生成静态库动态库的简单使用举例

在linux环境下静态库(.a)的编译和使用

Makefile 链接静态库

怎么编写Makefile生成静态库

Makefile常用万能模板(包括静态链接库动态链接库可执行文件)