第二載:makefile的結構

    在上一篇中,我們只是簡單的介紹了make跟makefile的基本概念,並且實現了一個簡單的makefile,但是那個makefile僅僅是做一些打印工作,並沒有什麼實際性用途。在編寫真正可用的makefile前,我們先來了解下makefile的結構。
    前邊也提到,makefile的意義在於:
    1、makefile用於定義源文件間的依賴關係
    2、makefile說明如何編譯各個源文件並生成可執行文件
    makefile的基本結構如下:
                                      目標 依賴
                                      [ Tab ]   命令   
       - 目標:通常爲我們期望編譯得到的可執行程序或者庫
       - 依賴:指編譯這個可執行程序或庫所以要的源文件或其他目標,簡稱目標依賴於這些文件或庫
       - 命令:指通過這些依賴,如何編譯得到這個目標的命令,如gcc  -o xxx -c xxx.c 等

      注意:1、目標與依賴都可以是多個,目標與目標、依賴於依賴之間用空格分開即可
                 2、命令的前邊必須要跟一個Tab空格

    有了以上的基本知識,下邊來看一個makefile的依賴示例

all : test
    @echo "make all"
test:
    @echo "make test"

    從這個makefile的內容得知,all目標依賴於test,所以要all目標執行成功,首先test目標要執行成功,簡單來說就是先依賴後目標
所以當我們執行make all的時候,會先打印 "make test" 再打印 "make all",如下。

/home/delphi/myshare/makefile>make all
make test
make all
/home/delphi/myshare/makefile>

    上邊在每條命令前加了一個@符號,作用是不打印執行的命令,只打印結果,相當於一個小技巧

依賴規則:
   
1、當目標對應的文件不存在時,執行對應命令
    2、當
依賴在時間上比目標更新時(說明源文件有改動),執行對應命令
    3、當
依賴關係連續發生時,對比依賴鏈上的每一個目標

第一個make編譯案例

hello.out all : main.o func.o
    gcc -o hello.out main.o func.o

main.o : main.c
    gcc -o main.o -c main.c

func.o : func.c
    gcc -o func.o -c func.c

源文件main.c與func.c如下

//main.c源文件
#include <stdio.h>

extern void fun();

int main()
{
    fun();

    return 0;
}

//func.c源文件
#include <stdio.h>

void fun()
{
    printf("hello makefile\n");
}

從makefile文件中我們知道,想得到的可執行程序爲hello.out,分別依賴於main.o與func.o,而兩個.o文件又分別作爲兩個子目標依賴於各自的.c源文件,關係即爲:
    hello.out  ->  main.o  func.o
    main.o -> main,c
    func.o -> func.c

執行make

再執行一次

在第二次make的時候,因爲兩個.o依賴、hello.out都是最新的,所以就不需要再編譯了,但是當我們執行 make all時,因爲all目標在文件目錄中不存在,兩個.o已經存在並且沒做改動,所以make all時只會進行強制鏈接

這就是爲什麼把hello.out 與 all都作爲目標的原因,當需要強制鏈接時就執行make all;需要依據依賴是否更改決定是否鏈接時直接make即可

以上內容參考《狄泰軟件學院》操作系統篇之 - makefile專題

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