2014-03-31 69 views
0

我想用簡單的三個文件來學習makeMakefile第一個規則目標

foo.h中

#ifndef __foo_H_ 
#define __foo_H_ 

void print(); 

#endif 

foo.c的

#include <stdio.h> 
#include "foo.h" 


void print() 
{ 
    printf("Hello World !"); 
} 

的main.c

#include "foo.h" 

int main() 
{ 
    print(); 
    return 0; 
} 

當我使用下面的Makefile,一切都正常運行

的makefile

CC = gcc 
CFLAGS = -I. 
DEPS = foo.h 
OBJ = foo.o main.o 

.PHONY: clean 

main: $(OBJ) 
     gcc -o [email protected] $^ $(CFLAGS) 

%.o: %.c $(DEPS) 
     $(CC) -c -o [email protected] $< $(CFLAGS) 

clean: 
     rm *.o 

上面的工作是因爲make默認運行第一個目標(我基本上都是在這裏讀取的)。

如果我用下面的makefile

CC = gcc 
CFLAGS = -I. 
DEPS = foo.h 
OBJ = foo.o main.o 

.PHONY: clean 

clean: 
     rm *.o 

main: $(OBJ) 
     gcc -o [email protected] $^ $(CFLAGS) 

%.o: %.c $(DEPS) 
     $(CC) -c -o [email protected] $< $(CFLAGS) 

以上的makefile調用make因爲make默認運行的第一條規則只運行make clean

問題是與此生成的文件

CC = gcc 
CFLAGS = -I. 
DEPS = foo.h 
OBJ = foo.o main.o 

.PHONY: clean 

%.o: %.c $(DEPS) 
     $(CC) -c -o [email protected] $< $(CFLAGS) 

main: $(OBJ) 
     gcc -o [email protected] $^ $(CFLAGS) 

clean: 
     rm *.o 

在上面的makefile使用make我得到

gcc -c -o foo.o foo.c -I. 
gcc -c -o main.o main.c -I. 
gcc -o main foo.o main.o -I. 

爲什麼不make只是建立.o文件並停止,因爲它是第一目標爲什麼它還會繼續構建主體?沒有我在第一條規則中指定的構建main的地方。

+0

大概規則是第一個*特定*目標將被制定。像'%.o:%.c $(DEPS)'這樣的隱式模式規則不會指定特定的目標。 –

+0

@j_random_hacker但是模式不是一個有效的目標。所以如果我要使用一個只使用上述模式構建目標文件的makefile,那麼'make'期望什麼都不應該發生,是不是很奇怪? –

+0

@j_random_hacker是的,如果我只指定了模式,那麼'make'說「make:***沒有目標,停止。「 –

回答

5

「第一個目標」規則只計算顯式目標。它不會計算隱式目標,例如後綴規則或模式規則。

考慮:如何確定它應該建立.o文件?它應該構建哪個.o文件?如何理解它應該在變量OBJ中構建變量,而不是其他變量?

+0

但是不能將這種模式用作創建所有'.c文件的目標文件'檔案? –

+0

該模式規則將應用於匹配'%.o'的所有請求/所需目標,但該規則本身並未指定任何需要構建的顯式目標。具體做法是不去尋找目標建立。它只建立你已經告訴它構建的東西(以及它確定需要構建的東西)。 –

+0

@Kartik Anand:不。那個模式說「如果你有一個.c,你想建立一個.o,你可以用這個配方來做。」。這是一個抽象的陳述。 Make沒有任何工具可以讓它理解_all'.c'文件_的含義。它永遠不會(單單)瀏覽目錄中的所有文件,並選擇看起來與某種模式匹配的文件,然後構建它。 Make只會構建你明確要求它構建的目標,無論是通過makefile中的顯式目標還是命令行(例如'make foo.o')。 – MadScientist

1

我正在尋找手冊的一個很好的部分來指出你,但沒有找到任何具體和具體的使用。就我所知,這個問題的答案是,模式規則不是目標,默認目標必須如其名稱所示,成爲目標。

如果你使用一個靜態模式規則(它確實定義了目標),那麼你的期望幾乎是正確的,因爲make會選擇第一個這樣的文件,並在這種情況下構建它(並非全部如你所期望的那樣) 。

+0

即使我在想同樣的事情,但我找不到明確寫的任何地方 –

+0

如果你仔細閱讀,你會注意到手冊中談到的目標和規則明顯並且討論了默認目標,定義目標和定義模式規則,我相信這是手冊最接近於特定的內容 –