2012-10-03 12 views
5

Używam prostego Makefile bez problemów:Makefile reguła podkatalogu C aby OBJ

CC=gcc 
CFLAGS= -std=c99 -ggdb -Wall -I. 
DEPS = hellomake.h 
OBJ = hellomake.o hellofunc.o 

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

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

Pliki są w katalogu głównego projektu:

./project/Makefile 
./project/hellomake.c 
./project/hellomake.h 

Potem próbowałem zorganizowany plików i umieścić rzeczy jak:

./project/Makefile 
./project/src/hellomake.c 
./project/include/hellomake.h 

i dodatkowych podkatalogach katalogów:

./project/lib 
./project/obj 

Potem nowa wersja Makefile:

IDIR =include 
CC=gcc 
CFLAGS= -std=c99 -ggdb -Wall -I$(IDIR) 

ODIR=obj 
LDIR =lib 

LIBS=-lm 

_DEPS = hellomake.h 
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS)) 

_OBJ = hellomake.o hellofunc.o 
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ)) 


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

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

.PHONY: clean 

clean: 
    rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ 

Mam kompilacji na systemie Linux za pomocą Emacsa z kompilatora gcc:

$ gcc --version 
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 

Potem biegnę na Emacs:

<Esc> 
x 
compile 
make 

I daje komunikat:

"./project/src/" -*- 
make: *** No rule to make target `obj/hellomake.o', needed by `hellomake'. Stop. 
Compilation exited abnormally with code 2 at Wed Oct 3 17:10:01 

Jakiej zasady powinna brakować w pliku Makefile?

Wszystkie komentarze i sugestie są wysoko cenione.


Dzięki za sugestię, jest ona dodawana do kodu. Następnie kompilator narzeka:

make -k 
make: *** No rule to make target `src/hellomake.c', needed by `obj/hellomake.o'. 
make: *** No rule to make target `../include/hellomake.h', needed by `obj/hellomake.o'. 
make: Target `obj/hellomake.o' not remade because of errors 

Jakieś inne sugestie?

Z góry dziękuję!

+0

'project/obj' byłoby odrobinę bardziej sensowne niż' project/src/obj' –

+0

Witaj, Steve-o. Dzięki! Wprowadziłem zmianę, którą zasugerowałeś. – ThreaderSlash

Odpowiedz

5

naprawić błąd make: *** No rule to make target 'obj/hellomake.o', needed by 'hellomake'. Stop.

zmienić tę linię:

$(ODIR)/%.o: %.c $(DEPS) 

Do:

$(OBJ): $(ODIR)/%.o: src/%.c $(DEPS) 

To tworzy reguły dla wszystkich obiektów w zmiennej $(OBJ). Drugi parametr ("$(ODIR)/%.o") wyodrębnia nazwę pliku z pełnej ścieżki, aby przekazać nazwę pliku tylko do trzeciego parametru ("src/%.c").

+0

Witaj Ryan. Masz rację ... brakowało plików w "src /". Usuwam też ".." jak sugerujesz. Został jednak jeden błąd: make: *** Brak reguły dla celu '/include/hellomake.h ', wymagany przez' obj/hellomake.o'. – ThreaderSlash

+0

Usuń początek/z uwzględnienia. To/mówi Makefile, aby zajrzał do katalogu głównego systemu plików zamiast do folderu projektu. – Ryan

+0

Ryan dzięki jeszcze raz! Zdjąłem "/". Jeden pozostały błąd zniknął. Następnie uruchom (gdb) ... daje: {{(gdb) uruchom Program startowy: Nie określono pliku wykonywalnego. Użyj polecenia "file" lub "exec-file".}} – ThreaderSlash

-1

Ok.Teraz próbuję kolejny przykład znaleźć tutaj [How can I create a Makefile for C projects with SRC, OBJ, and BIN subdirectories?] a tu idzie:

TARGET = hi.sh 
CC  = gcc 
# compiling flags here 
CFLAGS = -std=c99 -ggdb -Wall -I./src 
TARGET = bin/hi.sh 

LINKER = gcc -o 
# linking flags here 
LFLAGS = -Wall -I. -lm 

# change these to set the proper directories where each files shoould be 
SRCDIR = src 
OBJDIR = obj 
BINDIR = bin 

SOURCES := $(wildcard $(SRCDIR)/*.c) 
INCLUDES := $(wildcard $(SRCDIR)/*.h) 
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o) 
rm  = rm -f 


$(BINDIR)/$(TARGET): $(OBJECTS) 
    @$(LINKER) $(TARGETPATH)/$(TARGET) $(LFLAGS) $(OBJECTS) 
    @echo "Linking complete!" 

OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o) 

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c 
    $(CC) $(CFLAGS) -c $< -o [email protected] 
    @echo "Compiled "$<" successfully!" 

.PHONEY: clean 
clean: 
    @$(rm) $(OBJECTS) 
    @echo "Cleanup complete!" 

.PHONEY: remove 
remove: clean 
    @$(rm) $(BINDIR)/$(TARGET) 
    @echo "Executable removed!" 

Pliki są organizowane jako:

./project/bin/ executable 
./project/ojb/*.0 
./project/src/*.c and *.h 
./project/Makefile 

Kompilator utrzymuje się podając tylko jeden zarzut:

make -k 
/usr/bin/ld: cannot open output file /bin/hi.sh: Permission denied 
collect2: ld returned 1 exit status 
make: *** [bin/bin/hi.sh] Error 1 

Wielkie dzięki za wszystkie komentarze i sugestie!

+0

Nawet jeśli jest to lat, twój problem polega po prostu na tym, że 'TARGETPATH' nie jest zdefiniowana i dlatego' $ (TARGETPATH)/$ (TARGET) 'w linkerze rozwiąże'/bin'. – xtra