Reputation: 35
I am trying to create a framework where each folder in the source directory becomes a library. I haven't gotten to the .d dependencies yet, I am stuck trying to get the LLIST
(library list) expansion to work.
My makefile is as follows:
# Directories
OBJDIR = obj
TGTDIR = target
INCDIR = include
SRCDIR = src
TSTDIR = tests
LIBDIR = lib
DEPDIR = .d
DIRS = $(OBJDIR) $(TGTDIR) $(INCDIR) $(LIBDIR) $(DEPDIR)
# Target name
TGT = caffeine
LLIST = utils middleware
OBJS := $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(wildcard $(SRCDIR)/**/*.c))
INCS := $(patsubst $(SRCDIR)/%.h, $(INCDIR)/%.h, $(wildcard $(SRCDIR)/**/*.h))
.PHONY: all
all: $(TGTDIR)/$(TGT)
$(TGTDIR)/$(TGT): $(LIBDIR)/$(LLIST).so
touch $@
$(LIBDIR)/$(LLIST).so: $(OBJDIR)/$(LLIST)/%.o
touch $@
$(OBJDIR)/$(LLIST)/%.o: $(SRCDIR)/$(LLIST)/%.c
touch $@
.PHONY: folders
folders:
mkdir -p $(DIRS)
.PHONY: clean
clean:
rm -rf $(DIRS)
The error I'm receiving is.
makefile:35: *** mixed implicit and normal rules: deprecated syntax
Which is this line.
$(OBJDIR)/$(LLIST)/%.o: $(SRCDIR)/$(LLIST)/%.c
To add for clarity the folder structure is as follows.
src
|-utils
|-utils.h
|-utils.c
|-hash.c
|-json.c
|-middleware
|-middleware.h
|-middleware.c
|-req.c
|-res.c
Upvotes: 1
Views: 418
Reputation: 100781
Well, what does that line expand to?
OBJDIR = obj
TGTDIR = target
SRCDIR = src
LIBDIR = lib
TGT = caffeine
LLIST = utils middleware
$(TGTDIR)/$(TGT): $(LIBDIR)/$(LLIST).so
...
$(LIBDIR)/$(LLIST).so: $(OBJDIR)/$(LLIST)/%.o
...
$(OBJDIR)/$(LLIST)/%.o: $(SRCDIR)/$(LLIST)/%.c
...
expands this way. which is obviously not right:
target/caffeine: lib/utils middleware.so
...
This says that the target target/caffeine
has two prerequisites: the first is lib/utils
and the second is middleware.so
. I expect that's not what you wanted.
lib/utils middleware.so: obj/utils middleware/%.o
...
This is not actually a pattern rule: a pattern rule MUST have a pattern matching character (%
) in the target. This creates two targets, lib/utils
and middleware.so
, and each one depends on two prerequisites: obj/utils
and the literal file named middleware/%.o
(because this is not a pattern rule).
obj/utils middleware/%.o: src/utils middleware/%.c
...
This tries to create an explicit rule for the target obj/utils
and the pattern rule for the pattern middleware/%.o
in the same rule, which is illegal and that's why make complains.
In short, you can't just create a variable with multiple words in it, like LLIST = utils middleware
, then plop that variable down into the middle of things and expect make to somehow do some type of iteration over those words and create multiple rules, or whatever. That's not how variable expansion works in a makefile: the variable is simply expanded and the results are parsed exactly as if you'd written the makefile without variables at all.
Upvotes: 3