Shake 不识别是否构建 rule/always 构建规则,即使它不应该
Shake does not recognize wether to build a rule/always builds a rule even if it shouldn't
我有一个项目,我使用 shake 生成一堆基于输入文件的报告,运行 作为一个 restful 网络服务。我选择 Shake 的原因之一是,如果输入文件未更改(例如,基于 Digest,可通过 shakeOptions
配置),则不应重建任何内容。
我注意到这些进程会 运行 即使我刚刚构建它们并且在 运行 之间没有文件更改。所以我尝试了一个简单的例子,它应该模拟我的一个构建过程
import Control.Monad.IO.Class
import Development.Shake
wanted = "foo.3"
main = shake shakeOptions $ do
want [wanted] -- (1)
"*.1" %> \out -> do -- (2)
liftIO $ putStrLn out
unit $ cmd Shell "touch" "foo.2"
"*.2" %> \out -> do need [out] -- (3)
unit $ cmd "touch" wanted
action $ unit $ cmd Shell "touch" wanted -- (4)
虽然 %>
规则从不 运行 - action
规则始终有效。
如果我注释掉 (4) 并手动创建文件 "foo.1" - 规则 (1) 失败,因为它无法确定 (2) -> (3) 可以构建结果。
如果另一方面我注释掉 (2) 和 (3) 并保留 (4) - 即使 "foo.3" 存在并且已经 "built" 规则 运行s通过之前摇一摇。
我将 shake-0.15.11 与 shake 结合使用 - 使用 shake runhaskell Main.hs --package shake
或 shake exec -- testshake
没有任何区别。编译器是 GHC-8.0.2。所有这些都是在 Linux(薄荷)上完成的。
我读了 How does Shake decide whether to rebuild a target? - 我从中了解到,只有当输入文件或输出文件发生变化(其中变化由 shakeOptions
配置决定)时,shake 才会重建内容)
首先,pat %> act
意味着您创建文件构建规则,对于任何文件路径 都将是 运行 将接受模式 pat
。这意味着如果有人调用 need [foo]
和 pat ?== foo
那么将是 运行 带有参数 foo
的操作 act
。因此,操作 act
应该尝试构建 foo
.
其次,关于 action
,如文档中所写:
The action will be run in every build execution (unless withoutActions is used).
和wand
定义如下:want = action . need
.
例如,我根据关于文件之间依赖关系的一些假设重新设计了您的示例。即,foo.3 需要 foo.2,foo.2 需要 foo.1 并且 foo.1 已经存在(它是来源)。
wanted = "foo.3"
main = shake shakeOptions $ do
want [wanted]
"*.3" %> \out -> do
putNormal out
need [out -<.> ".2"]
unit $ cmd Shell "touch" out
"*.2" %> \out -> do
putNormal out
need [out -<.> ".1"]
unit $ cmd Shell "touch" out
我有一个项目,我使用 shake 生成一堆基于输入文件的报告,运行 作为一个 restful 网络服务。我选择 Shake 的原因之一是,如果输入文件未更改(例如,基于 Digest,可通过 shakeOptions
配置),则不应重建任何内容。
我注意到这些进程会 运行 即使我刚刚构建它们并且在 运行 之间没有文件更改。所以我尝试了一个简单的例子,它应该模拟我的一个构建过程
import Control.Monad.IO.Class
import Development.Shake
wanted = "foo.3"
main = shake shakeOptions $ do
want [wanted] -- (1)
"*.1" %> \out -> do -- (2)
liftIO $ putStrLn out
unit $ cmd Shell "touch" "foo.2"
"*.2" %> \out -> do need [out] -- (3)
unit $ cmd "touch" wanted
action $ unit $ cmd Shell "touch" wanted -- (4)
虽然 %>
规则从不 运行 - action
规则始终有效。
如果我注释掉 (4) 并手动创建文件 "foo.1" - 规则 (1) 失败,因为它无法确定 (2) -> (3) 可以构建结果。
如果另一方面我注释掉 (2) 和 (3) 并保留 (4) - 即使 "foo.3" 存在并且已经 "built" 规则 运行s通过之前摇一摇。
我将 shake-0.15.11 与 shake 结合使用 - 使用 shake runhaskell Main.hs --package shake
或 shake exec -- testshake
没有任何区别。编译器是 GHC-8.0.2。所有这些都是在 Linux(薄荷)上完成的。
我读了 How does Shake decide whether to rebuild a target? - 我从中了解到,只有当输入文件或输出文件发生变化(其中变化由 shakeOptions
配置决定)时,shake 才会重建内容)
首先,pat %> act
意味着您创建文件构建规则,对于任何文件路径 都将是 运行 将接受模式 pat
。这意味着如果有人调用 need [foo]
和 pat ?== foo
那么将是 运行 带有参数 foo
的操作 act
。因此,操作 act
应该尝试构建 foo
.
其次,关于 action
,如文档中所写:
The action will be run in every build execution (unless withoutActions is used).
和wand
定义如下:want = action . need
.
例如,我根据关于文件之间依赖关系的一些假设重新设计了您的示例。即,foo.3 需要 foo.2,foo.2 需要 foo.1 并且 foo.1 已经存在(它是来源)。
wanted = "foo.3"
main = shake shakeOptions $ do
want [wanted]
"*.3" %> \out -> do
putNormal out
need [out -<.> ".2"]
unit $ cmd Shell "touch" out
"*.2" %> \out -> do
putNormal out
need [out -<.> ".1"]
unit $ cmd Shell "touch" out