如何根据外部因素构建规则名称?

时间:2015-11-12 13:43:27

标签: shake-build-system

直到现在我有以下代码:

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)

并在构造mainTgtbuildDir名称时使用变量foundArch而不是arch。显然这是无法做到的,因为即使是action函数可以创建的唯一顶级规则也会返回Rule ()。我该怎么办?

1 个答案:

答案 0 :(得分:1)

我认为你应该可以做到:

form-group

Shake中的目标模式必须是静态知道的,因为这确保了快速重建的一些重要属性(您可以保证一个地方的变化具有可预测的效果)。但是,您可以运行命令来确定诸如arch,编译器版本等之类的内容。之前创建构建脚本并将其烘焙。

另一个观点是,您是基于arch动态生成的构建系统。使用Shake作为Haskell EDSL,这不是特别的问题,你可以说在使用命令行之前就已经这样做了。