Unreliable parallel builds in a makefile with .INTERMEDIATE?

元气小坏坏 提交于 2019-12-06 01:38:41

The SO answer you link to has an error; surprising that so many people have apparently used it with success.

What's happening (you can add the -rRd options to your make invocation to see in more detail) is a result of GNU make's directory caching. GNU make doesn't expect the filesystem state to change in any way other than what your makefile describes, and so it caches the contents of directories to provide a significant performance increase (for large makefiles/directories).

Basically, when make runs the rule:

out.intermediate: in
        touch out1 out2

it doesn't expect that this recipe will update any targets other than the one listed in the rule: out.intermediate. If the other files out1 and out2 are already internalized in the directory cache (which they will be since they exist and we've already checked them as prerequisites to out3), then make won't go back to the filesystem and see if they've been updated or not: make "knows" they can't have changed because no rule that it ran could have changed them, according to the makefile.

There's a simple, one-character fix to make all this work. Change this line:

out1 out2: out.intermediate

to this:

out1 out2: out.intermediate ;

If you want to be more explicit you could also use this:

out1 out2: out.intermediate
        @:

or even this, for debugging:

out1 out2: out.intermediate
        @echo Do nothing

What all these have in common is that you've now defined not just a dependency relationship between the targets and prerequisite, but you've also given a recipe that make should invoke for that rule. Even if the recipe is empty (as in the first example), so make doesn't actually run any commands, make will still infer that it's possible that the timestamps on out1 and/or out2 have changed, and it will invalidate the cached modified time for those targets and re-retrieve them from the filesystem.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!