views:

371

answers:

3

I have a makefile that looks like this

CXX = g++ -O2 -Wall

all: code1 code2

code1: code1.cc utilities.cc
   $(CXX) $^ -o $@

code2: code2.cc utilities.cc
   $(CXX) $^ -o $@

What I want to do next is to include 'clean target' so that every time I run 'make' it will automatically delete the existing binary files of code1 and code2 before creating the new ones.

I tried to put these lines at the very end of the makefile, but it doesn't work

clean: 
    rm -f $@
    echo Clean done

What's the right way to do it?

+6  A: 

In makefile language $@ means "name of the target", so rm -f $@ translates to rm -f clean.

You need to specify to rm what exactly you want to delete, like rm -f *.o code1 code2

qrdl
+7  A: 

The best thing is probably to create a variable that holds your binaries:

binaries=code1 code2

Then use that in the all-target, to avoid repeating:

all: clean $(binaries)

Now, you can use this with the clean-target, too, and just add some globs to catch object files and stuff:

.PHONY: clean

clean:
    rm -f $(binaries) *.o

Note use of the .PHONY to make clean a pseudo-target. This is a GNU make feature, so if you need to be portable to other make implementations, don't use it.

unwind
+1 for `.PHONY` (which is a GNU-ism, but Mostly Harmless elsewhere). However, it's a bad idea to put `clean` as a dependency of `all`; that increases build time and noise. Better to define all the *real* dependencies so that changes to source get propagated exactly as far as necessary.
Donal Fellows
+2  A: 

By the way it is written, clean rule is invoked only if it is explicitly called:

make clean

I think it is better, than make clean every time. If you want to do this by your way, try this:

CXX = g++ -O2 -Wall

all: clean code1 code2

code1: code1.cc utilities.cc
   $(CXX) $^ -o $@

code2: code2.cc utilities.cc
   $(CXX) $^ -o $@

clean: 
    rm ...
    echo Clean done
Alex Farber
As qrdl explained, this is wrong. "rm -f $@" becomes "rm -f clean", which would not work.
bjarkef
No downvote, but usually this is a bad idea. Anything but a very small project takes some time to build from scratch, and you really don't want to have to wait that long every time you have made a small change.
Thomas Padron-McCarthy
bjarkef: right, I just answered to the part of auto-delete. Thomas Padron-McCarthy: agree, and this is written in my post.
Alex Farber