直到现在我有以下代码:
shakeArgsWith opts additionalFlags $ \flags targets -> return $ Just $ do
...
-- Get target arch from command line flags
let givenArch = listToMaybe [v | AFlag v <- flags]
let arch = fromMaybe defArch givenArch
...
-- Set the main target
let outName = masterOutName projType toolchain projName
let mainTgt = (case projType of
Binary _ -> "bin"
Archive -> "lib")
</> prettyShowArch arch
</> show variant
</> outName
-- Set the build directory for the current run
let buildDir = bldDir </> show toolchain </> prettyShowArch arch </> show variant
...
mainTgt %> \out -> do ...
...
buildDir <//> "*.o" %> \out -> do ...
...
表示根据我正在解析的命令行标志构造的规则名称(它们包含arch变量)。
所以,如果我给shake --arch=x64
我正在构建bin/x64/Release
目录中的主要目标,并相应地在tmp/x64/Release
文件夹中构建我的中间构建文件。
但现在不是使用命令行标志,而是希望用于构造规则名称的共享arch变量根据某个命令的输出进行填充,例如,如果我可以定义一些顶级操作,它将是这样的:
Stdout sout <- quietly $ cmd (EchoStdout False) (EchoStderr False) "gcc -dumpmachine" :: Action (Stdout String)
let foundArch = show (gccTripletToArch sout)
并在构造mainTgt
和buildDir
名称时使用变量foundArch而不是arch。显然这是无法做到的,因为即使是action
函数可以创建的唯一顶级规则也会返回Rule ()
。我该怎么办?
答案 0 :(得分:1)
我认为你应该可以做到:
form-group
Shake中的目标模式必须是静态知道的,因为这确保了快速重建的一些重要属性(您可以保证一个地方的变化具有可预测的效果)。但是,您可以运行命令来确定诸如arch,编译器版本等之类的内容。之前创建构建脚本并将其烘焙。
另一个观点是,您是基于arch动态生成的构建系统。使用Shake作为Haskell EDSL,这不是特别的问题,你可以说在使用命令行之前就已经这样做了。