0
votes

I am trying to compile a c program with gnu make, so that the objective files created are put in a Build directory. My project directory look like this:

| root
|--> makefile
|--> BuildDir
|--> HeadersDir
|    -> main.h
|    .
|    .
|--> Modules
|    -> modules1.c
|    .
|    .
|--> Program
|    -> program1.c
|    .
|    .

And I want all objective files created from Modules and Program source files to get saved inside BuildDir. So far I have this makefile

CC = gcc
CFLAGS = -Wall -Wextra -g3 -I./HeaderFiles
LDFLAGS = -lm

# Get all source files
SRCFILES := $(wildcard ./Programs/*.c)
SRCFILES += $(wildcard ./Modules/*.c)

# Generate objective files
OBJFILES = $(patsubst %.c, %.o, $(SRCFILES))
OBJFILES := $(subst ./Programs, ./Build, $(OBJFILES))
OBJFILES := $(subst ./Modules, ./Build, $(OBJFILES))

EXEC = travelMonitor
PARAMETERS =

all: $(OBJFILES) $(EXEC)

%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@

$(EXEC): $(OBJFILES)
    $(CC) $(CFLAGS) $(OBJFILES) -o $@

and that outputs:

make: *** No rule to make target 'Build/mainFunctions.o', needed by 'all'.  Stop.

Can anyone help?

1

1 Answers

0
votes

This rule:

%.o: %.c

says how to build a .o from a .c. The rule can ONLY match if both the target matches the pattern AND the prerequisites exist or can be built. So does this rule match?

Well, for a target Build/mainFunctions.o it does match the pattern, with a stem (the part that matches the %) of Build/mainFunctions. Given that stem, what is the prerequisite? We have %.c so after substitution of the stem make wants to build the prerequisite Build/mainFunctions.c. Does that exist? No. Does make know how to make it? No. So, this pattern rule doesn't match. Make will look for any other pattern rules that might match, but there are none. So, make tells you it can't find any way to create this target.

If you want to put the object files in different directories then you have to encode that into your rule, else make can't know which rule to use; you'd have to write this as:

Build/%.o : Programs/%.c
        $(CC) $(CFLAGS) -c $< -o $@

Now of course this won't build Modules sources so you need another rule for that:

Build/%.o : Modules/%.c
        $(CC) $(CFLAGS) -c $< -o $@

Now it will work.