make

Linux 下 make 命令是系統管理員和程序員用的最頻繁的命令之一。管理員用它通過命令行來編譯和安裝很多開源的工具,程序員用它來管理他們大型複雜的項目編譯問題。本文我們將用一些實例來討論 make 命令背後的工作機制。

Make 如何工作的:
對於不知道背後機理的人來說,make 命令像命令行參數一樣接收目標。這些目標通常存放在以 “Makefile” 來命名的特殊文件中,同時文件也包含與目標相對應的操作。更多信息,閱讀關於 Makefiles 如何工作的系列文章。

當 make 命令第一次執行時,它掃描 Makefile 找到目標以及其依賴。如果這些依賴自身也是目標,繼續爲這些依賴掃描 Makefile 建立其依賴關係,然後編譯它們。一旦主依賴編譯之後,然後就編譯主目標(這是通過 make 命令傳入的)。

現在,假設你對某個源文件進行了修改,你再次執行 make 命令,它將只編譯與該源文件相關的目標文件,因此,編譯完最終的可執行文件節省了大量的時間。

Make 命令實例:
下面是工程的內容:

$ ls
anotherTest.c Makefile test.c test.h
下面是 Makefile 的內容:

all: test

test: test.o anotherTest.o
gcc -Wall test.o anotherTest.o -o test

test.o: test.c
gcc -c -Wall test.c

anotherTest.o: anotherTest.c
gcc -c -Wall anotherTest.c

clean:
rm -rf *.o test
現在我們來看 Linux 下一些 make 命令應用的實例:

  1. 一個簡單的例子

爲了編譯整個工程,你可以簡單的使用 make 或者在 make 命令後帶上目標 all。

$ make
gcc -c -Wall test.c
gcc -c -Wall anotherTest.c
gcc -Wall test.o anotherTest.o -o test
你能看到 make 命令第一次創建的依賴以及實際的目標。

如果你再次查看目錄內容,裏面多了一些 .o 文件和執行文件:

$ ls
anotherTest.c anotherTest.o Makefile test test.c test.h test.o
現在,假設你對 test.c 文件做了一些修改,重新使用 make 編譯工程:

$ make
gcc -c -Wall test.c
gcc -Wall test.o anotherTest.o -o test
你可以看到只有 test.o 重新編譯了,然而另一個 Test.o 沒有重新編譯。

現在清理所有的目標文件和可執行文件 test,你可以使用目標 clean:

$ make clean
rm -rf *.o test

$ ls
anotherTest.c Makefile test.c test.h
你可以看到所有的 .o 文件和執行文件 test 都被刪除了。

  1. 通過 -B 選項讓所有目標總是重新建立

到目前爲止,你可能注意到 make 命令不會編譯那些自從上次編譯之後就沒有更改的文件,但是,如果你想覆蓋 make 這種默認的行爲,你可以使用 -B 選項。

下面是個例子:

$ make
make: Nothing to be done for `all’.

$ make -B
gcc -c -Wall test.c
gcc -c -Wall anotherTest.c
gcc -Wall test.o anotherTest.o -o test
你可以看到儘管 make 命令不會編譯任何文件,然而 make -B 會強制編譯所有的目標文件以及最終的執行文件。

  1. 使用 -d 選項打印調試信息

如果你想知道 make 執行時實際做了什麼,使用 -d 選項。

這是一個例子:

$ make -d | more
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for x86_64-pc-linux-gnu
Reading makefiles…
Reading makefile Makefile’…
Updating makefiles….
Considering target file
Makefile’.
Looking for an implicit rule for Makefile’.
Trying pattern rule with stem
Makefile’.
Trying implicit prerequisite Makefile.o’.
Trying pattern rule with stem
Makefile’.
Trying implicit prerequisite Makefile.c’.
Trying pattern rule with stem
Makefile’.
Trying implicit prerequisite Makefile.cc’.
Trying pattern rule with stem
Makefile’.
Trying implicit prerequisite Makefile.C’.
Trying pattern rule with stem
Makefile’.
Trying implicit prerequisite Makefile.cpp’.
Trying pattern rule with stem
Makefile’.
–More–

這是很長的輸出,你也看到我使用了 more 命令來一頁一頁顯示輸出。

  1. 使用 -C 選項改變目錄

你可以爲 make 命令提供不同的目錄路徑,在尋找 Makefile 之前會切換目錄的。

這是一個目錄,假設你就在當前目錄下:

$ ls
file file2 frnd frnd1.cpp log1.txt log3.txt log5.txt
file1 file name with spaces frnd1 frnd.cpp log2.txt log4.txt
但是你想運行的 make 命令的 Makefile 文件保存在 ../make-dir/ 目錄下,你可以這樣做:

$ make -C ../make-dir/
make: Entering directory /home/himanshu/practice/make-dir’
make: Nothing to be done for
all’.
make: Leaving directory `/home/himanshu/practice/make-dir
你能看到 make 命令首先切到特定的目錄下,在那執行,然後再切換回來。

  1. 通過 -f 選項將其它文件看作 Makefile

如果你想將重命名 Makefile 文件,比如取名爲 my_makefile 或者其它的名字,我們想讓 make 將它也當成 Makefile,可以使用 -f 選項。

make -f my_makefile
通過這種方法,make 命令會選擇掃描 my_makefile 來代替 Makefile。

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