我有一個簡單的makefile,它在Linux上使用gcc
將p.c
文件編譯爲可執行文件。 p.c
文件取決於a.h
文件。 我的makefile文件看起來是這樣的:即使我編譯源代碼,爲什麼我的makefile會重新編譯?
//makefile
CC = gcc
build: p.c a.h
$(CC) -o out p.c
clean:
rm -f *.exe
rebuild: clean build
我有一個簡單的makefile,它在Linux上使用gcc
將p.c
文件編譯爲可執行文件。 p.c
文件取決於a.h
文件。 我的makefile文件看起來是這樣的:即使我編譯源代碼,爲什麼我的makefile會重新編譯?
//makefile
CC = gcc
build: p.c a.h
$(CC) -o out p.c
clean:
rm -f *.exe
rebuild: clean build
Makefile中不產生它有望產生,即build
,clean
和rebuild
文件。由於這些目標不是文件,它們應該被標記爲phony targets:
.PHONY: build clean rebuild
build
的目標應該是:
build : out
out : p.c a.h
$(CC) -o [email protected] p.c
什麼是$ @? – batman
除非您有名爲build,clean或rebuild的文件,否則不需要.PHONY。 –
@learner:[$ @](http://www.gnu.org/software/make/manual/make.html#index-g_t_0040_0040-_0040r_007b_0028automatic-variable_0029_007d-939) –
Makefile中具有的一般語法:
target : dependencies
commands to make target from dependencies
所以你的Makefile希望使用build : p.c a.h
目標創建一個名爲build
的文件。 由於命令實際上並不會在每次調用時都創建該文件,因此必須重新執行命令。
(PS:Linux程序沒有一個擴展名爲.exe)
這部分
build: p.c a.h
$(CC) -o out p.c
說:「我用$(CC)-O了PC和結果將彙編成爲一個名爲「build」的文件。由於你騙了make
(這會創建out
文件),它會嘗試再次構建「構建」。
還有這裏的Makefile作家上了一課:始終使用[email protected]
變量(表示對象)來避免這個錯誤:
out: p.c a.h
$(CC) -o [email protected] p.c
有關更多建議,請參閱Paul's Rules for Makefiles。
學習者,這裏是一個使用變量來存儲可執行文件名稱的例子。這樣,你只需要在你的Makefile開始在一個地方指定:
EXECUTABLE = out
.PHONY: build clean rebuild
build: $(EXECUTABLE)
$(EXECUTABLE): p.c a.h
$(CC) -o [email protected] p.c
clean:
rm -f $(EXECUTABLE)
rebuild: clean build
通常情況下,你也必須在變量列出您.c
和.h
文件太多,這樣就可以添加/從您的構建中刪除文件很容易,無需搜索您的Makefile中所有使用它們的位置。
如果你想避免總是重新編譯源,那麼你的目標應該取決於對象文件,沒有源文件:
target.exe : p.o $(CC) -o [email protected] $?; p.o: p.c a.h $(CC) -c [email protected] $?;
典型的makefile通常不必每一個明確的規則目標文件,也不會列出實現和頭文件之間的顯式依賴關係;大家平時看到的一樣
%.o : %.c $(CC) -c $(CFLAGS) $?;
(其中$?
表示先決條件的列表爲目標),或者,如果你的項目是死的簡單(一個源文件),你甚至不需要是一個隱含的規則;你通常可以用
都跑不掉:目標 目標:target.o
假設你有一個名爲target.c
文件,上面會使用默認的編譯器和CFLAGS選項建立target
。
同樣,一個典型的makefile(至少在我的經驗)沒有明確列出頭依賴;相反,它依靠編譯器選項自動生成這些依賴項列表(對於gcc,該選項爲-M
)。一個例子見here。
'make'的調用是什麼? –
一個小問題:當你試圖刪除一個'.exe'文件時,'make clean'不起作用,並且你的可執行文件沒有這樣的擴展名。 –
'p.c文件依賴於a.h文件'...這是不正確的。 ** out **依賴於a.h以及p.c,但你的makefile並不這麼說。 –