1

在 Makefile 中,可以引用调用时在命令行中设置的参数make。例如,规则中的配方可能包括 command python/subsample.py $(subsample_size),在命令行中通过键入类似make subsample subsample_size=0.1.

我想对shake. 我写了以下规则:

phony "echoEnvVar" $ do
    ev <- fromMaybe "undefined" <$> getEnv "ev"
    liftIO $ putStrLn ev

问题在于shake将变量的命令行定义ev视为另一个目标:

jeff@jeff-ThinkCentre-M700:~/shake-studies$ stack exec  ./build.sh echoEnvVar ev=whatever
Error when running Shake build system:
* ev=whatever
Error, file does not exist and no rule available:
  ev=whatever
CallStack (from HasCallStack):
  error, called at src/Development/Shake/Internal/Rules/File.hs:180:58 in shake-0.16.4-7UipAYwzJlKKX7fQ0hMQ1b:Development.Shake.Internal.Rules.File

如果我改为在没有命令行参数的情况下调用该规则,它将按预期运行:

jeff@jeff-ThinkCentre-M700:~/shake-studies$ stack exec  ./build.sh echoEnvVar
undefined
Build completed in 0:01m
jeff@jeff-ThinkCentre-M700:~/shake-studies$
4

2 回答 2

3

当你说

make subsample subsample_size=0.1

make使用两个参数调用:subsamplesubsample_size=0.1,并且使用相同的环境,您的 shell 的其余部分位于。make识别subsample_size=0.1具有形式var=value,并将其解释为宏定义。这样做恰好与设置环境变量具有相同的效果。Shake 不支持在命令行上进行定义,因此您必须实际设置环境变量。

您为 Shake 设置环境变量的方式将取决于您用于执行 Shake 的程序。您正在通过build.sh. 假设这不会做任何太有趣的事情,脚本会将自己的环境原封不动地传递给 Shake。您正在调用build.shthrough stack exec,它将从其自己的环境中传递您的变量,并且不会更改(但它确实会更改某些其他变量)。您正在stack exec通过自己的 shell 调用。假设它是一个 POSIX shell,你可以写

ev="Hello World!" stack exec ./build.sh echoEnvVar

ev在调用期间设置环境变量stack。您也可以使用export内置的.

于 2018-12-02T02:46:44.363 回答
1

如果您想要的是一个环境变量,那么@HTNW 的答案就是正确的。

如果您真正想要的是程序中可用的配置选项,那么您可以使用shakeArgsWith. 举个例子:

import System.Console.GetOpt

flags = [Option "" ["subsample_size"] (ReqArg readEither) "Set the subsample size (in %)."]

main = shakeArgsWith shakeOptions flags $ \flags targets -> return $ Just $ do
    -- now flags will contain a list of the passed subsample_size values
    ...
于 2018-12-02T15:49:12.597 回答