Mayank
Mayank

Reputation: 2210

Without .PHONY target is getting built when a file named as target already exists in current directory

While going through MakeFiles I found that when the file named as target is present even then without using .PHONY, target is getting built. But when I am doing the same with another target i.e. clean, then target is not getting built and saying "clean is up-to-date" which is OK. I just want to know why the other target is getting built when the file exists in the current directory.

makefile:

CC:= gcc
CCFLAGS:=-Wall -Wextra
hello: hellomake.o hellofunc.o
        $(CC) $(CCFLAGS) hellomake.c hellofunc.c -o file
hellomake.o : hellomake.c
        $(CC) $(CCFLAGS) -c hellomake.c
hellofunc.o : hellofunc.c
        $(CC) $(CCFLAGS) -c hellofunc.c
clean:
        rm -rf *.o
        rm -rf file

My current directory has file named same as the target, as "hello". It should give result as "hello is up-to-date" but it is not doing it and giving the output as : make hello

gcc  -Wall -Wextra  hellomake.c hellofunc.c -o file 

Please tell why is this building the target when the TARGET IS NOT .PHONY AND THE FILE NAMED AS TARGET ALREADY EXISTS IN CURRENT DIRECTORY.

Upvotes: 4

Views: 1140

Answers (1)

enrico.bacis
enrico.bacis

Reputation: 31484

Because make looks at the last-modified times to decide what to build. From the make manual:

The make program uses the makefile database and the last-modification times of the files to decide which of the files need to be updated.

The command make examines the time relationships between the target and its prerequisites. If the prerequisites have been modified after the target it means that the target is out of date and the rebuild is triggered even if the file is present. So most likely your dependencies have been modified after the target.

In order to avoid this behavior, you can:

  • Use touch to change the target timestamp.
  • Use make -t hello or make --touch hello before invoking make hello. From the docs:
‘-t’
‘--touch’
Marks targets as up to date without actually changing them. In other words,
make pretends to update the targets but does not really change their
contents; instead only their modified times are updated.

Upvotes: 5

Related Questions