Reputation: 550
I'm writing a makefile
for a very small personal project written in C.
My project is divided into subdirectories, but the directives for these utilme are not found even if (I think) the code is right:
TARGET = example.out
ENV = /usr/bin/env
MKDIR = mkdir
RMV = rm
CP = cp
CC = gcc
CFLAGS = -lm
BINDIR = ./bin
OBJDIR = ./obj
SRCDIR = ./src
SRCS = master.o request/request.o util/util.o # these are all .c files (./src/...)
# ---
.PHONY: build
build: prepare $(SRCS)
$(ENV) $(CC) $(addprefix $(OBJDIR)/, $(SRCS)) -o $(BINDIR)/$(TARGET)
# ---
.PHONY: prepare
prepare:
@$(ENV) $(MKDIR) -p $(BINDIR) $(OBJDIR)
@$(ENV) $(CP) data.txt $(BINDIR)/data.txt
# ---
.PHONY: clean
clean:
@$(ENV) $(RM) -rf $(BINDIR) $(OBJDIR)
# ---
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(ENV) $(CC) $(CFLAGS) -c $<
It says:
make: *** No rule to make target 'master.o', needed by 'build'. Stop.
And if I change $(OBJDIR)/%.o: $(SRCDIR)/%.c
to %.o: $(SRCDIR)/%.c
, it says:
make: *** No rule to make target 'request/request.o', needed by 'build'. Stop.
Upvotes: 0
Views: 59
Reputation: 2103
You have effectively no rule to create master.o
from master.c
.
In the following rule:
$(OBJDIR)/%.o: $(SRCDIR)/%.c
./obj/%.o
does not match master.o
And if master.c
is in src
(as indicated by the comment) the default rules don't match either.
So in order to match the rule, the target must be ./obj/master.o
The same goes for all the other .o files and you will run into trouble with the subdirectories. To get around that you can create the target directory in the recipe directly:
$(OBJDIR)/%.o: $(SRCDIR)/%.c
mkdir -p $(dir $@)
$(CC) -c -o $@ $(CFLAGS) $<
Upvotes: 2
Reputation: 533
the default behaviour of gcc is to place the .o-file beneath the .c-file. to place it into the object file directory, you have to use an -o $@
argument:
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(ENV) $(CC) $(CFLAGS) -c $< -o $@
And the build rule shoud depend on $(addprefix $(OBJDIR)/, $(SRCS))
if this is what is used in the command.
build: prepare $(addprefix $(OBJDIR)/, $(SRCS))
$(ENV) $(CC) $(addprefix $(OBJDIR)/, $(SRCS)) -o $(BINDIR)/$(TARGET)
Upvotes: 0