title: How to place object files in separate subdirectory
body: <p>I'm having trouble with trying to use make to place object files in a separate subdirectory, probably a very basic technique. I have tried to use the information in this page:
  <a href="http://www.gnu.org/software/hello/manual/make/Prerequisite-Types.html#Prerequisite-Types" rel="noreferrer">http://www.gnu.org/software/hello/manual/make/Prerequisite-Types.html#Prerequisite-Types</a></p>
  
  <p>I get the following output from make:</p>
  
  <pre><code>make: *** No rule to make target `ku.h', needed by `obj/kumain.o'.  Stop.
  </code></pre>
  
  <p>However ku.h is a dependency not a target (although it's obviously #included within the c source files). When I don't try to use a subdirectory for object files (i.e. miss out the OBJDIR parts) it works fine. Why does make think ku.h is a target?</p>
  
  <p>my makefile is this: (the style is after reading various sources of information)</p>
  
  <pre><code>.SUFFIXES:
  .SUFFIXES: .c .o
  
  CC=gcc 
  CPPFLAGS=-Wall
  LDLIBS=-lhpdf
  VPATH=%.c src
  VPATH=%.h src
  VPATH=%.o obj
  OBJDIR=obj
  
  objects= $(addprefix $(OBJDIR)/, kumain.o kudlx.o kusolvesk.o kugetpuz.o kuutils.o \
    kurand.o kuASCboard.o kuPDFs.o kupuzstrings.o kugensud.o \
    kushapes.o )
  
  ku : $(objects)
    $(CC) $(CPPFLAGS) -o ku $(objects) $(LDLIBS)
  
  $(objects) : ku.h kudefines.h kuglobals.h kufns.h | $(OBJDIR)
  
  $(OBJDIR):
    mkdir $(OBJDIR)
  
  .PHONY: clean
  clean :
    rm $(objects)
  </code></pre>
  
  <p>Edit:
  I applied the change to use the vpath directive. My version was a bad mixture of VPATH=xxx and vpath %.c xxx. However I now get another problem (which was the original problem before I added the wrong vpath). This is now the output:</p>
  
  <pre><code>    gcc  -o ku -lhpdf obj/kumain.o obj/kudlx.o obj/kusolvesk.o ..etc
      gcc: obj/kumain.o: No such file or directory
      gcc: obj/kudlx.o: No such file or directory
      gcc: obj/kusolvesk.o: No such file or directory
      gcc: obj/kugetpuz.o: No such file or directory
      gcc: obj/kuutils.o: No such file or directory
      gcc: obj/kurand.o: No such file or directory
      gcc: obj/kuASCboard.o: No such file or directory
      gcc: obj/kuPDFs.o: No such file or directory
      gcc: obj/kupuzstrings.o: No such file or directory
      gcc: obj/kugensud.o: No such file or directory
      gcc: obj/kushapes.o: No such file or directory
      make: *** [ku] Error 1
  </code></pre>
  
  <p>It appears that make is not applying the implicit rule for an object file although the manual says 
  "Implicit rules tell make how to use customary techniques so that you do not have to specify them in detail when you want to use them. For example, there is an implicit rule for C compilation. File names determine which implicit rules are run. For example, C compilation typically takes a .c file and makes a .o file. So make applies the implicit rule for C compilation when it sees this combination of file name endings." and also "The search through the directories specified in VPATH or with vpath also happens during consideration of implicit rules (see Using Implicit Rules)."</p>
  
  <p>Again here "For example, when a file foo.o has no explicit rule, make considers implicit rules, such as the built-in rule to compile foo.c if that file exists. If such a file is lacking in the current directory, the appropriate directories are searched for it. If foo.c exists (or is mentioned in the makefile) in any of the directories, the implicit rule for C compilation is applied."</p>
  
  <p>Any assistance in getting implicit rules to work for my makefile would be greatly appreciated.</p>
  
  <p>Edit no 2:
  Thanks to Jack Kelly I have made an explicit rule to compile the .c files since I couldn't get anywhere trying to use implicit rules. Also thanks to al_miro for the vpath info.</p>
  
  <p>Here is the working makfile:</p>
  
  <pre><code>.SUFFIXES:
  .SUFFIXES: .c .o
  
  CC=gcc 
  CPPFLAGS=-Wall
  LDLIBS=-lhpdf
  OBJDIR=obj
  vpath %.c src
  vpath %.h src
  
  objects = $(addprefix $(OBJDIR)/, kumain.o kudlx.o kusolvesk.o kugetpuz.o kuutils.o \
    kurand.o kuASCboard.o kuPDFs.o kupuzstrings.o kugensud.o \
    kushapes.o )
  
  ku : $(objects)
    $(CC) $(CPPFLAGS) -o ku $(objects) $(LDLIBS)
  
  $(OBJDIR) obj/%.o : %.c ku.h kudefines.h kuglobals.h kufns.h 
    $(CC) -c $(CPPFLAGS) $&lt; -o $@
  
  .PHONY : clean
  clean :
    rm $(objects)
  </code></pre>