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\n",var1, var2, add(var1,var2));
    printf("%d sub %d is %d\n",var1, var2, sub(var1,var2));
    printf("%d mul %d is %d\n",var1, var2, mul(var1,var2));
    printf("%d div %d is %d\n",var1, var2, div(var1,var2));
    printf("%d mod %d is %d\n",var1, var2, mod(var1,var2));
    printf("%d sqrt %d is %d\n",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文件都鏈接到內存上。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM