2011-01-12 6 views
8

Ich habe gemeinsamen Code (z. B. hello.cpp), die von mehreren ausführbaren Dateien verwendet wird. Ich bin mit einem einzigen Makefile, es zu bauen alle:Hilfe zur Vereinfachung einer Makefile für mehrere ausführbare Dateien

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) 

Ich bin nicht sehr glücklich über ein separates Ziel für jede ausführbare Datei mit - die Ziele sind im Wesentlichen gleich. Gibt es eine Möglichkeit, dies mit einem Ziel für alle ausführbaren Dateien zu tun? Ich habe gehofft, dass so etwas wie dies funktionieren würde:

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) 

Aber ich bekomme einen Verbindungsfehler:

[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 

Aus irgendeinem Grunde es versucht app1.out zu bauen, ohne die Abhängigkeit hello.o zu bauen. Kann jemand erklären, warum das nicht funktioniert, und etwas vorschlagen, das tut?

Hier ist der Rest des Dummy-Codes, nur für den Fall.

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 

Antwort

4

Das Problem scheint zu sein, dass Sie alte Suffixregeln verwenden. Von der Marke Info:

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'.

Die Lösung ist neu Stil Muster Regeln zu verwenden:

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

(Beachten Sie, dass Sie der Regel keine CPP definieren müssen, um .o; make hat einen vernünftigen Standard.)

+0

Danke für Ihre Antwort. Ich benutze die .cpp zu .o-Regel, um dem Compiler "CPPFLAGS" zu liefern. Ich habe sie im Beispielcode nicht gezeigt, weil ich die Dinge einfach gehalten habe. Werden 'make'-Defaults immer noch die" Standard "-Variablennamen enthalten (z.B.' CFLAGS', 'CPPFLAGS',' LDFLAGS', usw.)? – misha

+1

Ja, aber 'CPPFLAGS' ist für den C-Preprozessor. 'CXXFLAGS' ist für C++ Flags. –

Verwandte Themen