我正在将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
这使您可以完全控制如何处理目标,因此您可以做一些比虚假目标更强大的事情,但它的工作量更大。