如何在震动中构建变体?

时间:2015-10-05 18:20:33

标签: shake-build-system

如何在摇动中传递参数然后在我们的规则中使用它们?我想做一些相当于:

make ARCH=x86_64

make DEBUG=YES 等...

目前我一直在使用环境变量和getEnv功能来模拟这些。
如何依赖于给定的参数(环境变量),以便可以在构建中读取一次,将其存储在某个位置并从多个规则访问它?

e.g。现在我在多个规则中多次执行getEnv,但在编译时,环境变量可以改变。另外,例如,调试标志可以改变编译器和链接器标志,这意味着需要在链接和编译输出规则中提供信息。

1 个答案:

答案 0 :(得分:1)

您现有的使用环境变量的方法应该有效,并且由于Shake已经跟踪了环境变量,因此一种方法是解析DEBUG=YES并将其转换为环境变量。例如:

main = shakeArgsWith shakeOptions [] $ \_ args -> do
    let (vars,files) = partition ('=' `elem`) args
    forM_ vars $ \v -> let (a,'=':b) = break (== '=') v in setEnv a b
    return $ Just $ if null files then rules else want files >> withoutActions rules

rules :: Rules ()
rules = ...

由于环境变量是进程(及其子进程)的本地变量,因此这可能会正常工作。

当然,将这些信息存储在环境变量中有点难看。您可以创建自己的oracle来存储信息:

main = shakeArgsWith shakeOptions [] $ \_ args -> do
    let (vars,files) = partition ('=' `elem`) args
    let vars2 = [(a,b) | v <- vars, let (a,'=':b) = break (== '=') v]
    return $ Just $ do
        global <- addOracle $ \(Global x) -> return $ lookup x vars2
        if null files then rules global else want files >> withoutActions (rules global)

newtype Global = Global String deriving (Show,Typeable,Eq,Hashable,Binary,NFData)

rules :: (Global -> Action (Maybe String)) -> Rules ()
rules global = undefined

现在,我们不是将信息写入带有setEnv的环境变量,而是将其存储在带有addOracle的oracle中,它仍将被跟踪,并且不会与任何其他环境变量块冲突。