Makefile基本規則和原理

閱讀《跟我一塊兒寫makefile》,摘錄文章我的認爲有助於理解的語句,並記錄本身驗證明踐的過程,方便本身後續工做中複習。bash

1、基本規則

target ... : prerequisites ... command測試

  • target 是一個目標文件(makefile支持多目標),能夠是 Object File,也能夠是執行文件,還能夠是一個標籤(Label)。
  • prerequisites 生成 target 所須要的文件或是目標。
  • command 爲 make 須要執行的命令。(任意的 Shell 命令)

這是一個文件的依賴關係,也就是說,target 這一個或多個的目標文件依賴於prerequisites 中的文件,其生成規則定義在 command 中。說白一點就是說,prerequisites中若是有一個以上的文件比 target 文件要新的話,command 所定義的命令就會被執行。這就是 Makefile 的規則。也就是 Makefile 中最核心的內容。ui

2、最基本的實例

顯式規則,依賴關係寫的比較清楚。spa

run: main.o hello.o test.o
    gcc -o run main.o hello.o test.o
main.o: main.c
    gcc -c main.c
hello.o: hello.c
    gcc -c hello.c
test.o: test.c
    gcc -c test.c
clean:
    rm run *.o
複製代碼

運行結果:code

root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make run
gcc -c main.c
gcc -c hello.c
gcc -c test.c
gcc -o run main.o hello.o test.o
複製代碼

run所須要的依賴文件不存在時,執行下一語句。待依賴文件生成時,繼續執行run對應的命令。get

若是依賴的test.o文件沒有生成的規則,makefile會自動產生規則去生成test.o文件。這個特性就是隱晦規則,主要靠make自動推導。只要 make 看到一個[.o]文件,它就會自動的把[.c]文件加在依賴關係中,如自動把test.c加入到依賴關係中,而且cc -c -o test.o test.c也會被推導出來。源碼

刪除該語句測試
test.o: test.c
    gcc -c test.c
複製代碼

運行結果:string

gcc -c main.c
gcc -c hello.c
cc    -c -o test.o test.c
gcc -o run main.o hello.o test.o
複製代碼

若是沒有test.c文件則沒法生成,直接終止執行。it

root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make run
gcc -c main.c
gcc -c hello.c
make: *** No rule to make target `test.o', needed by `run'.  Stop.
複製代碼

make 並無論命令是怎麼工做的,他只管執行所定義的命令。 make 會比較 targets 文件和 prerequisites 文件的修改日期,若是 prerequisites 文件的日期要比 targets 文件的日期要新,或者 target 不存在的話,那麼,make 就會執行後續定義的命令。我發覺書上這句話有點問題。 測試把hello.c文件刪除後,即沒法生成hello.o這個target,執行make run,結果以下編譯

root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make run
gcc -c main.c
make: *** No rule to make target `hello.c', needed by `hello.o'.  Stop.
複製代碼

後續定義的語句並不會去執行,直接終止。

test.o: test.c
    gcc -c test.c
複製代碼

原來是我理解錯誤了,書中後面提到: 在找尋的過程當中,若是出現錯誤,好比最後被依賴的文件找不到,那麼make 就會直接退出,並報錯,而對於所定義的命令的錯誤,或是編譯不成功,make 根本不理。make 只管文件的依賴性,即,若是在我找了依賴關係以後,冒號後面的文件仍是不在,那麼對不起,我就不工做啦。 這個target不存在,是指上一次編譯生成的run,已經不存在須要執行對應的command來產生。而且大前提是整個makefile的依賴關係正確和編譯命令所需的文件是存在的狀況下。

3、基本原理

  1. make 會在當前目錄下找名字叫「Makefile」或「makefile」的文件。
  2. 若是找到,它會找文件中的第一個目標文件(target),實例中第一個目標target爲run
  3. 若是 run 文件不存在,或是run 所依賴的後面的 .o 文件的文件修改時間要比 run這個文件新,那麼,他就會執行後面所定義的命令來生成 run這個文件。(根據這個特性,我每次修改相應的文件時候,有依賴關係的文件都會從新編譯和連接。其實徹底能夠不用make clean,畢竟大型源碼從新編譯一次是很耗費時間的。)
  4. 若是run所依賴的.o 文件也存在,那麼 make 會在當前文件中找目標爲.o 文件的依賴關係,也按照第3點的判斷依據來更新生成.o文件。
  5. 若是run依賴關係中好比test.o的生成規則沒在makefile文件中體現,make會自動產生規則並生成test.o文件,前提是test.c存在當前目錄下,不然直接終止執行。
  6. 最終根據對應的依賴關係生成run這個可執行文件。
相關文章
相關標籤/搜索