Monday, January 24, 2011

.PHONY

For a long time, I used to look at .PHONY targets in makefiles and wonder how useful those targets were. Today, I found the usefulness while playing with prelink (more on prelink later).

I created the following files and folders while doing this:

[root@sarin prelink]#ls -l
total 20
drwxr-xr-x 2 root root 4096 2011-01-24 11:14 bin
drwxr-xr-x 2 root root 4096 2011-01-24 11:14 lib
-rw-r--r-- 1 root root   57 2011-01-24 10:41 libutil.c
-rw-r--r-- 1 root root  273 2011-01-24 11:14 Makefile
-rw-r--r-- 1 root root  343 2011-01-24 10:56 prelink.c
[root@sarin prelink]#cat Makefile
all: bin

lib: libutil.c
        gcc -shared -Wl,-soname,libutil.so -o lib/libutil.so libutil.c

bin: lib prelink.c
         gcc -L/root/c/prelink/lib prelink.c -Wl,-rpath,lib -lpthread -lutil -o bin/prog

clean:
        rm -f lib/libutil.so bin/prog

Now, I did a make clean and did a make. Nothing happened. I got the message that "make: Nothing to be done for `all'.". If you notice, in the make file, target all had a dependency on 'bin'. Target 'bin' was dependent on target 'lib'. So, I was expecting that lib will be built first and then bin. But, It did not even try to build bin (I verified this by putting an echo in bin). After a long struggle, I found the reason.

As you can see, 'bin' and 'lib' were the names of two folders inside the current directory. So, make assumed that targets 'bin' and 'lib' where those folders. As these sub-folders were already present in the current folder,  it assumed that there is nothing to be done for target all.

This is the issue that .PHONY target fixes. It clearly tells make to avoid looking at files and folders for these names. I added the following line to the top of the makefile.

.PHONY: all bin lib
Thats it,  I was able to compile the program using my makefile!

No comments: