cgccmakefilevpath

Use vpath to find generated files


I'm trying to write a Makefile that compiles a *.c into an *.o and then move it to obj/. However when I try to link all the *.o files in main I get an error as if the generated files were not found. I tried to prefix the code with the right path but it wouldn't find it anyway. Does anyone have an idea on what I need to change to my code so that it does find the *.o files. This is my Makefile:

EXEC = main
CFLAGS = -c -Wall -g -I include -std=c99
OBJECTS = main.o jeu.o grille.o io.o
EXEC = main
DOCGEN = doxygen

vpath %.c src/
vpath %.h include/
vpath %.o obj/
vpath main bin/

all: main

main: $(OBJECTS)
    @echo "\n==== Linking $@ $^ ===="
    @gcc -o $@ $(OBJECTS)
    @mkdir -p bin
    @mv $@ bin/
    #@mkdir -p obj
    #@mv *.o obj/

main.o: io.h jeu.h

io.o: io.h 

jeu.o: jeu.h

%.o: %.c grille.h
    @echo "\n---- Rule " $@  $< "----"
    @gcc $(CFLAGS) $<
    @mkdir -p obj
    @mv $@ obj/


doc:
    @mkdir -p doc
    @$(DOCGEN)

clean: 
    @rm -rf doc/
    @rm -rf bin/
    @rm -rf obj/
    @rm -f *.xz

Any suggestions are welcome. I have read that vpath is not recommended for finding generated files. But this is an assignment and I have to use it this way. If I uncomment the two lines and comment the last two lines from the %.o rule, the code works great, but I cannot do that. This is the error at execution:

---- Rule  main.o src/main.c ----

---- Rule  jeu.o src/jeu.c ----

---- Rule  grille.o src/grille.c ----

---- Rule  io.o src/io.c ----

==== Linking main main.o jeu.o grille.o io.o ====
gcc: error: main.o: No such file or directory
gcc: error: jeu.o: No such file or directory
gcc: error: grille.o: No such file or directory
gcc: error: io.o: No such file or directory
gcc: fatal error: no input files
compilation terminated.
Makefile:15: recipe for target 'main' failed
make: *** [main] Error 1

Solution

  • Consider changing the compile rule to refer to the object folder:

    obj/%.o: %.c 
        [ -d obj ] || mkdir -p obj
        gcc -o $@ $<