Gaurav K
Gaurav K

Reputation: 2975

Including a .h file and directing .o files to a directory: Make

I am trying to learn make files.

My directory Structure is

$ ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/   /' -e 's/-/|/'
   .
   |-bin
   |---exe
   |---obj
   |-build
   |-include
   |-lib
   |-make
   |-source

What I am trying to do is place my include file conversion.h in include folder, all .c files in source, makefile in make, compiled all .o files in bin/obj and exe in /bin/exe

I referred below posts:

makefile include *.h file in other directory

Using make to move .o files to a separate directory

my makefile is:

VPATH= ./../source
OBJDIR= ./../bin/obj
EXEDIR= ./../bin/exe
#vpath %.o $(OBJDIR)
CFLAGS= -Wall -c -I.
#INCLUDES= -I./../include

objects= binary.o hex.o octal.o

conversion: $(objects)
#       gcc -Wall -o conversion $(objects) -I.

binary.o: binary.c conversion.h
        gcc $(CFLAGS) $< -o $(OBJDIR)/$@

octal.o: octal.c conversion.h
        gcc $(CFLAGS) $< -o $(OBJDIR)/$@

hex.o: hex.c conversion.h
        gcc  $(CFLAGS) $< -o $(OBJDIR)/$@


clean:
        rm -rf $(OBJDIR)/*.o *.o *~ conversion

I am using cygwin. My questions are:

1) I am not able to include my conversion.h from location ./../include ,-I. works fine if I copy conversion.h to make folder -but as soon as I replace with -I./../include without any copy of conversion.h in make folder I get below error

$ make
make: *** No rule to make target 'conversion.h', needed by 'binary.o'.  Stop.

2) My makefile does place all .o files to /bin/obj but when I try to use vpath as shown below (instead of using manual placement like --o $(OBJDIR)/$@)

vpath %.o $(OBJDIR)
...
   $(OBJDIR)/binary.o: binary.c conversion.h
             gcc $(CFLAGS) $< -o $@
...
...

doing above replacement for all .o rules,does not place all .o files to bin/obj directory

Any help would be appreciated.

Thanks

Upvotes: 0

Views: 131

Answers (2)

esorton
esorton

Reputation: 1572

Since your header files are in a separate directory, make cannot locate them. Since it can't locate them, it tries to build them by looking for a target rule. Since it cant find a target, you get the error listed in your question.

The -I./../includes only affects the compiler's include search path. It does not affect how make looks for include.

If you want make to search for your header files you will need to add a vpath for the headers. You will likely get the same error for the source files since they are in a separate directory as well. Thus, you will need to add a vpath for the source files as well.

To get your original to work with vpath as opposed to explicit locations, try the following:

VPATH= ./../source
OBJDIR= ./../bin/obj
EXEDIR= ./../bin/exe
INCLUDES= -I./../include
vpath %.c $(VPATH)
vpath %.h $(INCLUDES)
vpath %.o $(OBJDIR)
CFLAGS= -Wall -c -I. $(INCLUDES)

As noted in my comment and the comments for your referenced question, it is not recommended to use vpath to locate object files.

Upvotes: 0

R Sahu
R Sahu

Reputation: 206717

You have to be explicit about the locations of the .h file, the .c files, the .o files, and the executable when you define the targets and their dependencies.

VPATH= ./../source
INCLUDEDIR= ./../include
OBJDIR= ./../bin/obj
EXEDIR= ./../bin/exe
#vpath %.o $(OBJDIR)
INCLUDES= -I./../include
CFLAGS= -Wall -c -I. $(INCLUDES)

objects= $(OBJDIR)/binary.o $(OBJDIR)/hex.o $(OBJDIR)/octal.o

$(EXEDIR)/conversion: $(objects)
#       gcc -Wall -o conversion $(objects) -I.

$(OBJDIR)/binary.o: $(VPATH)/binary.c $(INCLUDEDIR)/conversion.h
    gcc $(CFLAGS) $< -o $@

$(OBJDIR)/octal.o: $(VPATH)/octal.c $(INCLUDEDIR)/conversion.h
    gcc $(CFLAGS) $< -o $@

$(OBJDIR)/hex.o: $(VPATH)/hex.c $(INCLUDEDIR)/conversion.h
    gcc  $(CFLAGS) $< -o $@

clean:
    rm -rf $(OBJDIR)/*.o *.o *~ $(EXEDIR)/conversion

Upvotes: 1

Related Questions