diff --git a/README.md b/README.md index c0dec5d..2688902 100644 --- a/README.md +++ b/README.md @@ -249,7 +249,8 @@ generation in GNU make prints misleading messages (cf. e.g. bug 102). Sun make's `.make.state` file (that is used for hidden dependency and command dependency tracking) sometimes causes more harm than good - e.g. when outdated dependencies aren't removed -(e.g. when one converts a target group into a target list). +(e.g. when one converts a target group into a target list). Or when +include files are regenerated unconditionally (cf. `test/empty_cmd.mf`). The distributed make that comes with OpenOffice is [also named DMake][oodmake]. It seems that it was independently developed of Sun's diff --git a/test/empty_cmd.mf b/test/empty_cmd.mf new file mode 100644 index 0000000..5671456 --- /dev/null +++ b/test/empty_cmd.mf @@ -0,0 +1,103 @@ +# (A) +.KEEP_STATE: + +all: hello + +clean: + rm foo.x foo.y + +foo.x: + touch foo.x + +# <- workaround: disable command dependencies +# ?touch foo.x + +foo.y: foo.x + cat foo.x foo.x > foo.y + +# <- workaround: disable command dependencies +# ?cat foo.x foo.x > foo.y + +# (B) +include foo.y + + +hello: + echo hello + +# The perhaps unintuitive effect of `.KEEP_STATE` +# on the generation of include files. +# +# Effects: +# +# 1) comment out the line after (A) +# +# $ somake -f empty_cmd.mf clean +# rm foo.x foo.y +# $ rm .make.state +# $ somake -f empty_cmd.mf +# touch foo.x +# cat foo.x foo.x > foo.y +# echo hello +# hello +# $ somake -f empty_cmd.mf +# echo hello +# hello +# +# -> meaning that the include file foo.y is only updated +# if it doesn't exist or foo.x is newer. This is +# the expected behavior. +# +# 2) comment in (A) and comment out (B) +# +# $ somake -f empty_cmd.mf clean +# rm foo.x foo.y +# $ rm .make.state +# $ somake -f empty_cmd.mf foo.y +# touch foo.x +# cat foo.x foo.x > foo.y +# $ somake -f empty_cmd.mf foo.y +# `foo.y' is up to date. +# +# -> again, as expected the foo.y action is only executed once. +# +# 3) comment in (A) and (B) +# +# $ somake -f empty_cmd.mf clean +# touch foo.x +# cat foo.x foo.x > foo.y +# rm foo.x foo.y +# $ rm .make.state +# $ somake -f empty_cmd.mf +# touch foo.x +# cat foo.x foo.x > foo.y +# echo hello +# hello +# $ somake -f empty_cmd.mf +# touch foo.x +# cat foo.x foo.x > foo.y +# echo hello +# hello +# +# -> this is unexpected because foo.y is generated each time. +# This is caused by an interaction between KEEP_STATE and +# include. Make reads in the `.make.state` file after +# include directives are being processed. But, as part of the +# dependency checking of the include files the usual KEEP_STATE +# logic is applied such that make assumes that the foo.y action +# command changed from '' (empty) to 'cat foo.x foo.x > foo.y'. +# +# (make basically looks up the 'old' command in an empty database) +# +# When calling make with `-d` the log contains messages like: +# +# different from empty old command +# Building foo.x because new command longer than old +# Building foo.y because new command longer than old +# +# A workaround is to disable command dependencies for the involved +# actions, i.e. `?touch foo` and `?cat foo.x foo.x > foo.y` +# +# This is a bug. +# +