Reputation: 101
I have a very simple makefile:
#Compiler flags
CC := gcc
INCLDIR := -I./includes
#Directories and files
BUILDDIR := ./build
STLIB := $(BUILDDIR)/libbinary_tree.a
$(BUILDDIR)/binary_tree.o: ./source_files/binary_tree.c | $(BUILDDIR)
$(CC) -c $< $(INCLDIR) -o $@
$(BUILDDIR):
mkdir $(BUILDDIR)
.PHONY: build
build: $(BUILDDIR)/binary_tree.o
ar -rcs $(STLIB) $(BUILDDIR)/binary_tree.o
What I want to do:
with the command make build
make from ./source_files/binary_tree.c
./build/binary_tree.o
and create a static library from it. If ./build
doesn't exist - create the folder.
But I get some warnings:
makefile:17: warning: overriding recipe for target 'build'
makefile:13: warning: ignoring old recipe for target 'build'
make: Circular build/binary_tree.o <- build dependency dropped.
ar -rcs ./build/libbinary_tree.a ./build/binary_tree.o
If I change in my file build to build2:
...
PHONY: build2
build2: ...
then make build2
works without warning.
How can this be achieved using make build
command?
Upvotes: 2
Views: 6414
Reputation: 100781
You have this:
BUILDDIR := ./build
$(BUILDDIR):
mkdir $(BUILDDIR)
build: $(BUILDDIR)/binary_tree.o
ar -rcs $(STLIB) $(BUILDDIR)/binary_tree.o
After variables are expanded make sees this:
./build:
mkdir $(BUILDDIR)
build: ./build/binary_tree.o
ar -rcs $(STLIB) $(BUILDDIR)/binary_tree.o
Make ignores initial ./
, so these two targets are the same. That's why you get this error.
You can do one of the following:
First, rename the target you use to build things: it's always wrong to write a rule in make that tells make it will create one thing (in this case, build
) but actually creates something else (in this case, $(STLIB)
). This rule should be written:
$(STLIB): $(BUILDDIR)/binary_tree.o
ar -rcs $@ $^
Of you want to have a simple rule to build it, add one like this:
all: $(STLIB)
Or second, if you have to have a rule named build
(not all
as in my example) rename your directory containing built objects, from build
to obj
or something.
Or finally, don't use the order-only prerequisite method to create the build
directory, so that you don't need to create a rule for it. For example:
$(BUILDDIR)/binary_tree.o: ./source_files/binary_tree.c
mkdir -p $(@D)
$(CC) -c $< $(INCLDIR) -o $@
Upvotes: 5