Makefile學習筆記

Makefile學習介紹--詳解

Makefile的規則

    target ... : prerequisites ...
            command
            ...
            ...

    target也就是一個目標文件,可以是Object File,也可以是執行文件。還可以是一個標籤(Label),對於標籤這種特性,在後續的“僞目標”章節中會有敘述。

    prerequisites就是,要生成那個target所需要的文件或是目標。

    command也就是make需要執行的命令。(任意的Shell命令)

這是一個文件的依賴關係,也就是說,target這一個或多個的目標文件依賴於prerequisites中的文件,其生成規則定義在command中。說白一點就是說,prerequisites中如果有一個以上的文件比target文件要新的話,或者target不存在的話,那麼,make就會執行後續定義的命令command所定義的命令就會被執行(command一定要以一個Tab鍵作爲開頭這就是Makefile的規則。也就是Makefile中最核心的內容。

說明:clean不是一個文件,它只不過是一個動作名字,有點像C語言中的lable一樣,其冒號後什麼也沒有,那麼,make就不會自動去找文件的依賴性,也就不會自動執行其後所定義的命令。要執行其後的命令,就要在make命令後明顯得指出這個lable的名字。這樣的方法非常有用,我們可以在一個makefile中定義不用的編譯或是和編譯無關的命令,比如程序的打包,程序的備份,等等。

----------------------------------------------------------------------------------------------------

1. 寫一個Makefile來告訴make命令如何編譯和鏈接這幾個文件。我們的規則是:

    1)如果這個工程沒有編譯過,那麼我們的所有C文件都要編譯並被鏈接。
    2)如果這個工程的某幾個C文件被修改,那麼我們只編譯被修改的C文件,並鏈接目標程序。

    3)如果這個工程的頭文件被改變了,那麼我們需要編譯引用了這幾個頭文件的C文件,並鏈接目標程序。

目標文件在編譯的過程中,如果出現錯誤,比如最後被依賴的文件找不到,那麼make就會直接退出,並報錯,而對於所定義的命令的錯誤,或是編譯不成功,make根本不理。make只管文件的依賴性,即,如果在我找了依賴關係之後,冒號後面的文件還是不在,那麼對不起,我就不工作啦。

2. object 變量,使用變量的形式,表示目標文件:objects = main.o kbd.o command.o display.o,然後很方便地在我們的makefile中以“$(objects)”的方式來使用這個變量;

3. “隱晦規則”和“僞目標文件”

    1> “隱晦規則”:GNU的make 非常強大,可以通過目標 .o 文件推導出相應的 .c 及編譯命令等;

    2> “僞目標文件”:  

        .PHONY : clean

        clean :

                -rm edit $(objects)

    .PHONY意思表示clean是一個“僞目標”。而在rm命令前面加了一個小減號的意思就是,也許某些文件出現問題,但不要管,繼續做後面的事加上 .PHONY 的目的是爲了避免和文件重名的這種情況;

.PHONY的實際使用範例:

    1> 如果你的Makefile需要一口氣生成若干個可執行文件,但你只想簡單地敲一個make完事,並且,所有的目標文件都寫在一個Makefile中,那麼你可以使用“僞目標”這個特性:

    all : prog1 prog2 prog3
    .PHONY : all

    prog1 : prog1.o utils.o
            cc -o prog1 prog1.o utils.o

    prog2 : prog2.o
            cc -o prog2 prog2.o

    prog3 : prog3.o sort.o utils.o

            cc -o prog3 prog3.o sort.o utils.o

    2> 目標也可以成爲依賴。所以,僞目標同樣也可成爲依賴。看下面的例子:

    .PHONY: cleanall cleanobj cleandiff

    cleanall : cleanobj cleandiff
            rm program

    cleanobj :
            rm *.o

    cleandiff :
            rm *.diff

“make clean”將清除所有要被清除的文件。“cleanobj”和“cleandiff”這兩個僞目標有點像“子程序”的意思。我們可以輸入“make cleanall”和“make cleanobj”和“make cleandiff”命令來達到清除不同種類文件的目的。

4. 引用其它的Makefile

在Makefile使用include關鍵字可以把別的Makefile包含進來,這很像C語言的#include,被包含的文件會原模原樣的放在當前文件的包含位置。

    include foo.make *.mk 
    等價於:

    include foo.make a.mk b.mk 

查找Makefile路徑一般是在當前的目錄下,或者make執行的時候,“-I”或“--include-dir”參數;

5. 文件搜尋

在一些大的工程中,有大量的源文件,我們通常的做法是把這許多的源文件分類,並存放在不同的目錄中。所以,當make需要去找尋文件的依賴關係時,你可以在文件前加上路徑,但最好的方法是把一個路徑告訴make,讓make在自動去找;

    1、 首先搜索的目錄是當前目錄;

    2、 VPATH = src:../headers    冒號分離不同的文件目錄,此例子先後在 src 和 ../headers 目錄下進行查詢;

    3、 make的“vpath”關鍵字(注意,它是全小寫的);

        1> vpath <pattern>; <directories>;
        爲符合模式<pattern>;的文件指定搜索目錄<directories>。 
            例子:vpath %.h ../headers    表示在目錄 ../headers 下查找 .h 頭文件;

        2> vpath <pattern>;
        清除符合模式<pattern>;的文件的搜索目錄。

        3> vpath
        清除所有已被設置好了的文件搜索目錄。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章