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.