Make 檔

Make 檔是一個由 make 指令參照的文字檔,它說明目標檔的建置, 並包含像來源層次相依關係及建置次序相依關係等資訊。

CDT 可為您產生 Make 檔,這類專案叫作受管理的 Make 專案。有些專案,即所謂的標準 Make 專案, 可讓您定義自己的 Make 檔。

範例 Make 檔

# 範例 Make 檔
# 這個 Make 檔示範及解說
# Make 巨集、巨集展開項、
# 規則、目標檔、相依關係、指令、目標
# 人工目標檔、型樣規則、相依關係規則。

# 註解開頭為 #,直到行尾。

# 以下是簡單的 Make 巨集。
LINK_TARGET = test_me.exe

# 以下是使用反斜線延伸至多指令行的 Make 巨集。
# 這樣可以快速修改更多物件檔。
OBJS =  \
 Test1.o \
 Test2.o \
 Main.o

# 以下是由兩個巨集展開項定義的 Make 巨集。
# 巨集展開項可視為 Make 巨集的文字置換。
# 巨集展開項是以 $ 引入並以括弧 () 含括。
REBUILDABLES = $(OBJS) $(LINK_TARGET)

# Make 巨集不需要在其巨集展開項之前定義,
# 但通常應該在它們出現於任何規則之前定義。
# 因此,Make 巨集通常先出現在 Make 檔中。

# 以下是簡單的規則(用於「清除」建置環境)。
# 它有一個叫作 "clean" 的目標檔(在第一行的冒號 ":" 左邊),
# 無相依關係(在冒號右邊),
# 及兩個指令(依接下來的指令行上的欄標縮排)
# 冒號之前的空格不是必要的,在這裡加入空格只是為了方便閱讀。
clean :
 rm -f $(REBUILDABLES)
 echo Clean done

# Make 檔應該具有兩個標準目標檔:
# "all" 和 "clean",因為它們通常是指令行目標。
# 同時,這些也通常是人工目標檔,因為它們通常不
# 對應於名叫 "all" 或 "clean" 的真實檔案。

# "all" 的規則使用於增量建置系統。
# 其做法是表達對該系統的結果的相依關係,
# 再變成有它們自己的規則和相依關係。
all : $(LINK_TARGET)
 echo All done

# 這些規則清單出現在 Make 檔的次序並沒有規定。
# Make 將建置它自己的相依關係樹,並只有在順利執行它的相依關係規則之後
# 才執行每一個規則一次。

# 以下是在其指令中使用部分內建 Make 巨集的規則:
# $@ 展開為規則的目標檔,本例為 "test_me.exe"。
# $^ 展開為規則的相依關係,本例為三個檔案
# main.o、test1.o 和 test2.o。
$(LINK_TARGET) : $(OBJS)
 g++ -g -o $@ $^

# 以下是型樣規則,通常用於編譯行。
# 它指示如何建立具有 .o 字尾的檔案,假設有一個檔案的字尾是 .cpp。
# 規則的指令使用部分內建 Make 巨集:
# $@ 用於符合型樣的目標檔
# $lt; 用於符合型樣的相依關係
%.o : %.cpp
 g++ -g -o $@ -c $<

# 這些是相依關係規則,是不含任何指令的規則。
# 相依關係規則指出冒號右邊如果有任何檔案變更,
# 冒號左邊的目標檔是否應視為過期。
# 使過期目標檔保持最新的指令可在他處找到
# (以本例而言,是透過上述型樣規則)。
# 相依關係規則通常是用來擷取標頭檔相依關係。
Main.o : Main.h Test1.h Test2.h
Test1.o : Test1.h Test2.h
Test2.o : Test2.h

# 除了以手動方式擷取相依關係之外,還有數個自動化
# 相依關係產生器存在。以下是其中一個可能性(註銷)...
# %.dep : %.cpp
#        g++ -M $(FLAGS) $< > $@
# include $(OBJS:.o=.dep)

常見問題:

「主控台」視圖對建置進行除錯很有幫助。

