16.Linuxshell程式設計(Makefile)

黑夜路口發表於2018-03-06

(建立於 2018/2/7 上午7:43:55)

MakeFile 構建工作,只需通過make一句命令就可以構建一個可執行程式,Maven ANT Gradle都是構建工具

在很多C/C++開源專案中,configure檔案用來檢查系統配置生成配置檔案,這些配置Makefile檔案用來生成我們需要的動態庫檔案

為什麼要寫Makefile檔案?
1.專案非常龐大時,讓構建過程自動化簡單
2.當依賴檔案比目標檔案有更新,會重建目標檔案
(gcc命令前必須是tab鍵,解析的時候根據tab鍵來判斷這是個命令,所有tab鍵後邊的內容都會被當作命令對待,所以如果寫註釋,要注意)

Makefile檔案相當於一系列的gcc 命令的組合
gcc -c xxx.c  生成.o檔案(相當於javac xxx生成class檔案)
gcc -o xxx.o  連結生成可執行檔案

如下圖,這個檔案就是Makefile檔案,檔名就是Makefile,固定的
#include<stdio.h>
int  divide(int a,int b) {
    printf("a/b=%d
",a/b);
}

#include<stdio.h>
int  multi(int a, int b) {
    printf("axb=%d
", a * b);
}

#include<stdio.h>
int  jian(int a, int b) {
    printf("a-b=%d
", a - b);
}

#include<stdio.h>
int  plus(int a, int b) {
    printf("a+b=%d
", a +b);
}

int  plus(int a, int b);
int  jian(int a, int b);
int  multi(int a, int b);
int  divide(int a, int b);
void main() {
    plus(20,10);
    jian(20, 10);
    multi(20, 19);
    divide(20, 10);
}
myapp:main.o plus.o minus.o multi.o divi.o
    gcc main.o plus.o minus.o multi.o divi.o -o myapp

#目標:main.o
#依賴:main.c
#命令:gcc -c main.c
main.o:main.c
    gcc -c main.c
plus.o:plus.c
    gcc -c plus.c
minus.o:minus.c
    gcc -c minus.c
multi.o:multi.c
    gcc -c multi.c
divi.o:divi.c
    gcc -c divi.c
    
clean:
    rm -f *.o
    rm -f myapp

執行make命令得到如下,生成了很多.o臨時檔案,如何在生成之後刪除這些檔案?
file:///C:/Users/renzhenming/Documents/My%20Knowledge/temp/4d3d1996-855f-40c3-9375-1f9fc118cb27/128/index_files/951526656.png
刪除臨時檔案

myapp:main.o plus.o minus.o multi.o divi.o
    gcc main.o plus.o minus.o multi.o divi.o -o myapp

#目標:main.o
#依賴:main.c
#命令:gcc -c main.c
main.o:main.c
    gcc -c main.c
plus.o:plus.c
    gcc -c plus.c
minus.o:minus.c
    gcc -c minus.c
multi.o:multi.c
    gcc -c multi.c
divi.o:divi.c
    gcc -c divi.c

//設定一個命令clean,刪除相關的東西(可見clean這個命令是自己寫在Makefile檔案中的,並非關鍵字,可以隨意寫,只要我們呼叫的時候寫對就可以了,比如這裡寫clean,執行makefile檔案的時候寫make clean,如果寫remove ,那命令自然就是make remove了)
clean:
    rm -f *.o
    rm -f myapp

執行make命令(只輸入一個make),就可以執行最終的目標也就是寫在最上邊的生成myapp的命令,如果你不要執行最終目標,而是像執行其中的一個目標,比如,我要執行生成main.o檔案,那麼就可以執行這個命令,make main.c 你要執行哪個就寫哪個檔案的名字,前邊加make既可

可以看到如main.o:main.c 意思時main.o依賴於main.c生成,回車後執行gcc -c main.c生成main.o檔案
最終生成的可執行檔案myapp依賴於main.o plus.o munus.o multi.o divi.o
:後邊的都是依賴檔案,一個可執行檔案可能依賴於很多檔案,然而並不是每次生成可執行檔案的時候所有依賴檔案都會被修改,
所以再次生成的時候只需要重新構建被修改的依賴檔案即可,Makefile具備檢查檔案是否更新的功能,再次編譯生成時,它會去重構已修改的檔案

當所有檔案都沒有被修改時,執行make結果如下截圖

file:///C:/Users/renzhenming/Documents/My%20Knowledge/temp/4d3d1996-855f-40c3-9375-1f9fc118cb27/128/index_files/780668562.png

當我們修改了其中一個c檔案後執行結果:(main.c被更新,導致main.o被重構,main.o重構後,myapp也需要被重構)

file:///C:/Users/renzhenming/Documents/My%20Knowledge/temp/4d3d1996-855f-40c3-9375-1f9fc118cb27/128/index_files/780778109.png

myapp:main.o plus.o minus.o multi.o divi.o                                               
  2         gcc main.o plus.o minus.o multi.o divi.o -o myapp
  3 
  4 #目滷輳?ain.o
  5 #?5攏潞main.c
  6 #??攏潞gcc -c main.c
  7 main.o:main.c
  8         gcc -c main.c
  9 plus.o:plus.c
 10         gcc -c plus.c
 11 minus.o:minus.c
 12         gcc -c minus.c
 13 multi.o:multi.c
 14         gcc -c multi.c
 15 divi.o:divi.c
 16         gcc -c divi.c
 17 
 18 .PHONY:clean       //為了防止存在和命令有相同命名的檔案產生衝突,這裡設定偽命令
 19 clean:
 20         rm -f *.o
 21         rm -f myapp

新增命令之前執行結果
file:///C:/Users/renzhenming/Documents/My%20Knowledge/temp/4d3d1996-855f-40c3-9375-1f9fc118cb27/128/index_files/781545156.png

新增偽命令之後執行結果
file:///C:/Users/renzhenming/Documents/My%20Knowledge/temp/4d3d1996-855f-40c3-9375-1f9fc118cb27/128/index_files/781575437.png

上邊那種是初級寫法,接下來我們升級一下,這樣就有點類似Android mk檔案了

OBJECTS=main.o plus.o minus.o divi.o multi.o                                             

myapp:$(OBJECTS)
      gcc $^ -o $@     //#自動化變數 $^表示所有依賴,$@表示目標
%.o:%.c                //#萬用字元 #gcc -c main.c -o main.o
      gcc -c $^ -o $@

.PHONY:clean
clean:
      rm -f *.o
      rm -f myapp

接下來第三階段寫法

  1 SOURCES=$(wildcard *.c)               //#所有.c原始檔                                                         
  2 OBJECTS=$(patsubst %.c,%.o,$(SOURCES))   //#把SOURCES中的所有.c字尾,替換成.o字尾
  3 
  4 myapp:$(OBJECTS)
  6         gcc $^ -o $@
  8 %.o:%.c
 10         gcc -c $^ -o $@
 16 .PHONY:clean
 17 clean:
 18         rm -f *.o
 19         rm -f myapp


相關文章