Maybe the below makes sense for some reason I don't understand but it sure seems weird. Seems like $< ends up with a different value depending on where the request for the target comes from:
$ ls Makefile $ cat Makefile OBJS = foo.o FC = cp # Fake Compile FL = cp # Fake Link vpath %.o objdir %.o: %.c $(FC) $< objdir/$@ foo: foo.o $(FL) $< $@ clean: rm -f *.o rm -f objdir/*.o rm foo $ mkdir objdir $ touch foo.c $ make foo.o cp foo.c objdir/foo.o $ make foo cp objdir/foo.o foo $ make clean rm -f *.o rm -f objdir/*.o rm foo $ make foo cp foo.c objdir/foo.o cp foo.o foo cp: cannot stat 'foo.o': No such file or directory make: *** [Makefile:12: foo] Error 1 2 $