閱讀787 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Makefile的規則

target ... : prerequisites ...
command

prerequisites中如果有一個以上的文件比target文件要新的話,command所定義的命令就會被執行。
這就是Makefile的規則。也就是Makefile中最核心的內容。

一個示例 test.c
#include<stdio.h>
int main()
{
    printf("hello world!\n");
}

//makefile

exename = test

$(exename) : test.o
 cc -o test test.o

test.o : test.c
 cc -c test.c
clean:
 rm test.o
install:
 cp test /usr/bin
uninstall:
 rm /usr/bin/test
doo:
 ./$(exename)
//添加變量後的makefile
exename = test
objfile = test.o
source = test.c
$(exename) : $(objfile)
 cc -o $(exename) $(objfile)

$(objfile) :$(source)
 cc -c $(source)
clean:
 rm $(objfile) $(exename)
install:
 cp test /usr/bin
uninstall:
 rm /usr/bin/test
doo:
 ./$(exename)

makefile的變量也就是一個字符串,理解成C語言中的宏可能會更好。


//讓make自動推導,隻要make看到一個[.o]文件,它就會自動的把[.c]文件加在依賴關係中,如果make找到一個whatever.o,那麼whatever.c,就會是whatever.o 的依賴文件。並且 cc -cwhatever.c 也會被推導出來,於是,我們的makefile再也不用寫得這麼複雜


exename = test
objfile = test.o
source = test.c
$(exename) : $(objfile)
 cc -o $(exename) $(objfile)

$(objfile) :$(source)

.PHONY: clean
clean:
 rm -rf $(objfile) $(exename)
.PHONY :doo
doo:
 ./$(exename)這種方法,也就是make的“隱晦規則”。上麵文件內容中,“.PHONY”表示,clean是
個偽目標文件。
每個Makefile中都應該寫一個清空目標文件(.o和執行文件)的規則,這不僅便於重
編譯,也很利於保持文件的清潔。這是一個“修養. 前麵說過,.PHONY意思表示clean是一個“偽目標”,。而在rm命令前麵加了一個小-rf的意思就是,也許某些文件出現問題,但不要管,繼續做後麵的事。當然,clean
的規則不要放在文件的開頭,不然,這就會變成make的默認目標,相信誰也不願意這
樣。不成文的規矩是——“clean從來都是放在文件的最後”。


在這個makefile中,目標文件(target)包含:執行文件edit和中間目標文件(*.o),
依賴文件(prerequisites)就是冒號後麵的那些 .c 文件和 .h文件。每一個 .o 文件都有一
組依賴文件,而這些 .o 文件又是執行文件 test的依賴文件。依賴關係的實質上就是說
明了目標文件是由哪些文件生成的,換言之,目標文件是哪些文件更新的。
在定義好依賴關係後,後續的那一行定義了如何生成目標文件的操作係統命令,一定
要以一個Tab鍵作為開頭。記住,make並不管命令是怎麼工作的,他隻管執行所定義
的命令。make會比較targets文件和prerequisites文件的修改日期,如果prerequisites文
件的日期要比targets文件的日期要新,或者target不存在的話,那麼,make就會執行
後續定義的命令。
這裏要說明一點的是,clean不是一個文件,它隻不過是一個動作名字,有點像C語言
中的lable一樣,其冒號後什麼也沒有,那麼,make就不會自動去找文件的依賴性,
也就不會自動執行其後所定義的命令。要執行其後的命令,就要在make命令後明顯得
指出這個lable的名字。這樣的方法非常有用,我們可以在一個makefile中定義不用的
編譯或是和編譯無關的命令,比如程序的打包,程序的備份,等等。

、如果make執行時,有“-I”或“--include-dir”參數,那麼make就會在這個參數所指
定的目錄下去尋找。
-include <filename>
其表示,無論include過程中出現什麼錯誤,都不要報錯繼續執行。和其它版本make兼
容的相關命令是sinclude,其作用和這一個是一樣的。

五、make的工作方式
GNU的make工作時的執行步驟入下:(想來其它的make也是類似)
1、讀入所有的Makefile。
2、讀入被include的其它Makefile。
3、初始化文件中的變量。
4、推導隱晦規則,並分析所有規則。
5、為所有的目標文件創建依賴關係鏈。
6、根據依賴關係,決定哪些目標要重新生成。
7、執行生成命令。

最後更新:2017-04-03 15:21:43

  上一篇:go C和CPP的區別 &amp; C++,Java and Python的區別
  下一篇:go dm642的中斷