Q1。「我的主控台」視圖顯示 "啟動建置器發生錯誤"。 它代表什麼意義?

啟動建置器錯誤 (make -k clean all )
(執行程式錯誤:啟動失敗)

很有可能 build 指令(依預設是 "make")沒有在存您的目錄中。您可以將它放置在路徑上再重新啟動 Eclipse。
您也可以將 build 指令變更為在您的路徑上的指令。如果您使用 MinGW 工具來進行編譯,則應該將 build 指令以 "mingw32-make" 代替。

Q2。 「我的主控台」視圖顯示 "Make 目標 X 無規則"

make -k clean all
make: *** No rule to make target 'clean'.
make: *** No rule to make target 'all'.

依預設,make 程式尋找一個通常叫作 "Makefile" 或 "makefile"。 如果它在工作目錄中找不到這樣的檔案, 或該檔案是空的或檔案不包含指令行目標的規則(在本例為 clean" 與 "all"),它將會失敗,與此問題相關的錯誤訊息會出現。

如果您已經具備有效的 Make 檔,則需要變更建置的工作目錄。build 指令的預設工作目錄是專案的根目錄。 您可以在 Make 專案內容中指定替代的「建置目錄」來變更這個目錄。 或者,如果 Make 檔另有別的名稱(例如 buildFile.mk), 您可以將預設 Build 指令設為 make -f buildFile.mk 來指定這個名稱。

如果您無有效的 Make 檔,請在根目錄中建立一個叫作 Makefile 的新檔案。然後您可以新增範例 Make 檔的內容(如上),並適當地修改它。

Q3。「我的主控台」視圖顯示 "遺漏分隔字元"

make -k clean all
makefile:12: *** missing separator.  Stop.

Make 檔的標準語法指出在建置規則中的每一行之前必須是欄標字元。這個欄標字元通常取代成空格, 而且因為兩者都導致空白字元縮排,所以這個問題容易遭到忽略。在所提供的範例中,錯誤訊息可以精確指向 "makefile" 檔的第 12 行;如果要解決這個問題,請在該行開頭插入欄標。

Q4。我的主控台」視圖顯示 "目標檔 'all' 因為錯誤而未重作"

make -k clean all
make: *** [clean] Error 255
rm -f Test1.o Test2.o Main.o test_me.exe
g++ -g -o Test1.o -c Test1.cpp
make: *** [Test1.o] Error 255
make: *** [Test2.o] Error 255
make: *** [Main.o] Error 255
g++ -g -o Test2.o -c Test2.cpp
g++ -g -o Main.o -c Main.cpp
make: Target 'all' not remade because of errors.

這裡可能出錯的地方是 g++ 不在路徑上。

錯誤 255 是由 make 產生,因為它的指令 Shell 無法找到特定規則的指令。
來自標準錯誤串流(指令行顯示錯誤 255)及標準輸出串流(所有其他指令行)的訊息會合併在這裡的「主控台」視圖中。

Q5。-k 旗標的作用?

-k 旗標告訴 make 即使有一個規則失敗,也要繼續製作其他獨立的規則。 這對於建置大型專案很有幫助。

您可以開啟「專案內容 > C/C++ Make 專案 > Make 建置器 > 在第一個建置錯誤停止」等選項來移除 -k 旗標。

Q6。「我的主控台」視圖如下:

mingw32-make clean all
process_begin: CreateProcess((null), rm -f Test1.o Test2.o Main.o test_me.exe, ...) failed.
make (e=2): The system cannot find the file specified.

mingw32-make: *** [clean] Error 2
rm -f Test1.o Test2.o Main.o test_me.exe

這表示 mingw32-make 找不到公用程式 "rm"。很可惜,MinGW 並未附帶 "rm"。如果要更正這個問題,請將 make 檔中的 clean 規則取代成:

clean :
	-del $(REBUILDABLES)
	echo Clean done

前導的減號告訴 make,即使 del 指令傳回失敗,亦將 clean 規則視為順利完成。由於指定要刪除的檔案若尚未存在(或不復存在),del 指令會失敗,因此這是可接受的。

IBM 版權聲明