2012-07-11 47 views
6

這只是makefile的一部分。我不太明白髮生了什麼事。makefile中有多個冒號和等號(需要說明)

OBJS = $(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o) 
$(OBJS):$(OBJ)/%.o: $(SRC)/%.cpp | print-opts 
    $(cc-command) 

所有我知道的是這些行將「.cpp」文件編譯爲.o,'print-opts'後,'cc-command'。但我不明白這個語義。

如果我擴大 'OBJS' 的宏,此行應該是:

$(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o) : $(OBJ)/%.o: $(SRC)/%.cpp | print-opts 
    $(cc-command) 

對我來說,它看起來像在「$(SRCS:$(SRC)/%CPP = $(OBJ )/%。o)',它聲稱$(SRC)中的所有.cpp將在$(OBJ)中到達.o,但這取決於$(OBJ)/%。o,這取決於$(SRC) /%.cpp。這沒有任何意義...

我不明白這裏等號的含義是什麼,以及多個冒號意味着什麼。

回答

14

假設你定義這三個變量(如果你沒有,該規則將不能很好地工作):

SRC = source_dir 
OBJ = object_dir 
SRCS = source_dir/foo.cpp source_dir/bar.cpp 

現在考慮分配

OBJS = $(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o) 

這是a substitution reference;它說「對於$(SRCS)中的任何形式爲$(SRC)/%.cpp的項目,將其更改爲$(OBJ)/%.o」。所以OBJS將評估爲object_dir/foo.o object_dir/bar.o

現在的規則:

$(OBJS):$(OBJ)/%.o: $(SRC)/%.cpp | print-opts 
    $(cc-command) 

的Thuis是static pattern rule。它指定目標列表($(OBJS)),目標模式($(OBJ)/%.o)和先決模式($(SRC)/%.cpp)。使目標與目標模式匹配,並使用它來構建必備條件名稱。因此,如果Make使用此規則構建object_dir/foo.o,詞幹將爲foo,前提條件爲source_dir/foo.cpp

(你沒問| print-opts,所以我認爲它已經清楚了。)

+0

非常感謝你。 gnu'make'手冊的引用也很有幫助。 (之前我曾看過那本手冊,但找不到我需要的信息) – qinsoon 2012-07-12 02:01:22

+0

Tad困惑於替代參考。所以,如果我有'main.c',它會將其粘貼到目標文件目錄中,並將文件擴展名更改爲'.o'。這保留了文件的內容,只是改變了擴展名。這爲我們將要結束的所有對象文件設置名稱。然後,我們使用名稱列表作爲目標,並將其編譯爲目標文件,並用剛剛編譯的新目標文件覆蓋這些文件。正確? – Ungeheuer 2017-04-27 15:43:38

+0

@Ungeheuer:不,替換引用對文件什麼都不做,它只是轉換變量。它將「source_dir/main.cpp」變成「object_dir/main.o」;這些是*文件名*,而不是*文件*。一旦我們有字符串「object_dir/main.o」,我們就可以將它傳遞給模式規則,它知道如何構建該名稱的文件。 – Beta 2017-04-27 23:56:25