Shake无法识别构建规则/总是建立规则,即使它不应该

时间:2017-05-04 14:22:31

标签: haskell shake-build-system

我有一个项目,我使用shake来生成一堆基于输入文件的报告,并作为一个宁静的Web服务运行。我选择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”存在并且之前已经“摇摆”,规则也会运行。

我使用shake-0.15.11结合摇动 - 使用shake runhaskell Main.hs --package shakeshake exec -- testshake没有任何区别。编译器是GHC-8.0.2。所有这些都是在Linux(Mint)上完成的。

我读了How does Shake decide whether to rebuild a target? - 只有当输入文件或输出文件发生变化(其中变化由shakeOptions配置确定)时,我才从中收集震动重建内容< / p>

1 个答案:

答案 0 :(得分:1)

首先,pat %> act表示您创建了文件构建规则,该规则将针对将使用模式pat接受的任何文件路径运行。这意味着,如果有人调用need [foo]pat ?== foo,那么将使用参数act运行操作foo。因此,操作act应该尝试构建foo

其次,关于action,如文档中所述:

  

该操作将在每次构建执行中运行(除非使用了withoutActions)。

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