Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to place object files in separate subdirectory

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: http://www.gnu.org/software/hello/manual/make/Prerequisite-Types.html#Prerequisite-Types

I get the following output from make:

make: *** No rule to make target `ku.h', needed by `obj/kumain.o'.  Stop. 

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?

my makefile is this: (the style is after reading various sources of information)

.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) 

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:

    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 

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

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

Any assistance in getting implicit rules to work for my makefile would be greatly appreciated.

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.

Here is the working makfile:

.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) $< -o $@  .PHONY : clean clean :   rm $(objects) 
like image 866
RussellG Avatar asked Mar 03 '11 08:03

RussellG


1 Answers

Since you're using GNUmake, use a pattern rule for compiling object files:

$(OBJDIR)/%.o: %.c     $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< 
like image 170
Jack Kelly Avatar answered Sep 30 '22 02:09

Jack Kelly