Shake build system 如何根据外部因素构造规则名称?

Shake build system 如何根据外部因素构造规则名称?,shake-build-system,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

到目前为止,我有以下代码:

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 ...
    ...

在构造
mainTgt
buildDir
名称时,使用变量foundArch代替arch。显然,这是无法做到的,因为即使是使用
操作
函数创建的唯一顶级规则也会返回
规则()
。我能做些什么呢?

我想你应该能做到:

shakeArgsWith opts additionalFlags $ \flags targets -> do
     Stdout sout <- cmd (EchoStdout False) (EchoStderr False) "gcc -dumpmachine"
     let arch = show (gccTripletToArch sout)
     return $ Just $ do
         let buildDir = bldDir </> show toolchain </> prettyShowArch arch </> show variant
         ...
         buildDir <//> "*.o" %> \out -> do ...
shakeArgsWith选择additionalFlags$\flags targets->do
标准输出\out->do。。。
Shake中的目标模式必须是静态已知的,因为这确保了快速重建的一些重要属性(您可以保证在一个地方进行更改会产生可预测的效果)。但是,在创建构建脚本之前,您可以运行命令来确定诸如arch、编译器版本等内容,并将它们烘焙进来


另一个观点是,您是基于arch动态生成一个构建系统的。使用Shake作为Haskell EDSL没有什么特别的问题,可以说您以前是通过命令行这样做的。

所以我想您的答案是在生成构建脚本之前检测arch(在shakeArgsWith之前在main中执行正常操作)?问题是,对于您的代码片段,我得到的
无法将预期的类型'IO(Stdout String)'与实际的类型'Action(Stdout String)
匹配。。我也曾想过做同样的事情,但使用这种解决方案,我失去了shake提供的预构建动作函数的功能。我悄悄地删除了
-它现在可以工作了吗
cmd
非常灵活,可以在
操作
IO
中使用。在
Action
中,它做了一些额外的事情,与Shake lint和profiling等集成,但在IO中也可以正常工作。显然,我们最终需要删除类型说明符(::Action(Stdout String))并且它可以工作!我会不会在没有安静的情况下过度打印?谢谢,现在已修复-我需要一个更宽的显示器!打印是
cmd
的Action Monad实例的一部分,因此在
IO
版本中不会发生。
shakeArgsWith opts additionalFlags $ \flags targets -> do
     Stdout sout <- cmd (EchoStdout False) (EchoStderr False) "gcc -dumpmachine"
     let arch = show (gccTripletToArch sout)
     return $ Just $ do
         let buildDir = bldDir </> show toolchain </> prettyShowArch arch </> show variant
         ...
         buildDir <//> "*.o" %> \out -> do ...