并行处理多个构建配置
Handling multiple build configurations in parallel
如何使用两种不同的配置构建一组源文件而不必重建所有内容?
我当前的设置添加了一个选项 --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/
但是,每次我切换配置时,我最终都会重建所有内容。我猜这是因为我所有的神谕都有 "changed"。我希望所有 oracles 都特定于我的两个不同的构建目录,这样更改就不会干扰使用不同配置的构建。
我知道有一个 -m 选项可以指定数据库的存储位置,但我不想指定必须始终同步的两个选项。
build --config=rel -m build_rel
有没有办法在解析 --config 选项后更新选项 shakeFiles?
另一个想法是参数化我所有的 Oracles 以包括我的构建配置,但后来我注意到 usingConfigFile 使用 Oracle,我也必须重新实现它。看起来很笨重。
是否有其他方法可以构建多个目标而无需重建所有内容?这似乎是一件微不足道的事情,但我还是想不通。
有几种解决方法:
独立数据库
如果您希望这两个目录完全无关,它们之间没有任何共享,那么更改数据库也是最有意义的。目前没有 "good" 方法来做到这一点(要么传递两个标志,要么预先解析一些命令行)。但是,添加应该很容易:
shakeArgsOptionsWith
:: ShakeOptions
-> [OptDescr (Either String a)]
-> (ShakeOptions -> [a] -> [String] -> IO (Maybe (ShakeOptions, Rules ())))
-> IO ()
这样您就可以通过一个标志控制这两个设置。
单一数据库
如果你想要一个单一的数据库,你可以加载所有配置文件,并指定像 release.destination = ...
和 debug.destination = ...
这样的配置,然后 */output.txt
的规则将根据以下内容查找配置规则的前缀,例如release/output.txt
会查找 release.destination
。这里的优点是任何在调试和发布之间没有改变的东西(例如文档)都可以共享。
如何使用两种不同的配置构建一组源文件而不必重建所有内容?
我当前的设置添加了一个选项 --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/
但是,每次我切换配置时,我最终都会重建所有内容。我猜这是因为我所有的神谕都有 "changed"。我希望所有 oracles 都特定于我的两个不同的构建目录,这样更改就不会干扰使用不同配置的构建。
我知道有一个 -m 选项可以指定数据库的存储位置,但我不想指定必须始终同步的两个选项。
build --config=rel -m build_rel
有没有办法在解析 --config 选项后更新选项 shakeFiles?
另一个想法是参数化我所有的 Oracles 以包括我的构建配置,但后来我注意到 usingConfigFile 使用 Oracle,我也必须重新实现它。看起来很笨重。
是否有其他方法可以构建多个目标而无需重建所有内容?这似乎是一件微不足道的事情,但我还是想不通。
有几种解决方法:
独立数据库
如果您希望这两个目录完全无关,它们之间没有任何共享,那么更改数据库也是最有意义的。目前没有 "good" 方法来做到这一点(要么传递两个标志,要么预先解析一些命令行)。但是,添加应该很容易:
shakeArgsOptionsWith
:: ShakeOptions
-> [OptDescr (Either String a)]
-> (ShakeOptions -> [a] -> [String] -> IO (Maybe (ShakeOptions, Rules ())))
-> IO ()
这样您就可以通过一个标志控制这两个设置。
单一数据库
如果你想要一个单一的数据库,你可以加载所有配置文件,并指定像 release.destination = ...
和 debug.destination = ...
这样的配置,然后 */output.txt
的规则将根据以下内容查找配置规则的前缀,例如release/output.txt
会查找 release.destination
。这里的优点是任何在调试和发布之间没有改变的东西(例如文档)都可以共享。