1. 程式人生 > >初識 makefile 的結構(二)

初識 makefile 的結構(二)

makefile 文件結構 makefile 組成

我們在上節中說到 makefile 的本質就是一個腳本程序,用來解釋執行的。那麽它的意義是用於定義源文件間的依賴關系,說明如何編譯各個源文件並生成可執行文件。我們來看看依賴的定義,如下

技術分享圖片

下來我們來分析下 makefile 中元素的意義:a> targets:通常是需要生成的目標文件名,make 所需執行的命令名稱;b> perequisities:當前目標所依賴的其他目標或文件;c> command:完成目標所需要執行的命令。我們來說說規則中的註意事項:a> targets 可以包含多個目標,使用空格對多個目標名進行分隔;b> perequisities

可以包含多個依賴,使用空格對多個依賴進行分隔;c> [ Tab ] 鍵 '\t',每一個命令行必須以 [ Tab ] 字符開始,[ Tab ] 字符告訴 make 此行是一個命令行;d> 續行符 \,可以將內容分開寫到下一行,提高代碼可讀性。

下來我們看看一個 makefile 的依賴示例,如下

技術分享圖片

依賴規則是:a> 當目標對應的文件不存在,執行對應命令;b> 當依賴在時間上比目標更新,執行對應命令;c> 當依賴關系連續發生時,對比依賴鏈上的每一個目標。在這講個小技巧:makefile 中可以在命令前加上 @ 符,作用為命令無回顯。

我們還是以代碼為例來進行分析說明

all : test
    @echo "make all"

test : 
    @echo "make test"

我們定義的目標 all 的依賴是 test,而 test 目標則沒有依賴,只是執行打印語句。當 test 目標正確執行後,all 目標的執行語句便會進行正常輸出。也就是說,先打印 make test,在輸出 make all。我們來看看編譯結果

技術分享圖片

那為什麽只打印出這兩句,沒有打印出上一節我們看到的 echo "make all" 呢?原因就是我們在它們前面加的 @ 無回顯符號,下來我們去掉 @ 符號看看編譯效果

技術分享圖片

以後如果我們不想看到 echo 那條命令本身的話,可以加上 @ 無回顯符號。下來我們來看個 make 的編譯案例,結構如下

技術分享圖片

我們來根據上面的結構編寫相應的 makefile 程序,看看執行效果


func.c 源碼

#include <stdio.h>

int foo()
{
    printf("void foo()\n");
}


main.c 源碼

extern void foo();

int main()
{
    foo();

    return 0;
}


makefile 源碼

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

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

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

我們來看看編譯結果

技術分享圖片

我們看到已經實現了。我們再來在 func.c 中打印的語句前加上 hello,再來看看編譯結果

技術分享圖片

我們看到再次進行編譯時,它只編譯了 func.c 文件,沒有編譯 main.c 文件,這也極大的提升了嵌入式編譯的效率。那麽在這塊有個小技巧,在工程開發中可以將最終可執行文件名和 all 同時作為 makefile 中第一條規則的目標,如下

技術分享圖片

我們再次來編譯,看看編譯結果

技術分享圖片

我們看到它說 hello.out 是最新的,執行的結果和我們之前是一樣的。因此這個小技巧可以極大的提高我們因重復編譯帶來的效率低下的問題。我們也可以直接 make all 進行再次編譯,如下

技術分享圖片

這次因為源文件都沒有改動,所以只執行了 hello.out 目標後面的語句。提高對 makefile 結構的學習,總結如下:1、makefile 用於定義源文件間的依賴關系;2、makefile 說明如何編譯各個源文件並生成可執行文件;3、makefile 中的目標之間存在連續依賴關系;4、依賴存在並且命令執行成功是目標完成的充要條件。


歡迎大家一起來學習 makefile 語言,可以加我QQ:243343083

初識 makefile 的結構(二)