Harsh February 2016

Why does 'touch' ing makefile along with all source file does not rebuild anything? How can I solve this?

I have some source files like file1, file2 and file3 and a Makefile:

tar: file1 file2 file3
    @echo hello

Now when I touch file1, it rebuilds file1 and tar.

But when I touch all source files and Makefile, it does not rebuild anything. It should rebuild all source files. Why so?

Simple solution is I touch all file but Makefile, but it becomes difficult when I have say 20 source files. What is the solution?

Answers


Dan Lowe February 2016

The way make works is to compare the timestamp on the target and the source(s). The general format of the rule is:

target: source(s)
    action(s)        

In this case, when you run make, it will look at the target's timestamp (tar) and ask whether that timstamp is older than the timestamp of any source (file, file2, file3). If the target is older than any of the sources, then it is considered out of date, which triggers the rule's action(s) to run.

The problem is that this rule doesn't do anything except to echo output. After it runs, tar still has the same timestamp it had before. The next time you run make, it will do exactly the same thing, because the starting condition (the timestamps) did not change.

You can make this work as expected by having the rule touch the tar file as one of its actions.

tar: file1 file2 file3
    @touch tar
    @echo hello

Now it should behave as expected.

$ make
make: `tar' is up to date.
$ touch file3    
$ make
hello
$ make
make: `tar' is up to date.

Of course, in a typical Makefile, your rule would do more than echo. If it is building something, normally the target of the rule (in this case tar) is modified as a result of the build action, so explicitly using touch is not usually required.

Post Status

Asked in February 2016
Viewed 3,355 times
Voted 8
Answered 1 times

Search




Leave an answer