Makefile文件編寫

源代碼文件

main3.capp

 1 #include <stdio.h>
 2 #include "static_lib.h"
 3 #include "fun.h"
 4 
 5 int main(void){
 6     int a=2,b=3;
 7     printf("add:%d sub:%d mul:%d div:%d\n",add(a,b),sub(a,b),mul(a,b),div(a,b));
 8     fun1();
 9     return 0;
10 }

static_lib.h和函數

1 extern int add(int a,int b);
2 extern int sub(int a,int b);
3 extern int mul(int a,int b);
4 extern int div(int a,int b);

static_lib.cui

 1 int add(int a,int b){
 2     return a + b;
 3 }
 4 
 5 int sub(int a,int b){
 6     return a - b;
 7 }
 8 
 9 int mul(int a,int b){
10     return a * b;
11 }
12 
13 int div(int a,int b){
14     return a / b;
15 }

fun.h和spa

1 extern void fun1();

fun.c3d

1 #include <stdio.h>
2 void fun1(){
3     printf("fun1 ...");
4 }

其中stati_lib.c中的文件編譯成靜態庫code

正常編譯

按照正常的編譯方法,這個程序能夠按以下順序編譯blog

可是每次改了源代碼以後都這樣子編譯顯然是不明智的,因此須要編寫一個Makefile規則文件get

Makefile Base

Makefile的規則爲源碼

其中target是目標文件或者動做it

prerequisites是生成目標依賴的文件

command是規則執行的命令,若是命令與依賴規則在一行,則以';'分割,若是在另外一行,則以tab開頭

編寫一個最簡單的Makefile編譯這些源碼

 1 app3  : static_lib.a fun.o
 2     gcc main3.c static_lib.a fun.o -o app3
 3 
 4 fun.o :
 5     gcc -c fun.c
 6 static_lib.o : 
 7     gcc -c static_lib.c
 8 
 9 static_lib.a : static_lib.o
10     ar rcs static_lib.a static_lib.o
11 
12 clean :
13     rm static_lib.a static_lib.o fun.o app3

執行make clean能夠將原來的清理掉

執行make會從新編譯源碼

 這樣當咱們修改源代碼以後就能夠簡單的編譯源碼了

Makefile hidden

但上面的Makefile顯然不夠簡潔,咱們能夠利用一些make的隱式規則,簡寫makefile,這些隱含規則能夠經過 make -p 指令查看。

1 app3  : static_lib.a fun.o main3.o
2     gcc main3.o fun.o static_lib.a -o app3
3 
4 static_lib.a : static_lib.o # 隱含會尋找*.c文件編譯成*.o文件
5     ar rcs static_lib.a static_lib.o
6 
7 clean :
8     rm *.a *.o app3

執行make能夠看到依然可以編譯成功

其中cc是一個符號連接

Makefile Var

還能夠進一步使用一些變量,進一步提升Makefile的可維護性

 1 CC       = gcc
 2 OBJS     = main3.o static_lib.a fun.o
 3 GEN_OPTS = -o 
 4 app3  : $(OBJS)
 5     $(CC) $(OBJS) $(GEN_OPTS) app3
 6 
 7 static_lib.a : static_lib.o # 隱含會尋找*.c文件編譯成*.o文件
 8     ar rcs static_lib.a static_lib.o
 9 
10 clean :
11     rm *.a *.o app3

執行make

並且能夠看到 1,2,4行的gcc存在縮進,說明隱含規則也使用指明的CC變量編譯。

Makefile autoVar

進一步的,咱們可使用一些自動化的變量。

 1 CC       = gcc
 2 OBJS     = main3.o static_lib.a fun.o
 3 GEN_OPTS = -o 
 4 app3  : $(OBJS)
 5     $(CC) $(OBJS) $(GEN_OPTS) app3
 6 
 7 static_lib.a : static_lib.o # 隱含會尋找*.c文件編譯成*.o文件
 8     ar rcs $@ $^
 9 
10 clean :
11     rm *.a *.o app3

其中自動化變量 $@表示規則中的目標文件集,$^表示依賴集,這個Makefile執行以後也能獲得想要的結果

Makefile Fun

最後結合前面的變量,再結合函數,等寫一個更完善的makefile,能夠作到增長了新的c文件或h文件不須要修改Makefile文件,再次以前,首先將static_lib.* 移動到lib目錄下,將其他源碼文件移動到src目錄。

並修改main3.c的include爲 ../lib/static_lib.h,修改Makefile文件以下

 1 CC       = gcc
 2 SRC      = ./src
 3 LIB      = ./lib
 4 OBJS     = $(patsubst %.c, %.o, $(wildcard $(SRC)/*.c))
 5 LIBS     = $(patsubst %.c, %.a, $(wildcard $(LIB)/*.c))
 6 GEN_OPTS = -o 
 7 app3  : $(OBJS) $(LIBS)
 8     $(CC) $(OBJS) $(LIBS) $(GEN_OPTS) app3
 9     @echo "gen done"
10 # 將lib目錄下的c文件編譯成a庫文件
11 $(LIBS) : $(patsubst %.c, %.o, $(wildcard $(LIB)/*.c))
12     ar rcs $@ $^
13 
14 clean :
15     -rm $(SRC)/*.o $(LIB)/*.a app3
16     @echo clean done.

其中patsubst是一個函數,替換通配符,wildcard函數擴展通配符,展開目錄下的全部匹配文件。

命令前面加'-'的話表示即使出錯也繼續執行。

相關文章
相關標籤/搜索