2011-01-12 11 views
8

Mam wspólny kod (na przykład hello.cpp) używany przez wiele plików wykonywalnych. Używam jednego Makefile to wszystko budować:Pomóż uprościć plik Makefile dla wielu plików wykonywalnych

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) 

nie jestem bardzo zadowolony z posiadania odrębnej cel dla każdego pliku wykonywalnego - cele są zasadniczo takie same. Czy jest jakiś sposób na zrobienie tego z jednym celem dla wszystkich plików wykonywalnych? Miałem nadzieję, że coś jak to będzie działać:

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) 

Ale dostaję łączący błąd:

[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 

Z jakiegoś powodu stara się budować app1.out bez buduje swoją zależność hello.o. Czy ktoś może wyjaśnić, dlaczego to nie działa i sugerować coś, co robi?

Oto reszta manekina, na wszelki wypadek.

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 

Odpowiedz

4

Problem polega na tym, że używasz reguł sufiksów w starym stylu. Z informacji Producent:

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

Rozwiązaniem jest użycie reguł wzorców nowy-style:

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

(również pamiętać, że nie trzeba zdefiniować .cpp do .o regułę; make ma sensowną domyślną.)

+0

Dzięki za odpowiedź. Używam reguły .cpp do .o do dostarczania niestandardowego 'CPPFLAGS' do kompilatora. Nie pokazałem ich w przykładowym kodzie, ponieważ zachowałem prostotę. Czy wartości domyślne 'make' nadal zawierają" domyślne "nazwy zmiennych (np.' CFLAGS', 'CPPFLAGS',' LDFLAGS', itd.)? – misha

+1

Tak, ale 'CPPFLAGS' jest dla pre-procesora C. 'CXXFLAGS' jest dla flag C++. –

Powiązane problemy