2

在我的 Makefiles 中,我更喜欢由环境变量定义输出目录,而不是硬编码(如果未设置,则使用一些合理的默认值)。例如,Make 规则看起来像

$(OUTPUT_DIR)/some_file: deps
     #build commands

我还没有弄清楚如何在 Shake 中实现类似的目标。我喜欢用getEnvWithDefault它来获取环境变量的值或合理的默认值,但是没有多少用绑定或 lambda 来抨击它让我可以将它与(*>).

怎么可能在 FilePattern 中插入环境变量以用于(*>)?

4

1 回答 1

1

该函数getEnvWithDefaultActionmonad 中运行,并且必须在您无法访问Actionmonad 的上下文中提供规则的名称,因此您无法按照您尝试的方式翻译此模式。有几种选择:

选项 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消除这种风险,但通常是不必要的。

于 2014-09-07T20:19:17.640 回答