如何使用shake将PHONY目标声明为默认动作



我正在将Makefile转换为Shakefile的过程中,我不确定如何处理PHONY make目标(clean, install等)。我试过这样写:

main = shake shakeOptions $ do
  want ["install"]
  "install" *> _ -> do
    need ["mytarget"]
    system' "ln" ["-s", "mytarget", "linkname"]

创建符号链接成功,但报告错误" error, rule "install" failed to build file: install"。

那么,如果没有使用"want"操作,我如何声明我想要运行的默认目标是假的呢?

在shake-0.10.1及以上版本中,您可以使用phony函数编写:

main = shake shakeOptions $ do
  want ["install"]
  phony "install" $ do
    need ["mytarget"]
    system' "ln" ["-s", "mytarget", "linkname"]

这应该完全符合您的要求,并且不需要生成假文件。此外,您可能希望使用shakeArgs而不是shake,以便用户可以从命令行中选择install,或者选择其他目标,例如clean.

在Shake -0.9及以下版本中,虚假目标是Shake的一个弱点——你可以这样做,但是它们比应该做的更冗长和手动。以下是一些选项:

让安装规则生成一个文件

作为一个非常简单的解决方案,只需在install规则的底部添加writeFile' "install" ""。这将生成一个虚拟文件,但每次mytarget更改时都会重新运行它。如果您希望每次请求install时都运行它(就像make中的伪代码一样),只需添加alwaysRerun即可。如果可以忽略冗余文件,这是最简单的解决方案,直到有一流的伪支持。

使用action

你可以写:

main = shake shakeOptions $ do
  action $ do
    need ["mytarget"]
    system' "ln" ["-s", "mytarget", "linkname"]

声明在每次构建中运行的操作。实际上,您可能只希望在命令行上运行install,因此您可以这样做:

main = do
  args <- getArgs
  shake shakeOptions $ do
    when ("install" `elem` args) $ action $ do
      ... install code ...

使用shakeArguments

在以后的shake版本中,你可以使用shakeArgsWith函数来写:

main = shakeArgsWith shakeOptions [] $ _ targets ->
  if "clean" `elem` targets then do
    removeFiles "_make" "//*"
    return Nothing
  else return $ Just $ do
    when ("install" `elem` targets) $ do
       ... install code ...
    ... other rules ...
    want $ delete "install" targets

这使您可以完全控制如何处理目标,因此您可以做一些比虚假目标更强大的事情,但它的工作量更大。

最新更新