make 'vpath' directive, why isn't it sufficient for this prerequisite?

477 Views Asked by At

The following example makefile works as expected, using vpath to find object files and source files. But in the last line, where i tell make about the dependency of one object file on the other, I need to specify the directory $(objd)/ of the prerequisite file, otherwise i get an error (see error message below the code). How come the vpath directive isn't sufficient in the last line?

# Program Name
prog = avpar

#dirs
objd=obj
modd=mod


# extra places to search for prerequisites
vpath %.f90 ../modules
vpath %.o obj/

# etc
FC      = gfortran
flags       = -I$(modd) -J$(modd) #-fopenmp

obj_files   = $(prog).o rw_mod.o 

# compile
p$(prog): $(obj_files)    
    $(FC)  $(flags) $^ -o $@

$(objd)/%.o: %.f90  
    $(FC)  $(flags) -c $< -o $@

$(objd)/$(prog).o: $(objd)/rw_mod.o

That is, changing the last line to:

$(objd)/$(prog).o: rw_mod.o

gives the error:

make: *** No rule to make target 'rw_mod.o', needed by 'obj/avpar.o'.  Stop.

EDIT with this form of the last lines it does also work, without the directory specification:

#compile
p$(prog): $(obj_files)    
    $(FC)  $(flags) $^ -o $@

$(objd)/rw_mod.o: rw_mod.f90 
    $(FC)  $(flags) -c $< -o $@

$(objd)/$(prog).o: $(prog).f90 rw_mod.o
    $(FC)  $(flags) -c $< -o $@
1

There are 1 best solutions below

2
user657267 On

vpath can only be used to find prerequisites that exist.

Makefiles rule 3

Use VPATH to locate the sources from the objects directory, not to locate the objects from the sources directory.

There's no rule that matches rw_mod.o so the rule for obj/avpar.o fails, vpath won't prepend stuff during prerequisite rule lookup, the only way it would work here would be if obj/rw_mod.o already existed.

It's unlikely that rule is correct anyway, why would one object file depend on another?