Search code examples
makefile

Makefile using directory structure for source and object files - 2


First of all, Sorry I have reposted this question, Since earlier post question was not upto the mark.. and i don't want to delete it since users have replied to the post

Here is my Folder Structure :

Project : Makefile, final.hex
|- Src : one.c two.c
|- Obj : one.o two.o

Here is my Makefile :

TARGET = final.hex
CC = gcc
SRCDIR = Src
OBJDIR = Obj

SRC = one.c two.c
OBJS = $(OBJDIR)/one.o $(OBJDIR)/two.o

CFLAGS = -c 
LFLAGS = -Wl

.PHONY: all

all: $(TARGET)

$(TARGET): $(OBJS)
        @echo ****** TARGET ********
    @echo Target.hex created


$(OBJS): %.o: $(SRCDIR)/%.c
    $(CC) $(CFLAGS) $< -o $@
    @echo ****** OBJS ********
    @echo $@
    @echo $<

When I tried to run makefile it gives an error : make: *** No rule to make target Src/Obj/one.c', needed by Obj/one.o'. Stop.

The question is there any method or another solution where we can tell makefile to look into $(SRCDIR) for *.c files for compilation even though *.o files to be remain in $(OBJDIR)

Note: I'm new to the world of Makefile & Stackoverflow

The question is there any method or another solution where we can tell makefile to look into $(SRCDIR) for *.c files for compilation even though *.o files to be remain in $(OBJDIR)

Note: I'm new to the world of Makefile & Stackoverflow


Solution

  • You simply have to look at the expansion of the variables and how they match the pattern. Let's look at what your makefile says:

    $(OBJS): %.o: $(SRCDIR)/%.c
    

    This will expand to this:

    Obj/one.o Obj/two.o: %.o: Src/%.c
    

    When make matches Obj/one.o with %.o, the stem (%) will be Obj/one of course.

    Then make will substitute that stem into Src/%.c so you get Src/Obj/one.c. That is not what you want.

    You want the stem (the part that matches the %) to be just the file name with no directory: one. So, you have to write your rule to make that so. Use:

    $(OBJS): $(OBJDIR)/%.o: $(SRCDIR)/%.c
    

    This expands to:

    Obj/one.o Obj/two.o: Obj/%.o: Src/%.c
    

    and now when make matches Obj/one.o with Obj/%.o, the stem matches just one and so the prerequisite will be Src/one.c which is what you want.