Règle de sous-répertoire Makefile C pour faire obj

J’exécute un Makefile simple sans problèmes:

CC=gcc CFLAGS= -std=c99 -ggdb -Wall -I. DEPS = hellomake.h OBJ = hellomake.o hellofunc.o %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) hellomake: $(OBJ) gcc -o $@ $^ $(CFLAGS) 

Les fichiers sont dans le répertoire du projet principal:

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

Ensuite, j’ai essayé d’organiser les fichiers et de mettre des choses comme:

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

et répertoires supplémentaires de sous-répertoires:

 ./project/lib ./project/obj 

Puis la nouvelle version du 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 $@ $< $(CFLAGS) hellomake: $(OBJ) gcc -o $@ $^ $(CFLAGS) $(LIBS) .PHONY: clean clean: rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ 

Je comstack sous Linux en utilisant Emacs avec le compilateur gcc:

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

Ensuite, je cours sur Emacs:

  x comstack make 

Et cela donne le message:

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

Quelle règle devrait être manquant pour être inclus dans le fichier Makefile?

Tous les commentaires et suggestions sont très appréciés.


Merci pour votre suggestion, elle est ajoutée au code. Ensuite, le compilateur se plaint:

 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 

Une autre suggestion?

Merci d’avance!

    Pour corriger l’erreur, make: *** No rule to make target 'obj/hellomake.o', needed by 'hellomake'. Stop. make: *** No rule to make target 'obj/hellomake.o', needed by 'hellomake'. Stop.

    Changer cette ligne:

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

    À:

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

    Cela crée une règle pour tous les objects de la variable $(OBJ) . Le deuxième paramètre (‘ $(ODIR)/%.o ‘) extrait le nom du fichier du chemin complet afin de ne transmettre que le nom du fichier au troisième paramètre (‘ src/%.c ‘).

    D’accord. Maintenant, je suis en train d’essayer un autre exemple trouvé ici [ Comment créer un Makefile pour des projets C avec des sous-répertoires SRC, OBJ et BIN? ] et voilà:

     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 $@ @echo "Compiled "$<" successfully!" .PHONEY: clean clean: @$(rm) $(OBJECTS) @echo "Cleanup complete!" .PHONEY: remove remove: clean @$(rm) $(BINDIR)/$(TARGET) @echo "Executable removed!" 

    Les fichiers sont organisés comme suit:

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

    Le compilateur persiste en ne donnant qu'une plainte:

     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 

    Merci beaucoup pour tous vos commentaires et suggestions!