2

我想在我的项目中找到所有的“Makefile”,然后根据它们生成规则。但是,看起来(故意)没有什么可以逃脱动作。因此,我在摇动功能之前将我的“Makefile”扫描仪提升到了 IO 操作。

main = do
  makefiles <- findMakefiles
  shake skakeOptions $ generate_rules makefiles

有没有更好的办法?

4

1 回答 1

1

首先,我认为目前的方法没有任何问题。Shake 包本身对内置的 Ninja 和 Makefile 解释器使用类似的方法,请参阅有关 Makefile 解释器Sake 解释器的详细信息。只要处理 Makefile 足够快(通常是这样),那么您基本上是在使用 Shake 为您的自定义构建语法编写一个解释器,它工作得很好。

有几个原因可以避免这种方法,例如,如果 Makefile 的处理成本很高,或者 Makefile 本身有其他依赖项。在这种情况下,您可以使用组合newCache来解析 Makefile 一次,addOracle因此规则可以取决于它们所需的 Makefile 子集。但是,这种方法很难正确,因为它基本上强制了一个间接层,并且您必须对如何generate_rules工作做出一些假设。ghc-make包使用这种技术(参见“makefile”规则和调用newCache),usingConfigFileShake 包中的函数使用相同的newCache/addOracle模式。

坚持原来的方法,您可以在某些地方稍有不同findMakefiles。你可以做:

main = shakeArgsWith shakeOptions [] $ \_ -> xs -> do
    makefiles <- findMakefiles
    let rules = generate_rules makefiles
    if null xs then rules else withoutActions rules >> want xs

这样做的好处是您可以轻松添加命令行标志来确定在哪里可以找到 Makefile,或处理它的选项。Shake 中的 Ninja 和 Makefile 系统都支持这一点,--makefile=FILE用于覆盖默认值。即使您不想 move generate_rules,您也可能希望在原始示例中替换shakeshakeArgs,这将为您提供命令行处理。

于 2014-08-18T07:00:13.627 回答