摇一摇:如何在调用时设置环境变量?

时间:2018-11-30 23:48:28

标签: haskell command-line-arguments shake-build-system

在Makefile中,可以引用在调用make时在命令行中设置的参数。例如,规则中的配方可能包含命令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$

2 个答案:

答案 0 :(得分:3)

当你说

make subsample subsample_size=0.1

您使用两个参数调用makesubsamplesubsample_size=0.1,并且在相同的环境中,其余的Shell处于其中。make识别出{{1} }的格式为subsample_size=0.1,并将其解释为宏定义。这样做恰好与设置环境变量具有相同的效果。 Shake不支持在命令行上进行定义,因此您必须实际上设置一个环境变量。

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

stack exec

在调用ev="Hello World!" stack exec ./build.sh echoEnvVar 期间设置ev环境变量。您也可以使用export builtin

答案 1 :(得分: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
    ...