2

如何使用两种不同的配置构建一组源文件,而无需重新构建所有内容?

我当前的设置添加了一个选项 --config=rel,它将从 build_rel.cfg 加载所有选项并将所有内容编译到 build_rel/ 目录。

data Flags = FlagCfg String                                                                                                                                
    deriving (Show, Eq)                                                                                                                                    

flags = [Option ['c'] ["config"]                                                                                                                           
                (ReqArg (\x -> Right $ FlagCfg x) "CFG")                                                                                                   
                "Specify which configuration to use for the build"]                                                                                                                                              

main :: IO ()                                                                                                                                              
main = shakeArgsWith shakeOptions { shakeChange=ChangeModtimeAndDigest }                                                                                   
                     flags $                                                                                                                               
                     \flags targets -> return $ Just $do                                                                                                   

    let buildDir = "build" ++                                                                                                                              
                   foldr (\a def -> case (a, def) of  
                              (FlagCfg cfg, "") -> '_':cfg
                              otherwise         -> def)                                                                                    
                    "" flags                                                                                                                            

    -- Settings are read from a config file.                                                                                                               
    usingConfigFile $ buildDir ++ ".cfg"
    ...

如果我再跑

build --config=rel
build --config=dev

我最终会得到两个版本

build_rel/
build_dev/

但是,每次我切换配置时,我最终都会重建所有内容。我猜这是因为我所有的神谕都“改变了”。我希望所有 oracles 都特定于我的两个不同的构建目录,以便更改不会干扰使用不同配置的构建之间。

我知道有一个 -m 选项可以指定数据库的存储位置,但我宁愿不必指定两个必须始终同步的选项。

build --config=rel -m build_rel

解析 --config 选项后有没有办法更新选项shakeFiles?

另一个想法是参数化我的所有 Oracle 以包含我的构建配置,但后来我注意到 usingConfigFile 使用 Oracle,我也必须重新实现它。看起来很笨重。

有没有其他方法可以构建多个目标而不必重建所有内容?这似乎是一件微不足道的事情,但我仍然无法弄清楚。

4

1 回答 1

1

有几个解决方案:

独立的数据库

如果您希望这两个目录完全不相关,并且它们之间没有共享任何内容,那么更改数据库也是最有意义的。目前没有“好的”方法可以做到这一点(传递两个标志,或者预解析一些命令行)。但是,添加应该很容易:

shakeArgsOptionsWith
    :: ShakeOptions
    -> [OptDescr (Either String a)]
    -> (ShakeOptions -> [a] -> [String] -> IO (Maybe (ShakeOptions, Rules ())))
    -> IO ()

然后,您可以从一个标志控制这两个设置。

单一数据库

如果你想要一个单一的数据库,你可以加载所有的配置文件,并指定像release.destination = ...and之类的配置debug.destination = ...,然后 rule for*/output.txt会根据规则的前缀查找配置,例如release/output.txt会查找release.destination。这里的优点是任何在调试和发布之间没有变化的东西(例如文档)都可能被共享。

于 2017-08-12T16:32:44.973 回答