2011-01-12 75 views
8

我擁有多個可執行文件使用的通用代碼(例如hello.cpp)。我使用的是單一的Makefile打造這一切:幫助簡化多個可執行文件的Makefile

EXE=app1.out app2.out 
SRC=hello.cpp 
OBJ=$(SRC:.cpp=.o) 
SRC_MAIN=app1.cpp app2.cpp 
OBJ_MAIN=$(SRC_MAIN:.cpp=.o) 
all: $(EXE)  
app1.out: app1.o $(OBJ) 
    g++ $< $(OBJ) -o [email protected]  
app2.out: app2.o $(OBJ) 
    g++ $< $(OBJ) -o [email protected]  
.cpp.o: 
    g++ -c $< -o [email protected]  
clean: 
    rm -f $(EXE) $(OBJ) $(OBJ_MAIN) 

我不會爲每個可執行一個單獨的目標很開心 - 目標基本上是相同的。有沒有辦法用一個目標來執行所有可執行文件?我希望這樣的事情會的工作:

EXE=app1.out app2.out 
SRC=hello.cpp 
OBJ=$(SRC:.cpp=.o) 
SRC_MAIN=app1.cpp app2.cpp 
OBJ_MAIN=$(SRC_MAIN:.cpp=.o) 
all: $(EXE) 
.o.out: $(OBJ) 
    g++ $< $(OBJ) -o [email protected] 
.cpp.o: 
    g++ -c $< -o [email protected] 
clean: 
    rm -f $(EXE) $(OBJ) $(OBJ_MAIN) 

但我得到一個鏈接錯誤:

[email protected]:~/cpp/stack$ make -f Makefile2 
g++ -c app1.cpp -o app1.o 
g++ app1.o hello.o -o app1.out 
g++: hello.o: No such file or directory 
make: *** [app1.out] Error 1 
rm app1.o 

對於它試圖建立app1.out沒有建立其依賴hello.o某種原因。任何人都可以解釋爲什麼這不起作用,並建議這樣做嗎?

這是其餘的虛擬代碼,以防萬一。

app1.cpp:

#include "hello.h" 
int 
main(void) 
{ 
    print_hello(); 
} 

app2.cpp:

#include "hello.h"  
int 
main(void) 
{ 
    for (int i = 0; i < 4; ++i) 
     print_hello(); 
    return 0; 
} 

HELLO.CPP:

#include "hello.h"  
#include <stdio.h>  
void 
print_hello() 
{ 
    printf("hello world!\n"); 
} 

hello.h:

#ifndef HELLO_H 
#define HELLO_H 
void 
print_hello(); 
#endif 

回答

4

問題似乎是您正在使用舊式後綴規則。從補充信息:

Suffix rules cannot have any prerequisites of their own. If they have any, they are treated as normal files with funny names, not as suffix rules. Thus, the rule:

.c.o: foo.h 
      $(CC) -c $(CFLAGS) $(CPPFLAGS) -o [email protected] $< 

tells how to make the file '.c.o' from the prerequisite file 'foo.h', and is not at all like the pattern rule:

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

which tells how to make '.o' files from '.c' files, and makes all '.o' files using this pattern rule also depend on 'foo.h'.

的解決方案是使用新型模式規則:

%.out: %.o $(OBJ) 
    g++ $< $(OBJ) -o [email protected] 
%.o: %.cpp 
    g++ -c $< -o [email protected] 

(另請注意,你並不需要定義一個.cpp到.O規則; make有一個合理的默認值。)

+0

感謝您的回答。我使用.cpp to .o規則爲編譯器提供自定義的`CPPFLAGS`。我沒有在示例代碼中顯示它們,因爲我保持簡單。 `make`默認值是否仍然包含「默認」變量名稱(例如`CFLAGS`,`CPPFLAGS`,`LDFLAGS`等)? – misha 2011-01-12 07:47:05