Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added restat = 1 in the fortran dyndep example #2275

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Volker-Weissmann
Copy link

@Volker-Weissmann Volker-Weissmann commented Mar 20, 2023

Let's say you have a Fortran Project consisting of two files:

$ cat foo.f90
module foo
  implicit none
  integer, parameter :: rkind=SELECTED_REAL_KIND(15,307)

  contains
     function myProcessing(x) RESULT(z)
	    real(kind=rkind):: x,z

	 end function myProcessing
end module foo
$ cat bar.f90
program main
  use foo
  implicit none
  real(kind=rkind) :: val, res

  res = myProcessing(val)
end program main

If you do it like the manual suggests, you run into a problem:

$ cat build.ninja 
rule f95
  command = f95 -o $out -c $in
rule fscan
  command = echo -e "ninja_dyndep_version = 1\nbuild foo.o | foo.mod: dyndep\nbuild bar.o: dyndep | foo.mod" > $out
build foobar.dd: fscan foo.f90 bar.f90
build foo.o: f95 foo.f90 || foobar.dd
  dyndep = foobar.dd
build bar.o: f95 bar.f90 || foobar.dd
  dyndep = foobar.dd
$ ninja
[3/3] f95 -o bar.o -c bar.f90
$ ninja
ninja: no work to do.
$ touch foo.f90 
$ ninja
[3/3] f95 -o bar.o -c bar.f90
$ ninja -v -d explain
ninja explain: loading dyndep file 'foobar.dd'
ninja explain: output foo.mod older than most recent input foo.f90 (1679308368472041273 vs 1679308373408688040)
ninja explain: foo.mod is dirty
[1/2] f95 -o foo.o -c foo.f90
[2/2] f95 -o bar.o -c bar.f90
$ ninja -v -d explain
ninja explain: loading dyndep file 'foobar.dd'
ninja explain: output foo.mod older than most recent input foo.f90 (1679308368472041273 vs 1679308373408688040)
ninja explain: foo.mod is dirty
[1/2] f95 -o foo.o -c foo.f90
[2/2] f95 -o bar.o -c bar.f90

As you can see ninja rebuilds stuff even though nothing should get rebuild. The last two ninja calls should have printed ninja: no work to do..

I did some debugging and found that the following build.ninja file has the same problem:

rule f95
  command = f95 -o $out -c $in
build foo.o | foo.mod: f95 foo.f90
build bar.o: f95 bar.f90 | foo.mod

But why? The build.ninja file looks so correct!
The problem lies in the assumption that f95 -o foo.o -c foo.f90 will generate foo.mod. This is only half-true:

$ rm parent.mod
$ f95 -o foo.o -c foo.f90
$ stat foo.mod 
Access: 2023-03-20 11:36:14.018192964 +0100
Modify: 2023-03-20 11:36:14.018192964 +0100
Change: 2023-03-20 11:36:14.018192964 +0100
 Birth: 2023-03-20 11:36:14.018192964 +0100
$ f95 -o foo.o -c foo.f90
$ stat foo.mod 
Access: 2023-03-20 11:36:18.184855010 +0100
Modify: 2023-03-20 11:36:14.018192964 +0100
Change: 2023-03-20 11:36:14.018192964 +0100
 Birth: 2023-03-20 11:36:14.018192964 +0100
$ f95 -o foo.o -c foo.f90
$ stat foo.mod 
Access: 2023-03-20 11:36:18.184855010 +0100
Modify: 2023-03-20 11:36:14.018192964 +0100
Change: 2023-03-20 11:36:14.018192964 +0100
 Birth: 2023-03-20 11:36:14.018192964 +0100

As you can see, the fortran compiler indeed created foo.mod. But it does not update the modification time of foo.mod if it already does exist. If I insert a restat

build foo.o | foo.mod: f95 foo.f90
    restat = 1

everything seems to work.

I'm using gfortran 12.2.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant