2012-10-03 12 views
5

Sto facendo funzionare un semplice Makefile senza problemi:Makefile regola C sottodirectory per rendere 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) 

I file sono nella directory del progetto principale:

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

poi ho cercato di file organizzati , e mettere le cose come:

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

ed extra sottodirectory directory:

012.
./project/lib 
./project/obj 

Poi la nuova versione del 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)/*~ 

sto la compilazione su Linux usando Emacs con il compilatore gcc:

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

Poi, corro su Emacs:

<Esc> 
x 
compile 
make 

E dà il messaggio:

"./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 

Quale regola deve mancare per essere inclusa nel file Makefile?

Tutti i commenti e suggerimenti sono molto apprezzati.


Grazie per il tuo suggerimento, è stato aggiunto al codice. Quindi il compilatore si lamenta:

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 

Qualche altro suggerimento?

Grazie in anticipo!

+0

'project/obj' sarebbe un po 'più ragionevole di' project/src/obj' –

+0

Ciao Steve-o. Grazie! Ho fatto il cambiamento che hai suggerito. – ThreaderSlash

risposta

5

per correggere l'errore make: *** No rule to make target 'obj/hellomake.o', needed by 'hellomake'. Stop.

Modifica questa linea:

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

A:

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

Questo crea una regola per tutti gli oggetti nella variabile $(OBJ). Il secondo parametro ('$(ODIR)/%.o') estrae il nome del file dal percorso completo per passare solo il nome del file al terzo parametro ('src/%.c').

+0

Ciao Ryan. Hai ragione ... i file mancavano in "src /". Inoltre cancello ".." come suggerito. Ma rimane un errore: make: *** Nessuna regola per rendere target '/include/hellomake.h ', necessario per' obj/hellomake.o'. – ThreaderSlash

+0

Rimuovi l'inizio/dall'inclusione. Quella/dice al Makefile di cercare nella directory radice del filesystem invece della cartella del progetto. – Ryan

+0

Ryan, grazie ancora! Ho tolto il "/". L'unico errore rimanente è scomparso. Quindi in (gdb) run ... restituisce: {{(gdb) run Programma iniziale: Nessun file eseguibile specificato. Utilizzare il comando "file" o "file exec".}} – ThreaderSlash

-1

Ok.Ora sto cercando un altro esempio trovato qui [How can I create a Makefile for C projects with SRC, OBJ, and BIN subdirectories?] e qui va:

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!" 

I file sono organizzati come:

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

Il compilatore persiste dando solo una lamentela:

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 

Grazie mille per tutti i commenti e suggerimenti!

+0

Anche se questo è vecchio di anni, il tuo problema è semplicemente che 'TARGETPATH' non è definito e quindi' $ (TARGETPATH)/$ (TARGET) 'nel linker si risolverà in'/bin'. – xtra