I encounter an error relating to implicit rule in make (3.81). The example codes are:
dongli:test02 dongli$ ls -R
Makefile a.F90 b.F90 dir
./dir:
a.t.F90
The dependencies among the codes are:
a.t.F90: a.F90
a.t.o: a.t.F90
b.o: b.F90
b: a.t.o b.o
That is a.F90 is intermediate code, and a.t.F90 will be updated when a.F90 is updated. My make process is:
Test 1 (All codes on position):
-------------------------------------------------------------
Project: >>> test <<<
-------------------------------------------------------------
Creating dependency a.t.o
-------------------------------------------------------------
-----> ./dir/a.t.F90
Creating dependency b.o
-------------------------------------------------------------
-----> b.F90
Creating target 'b'
---> b is created.
-------------------------------------------------------------
Finished
-------------------------------------------------------------
Test 2 (touch a.F90):
dongli:test02 dongli$ touch a.F90
dongli:test02 dongli$ make
-------------------------------------------------------------
Project: >>> test <<<
-------------------------------------------------------------
Processing templates in a.F90
-------------------------------------------------------------
Creating dependency a.t.o
-------------------------------------------------------------
-----> a.t.F90
gfortran: error: a.t.F90: No such file or directory
gfortran: fatal error: no input files
compilation terminated.
make: *** [a.t.o] Error 1
Test 3: (Run make again):
dongli:test02 dongli$ make
-------------------------------------------------------------
Project: >>> test <<<
-------------------------------------------------------------
Creating dependency a.t.o
-------------------------------------------------------------
-----> ./dir/a.t.F90
Creating dependency b.o
-------------------------------------------------------------
-----> b.F90
Creating target 'b'
---> b is created.
-------------------------------------------------------------
Finished
-------------------------------------------------------------
I know there is a bug in make about directory caching (see here), but in my case, dir/a.t.F90 exists all the time. Any idea? Thanks!
Update1:
I use make -d to capture the following information in test 2:
Finished prerequisites of target file `a.t.F90'.
Prerequisite `a.F90' is newer than target `a.t.F90'.
Must remake target `a.t.F90'.
Ignoring VPATH name `./dir/a.t.F90'.
...
Successfully remade target file `a.t.F90'.
Finished prerequisites of target file `a.t.o'.
Prerequisite `a.t.F90' of target `a.t.o' does not exist.
Must remake target `a.t.o'.
Why ./dir/a.t.F90 is ignored when its prerequisite a.F90 is newer than it?
Update2:
I have put the example codes on gist.
Update3:
I found the following relating information:
If a target needs to be rebuilt, GNU make discards the file name found during the VPATH search for this target, and builds the file locally using the file name given in the makefile. If a target does not need to be rebuilt, GNU make uses the file name found during the VPATH search.