Skip to content

build: fix updated mod files not triggering recompiles#968

Open
VincentVanlaer wants to merge 1 commit intomainfrom
empty-recipe
Open

build: fix updated mod files not triggering recompiles#968
VincentVanlaer wants to merge 1 commit intomainfrom
empty-recipe

Conversation

@VincentVanlaer
Copy link
Copy Markdown
Member

make treats rules with no recipe different from rules with an empty recipe. The absence of a recipe conveys purely a dependency for the target. If however, there is no other recipe that actually updates the target, then make will not consider the target to be remade even if the dependencies have changed. Hence, any dependents of the target will not need to be remade according to make. The empty recipe fixes this, as make will consider the target to have a recipe, and thus will cause its dependents to also be remade.

Consider the following example (we use these type of dependency trees with ".anc" targets to handle fortran files producing multiple module files):

a.anc: a.f90
	... build commands ...

a.mod: a.anc

b.anc: b.f90 a.mod
	... build commands ...

b.mod: b.anc

If a.f90 gets updated with a change that also updates a.mod (for example, by changing something from private to public), it is necessary to also recompile b.f90. However, make does the following:

  1. Remake a.anc by executing the build comments
  2. Consider a.mod out of date
  3. No recipe for a.mod, consider it remade, but do not consider its timestamp updated
  4. Consider b.anc to be up-to-date as neither b.f90 nor a.mod have a timestamp newer than b.anc from make points of view, even though a.mod has a newer timestamp in reality.

By changing a.mod: a.anc to a.mod: a.anc ;, we now have recipe to remake a.mod (even though it doesn't do anything), make considers a.mod to be updated, and finally will remake b.anc.

make treats rules with no recipe different from rules with an empty
recipe. The absence of a recipe conveys purely a dependency for the
target. If however, there is no other recipe that actually updates the
target, then make will not consider the target to be remade even if the
dependencies have changed. Hence, any dependents of the target will not
need to be remade according to make. The empty recipe fixes this, as
make will consider the target to have a recipe, and thus will cause its
dependents to also be remade.

Consider the following example (we use these type of
dependency trees with ".anc" targets to handle fortran files producing
multiple module files):

```make
a.anc: a.f90
	... build commands ...

a.mod: a.anc

b.anc: b.f90 a.mod
	... build commands ...

b.mod: b.anc
```

If `a.f90` gets updated with a change that also updates `a.mod` (for
example, by changing something from `private` to `public`), it is
necessary to also recompile `b.f90`. However, make does the following:

1. Remake `a.anc` by executing the build comments
2. Consider `a.mod` out of date
3. No recipe for `a.mod`, consider it remade, but do not consider its
  timestamp updated
4. Consider `b.anc` to be up-to-date as neither `b.f90` nor `a.mod` have
  a timestamp newer than `b.anc` from make points of view, even though
  `a.mod` has a newer timestamp in reality.

By changing `a.mod: a.anc` to `a.mod: a.anc ;`, we now have recipe to
remake `a.mod` (even though it doesn't do anything), make considers
`a.mod` to be updated, and finally will remake `b.anc`.
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