kancler
kancler

Reputation: 101

makefile: warning: overriding recipe for target 'build'

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

Answers (1)

MadScientist
MadScientist

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

Related Questions