该函数getEnvWithDefault
在Action
monad 中运行,并且必须在您无法访问Action
monad 的上下文中提供规则的名称,因此您无法按照您尝试的方式翻译此模式。有几种选择:
选项 1:lookupEnv
调用前使用shake
要完全匹配 Make 的行为,您可以编写:
main = do
outputDir <- fromMaybe "output" <$> lookupEnv "OUTPUT_DIR"
shakeArgs shakeOptions $ do
(outputDir </> "some_file") *> \out -> do
need deps
-- build commands
这里我们使用lookupEnv
函数 (from System.Environment
) 在开始运行 Shake 之前获取环境变量。然后我们可以定义一个与环境变量精确匹配的文件。
选项 2:不要在规则中强制输出
或者,我们可以定义一个构建规则,some_file
无论它在哪个目录中,然后getEnvWithDefault
在我们说要构建哪个文件时使用 tracked :
main = shakeArgs shakeOptions $ do
"//some_file" *> \out -> do
need deps
-- build commands
action $ do
out <- getEnvWithDefault "OUTPUT_DIR"
need [out </> "some_file"]
在这里,规则模式可以构建任何东西,调用者选择输出应该是什么。我更喜欢这种变体,但如果some_file
模式以某种方式重叠,您可能会遇到名称冲突的风险很小。引入一个唯一的名称,因此所有输出都被命名为$OUTPUT_DIR/my_outputs/some_file
消除这种风险,但通常是不必要的。