摇动交叉编译?

Shake for cross-compilations?

我有一个构建两组目标的项目。一种是用于各种版本的手持设备的固件,最终为每个设备创建一个 .dfu 文件。这使用了arm编译链。另一组是为构建平台编译代码的相同设备的模拟器(好吧,通常无论如何)。我继承的 Makefile 在 cc != gcc 的任何环境中都不能很好地工作,因为将编译器传递到递归 makes 时存在问题。

我正在考虑重写 shake 中的构建文件,但想知道它如何处理想要做一个 "make release" 然后用不同的编译器或标志多次编译同一组源文件生成不同种类的二进制文件。这不是我以前遇到过的问题,而且根据我的 google 搜索,很多人都没有公开谈论过这个问题。

我不知道有人使用 Shake 进行交叉编译(虽然我想它会发生),但是很多人使用一个 Shake 脚本构建不同的配置,例如debug/profile/release,这需要大致相同的操作。通常的做法是将输出文件放在不同的目录中,并根据输出目录定义不同的规则(或相同的规则但参数化)。举个例子:

"release/arm//*.obj" *> \out -> command "arm-cc" ["source-file.c","-o",out]
"release/x86//*.obj" *> \out -> command "gcc" ["source-file.c","-o",out]

或者,您可以对每一个都有相同的规则,只需根据目录切换编译器:

"release//*.obj" *> \out ->
    let cc = if takeDirectory1 $ dropDirectory1 out == "arm" then "arm-cc else "gcc"
    command cc ["source-file.c","-o",out]

哪个效果最好通常取决于 arm 和 x86 是否大部分相同但切换了编译器,或者只是非常不同。

最后,您只需调用 want ["release/arm/install.tar.gz","release/x86/install.tar.gz"],Shake 将递归地同时创建两个版本。

也许看看 shake-language-c。它目前正在与移动和网络交叉编译工具链一起使用,但它应该直接与其他工具链接口。

下面是为 iOS 设备和模拟器编译静态库的示例:

import Control.Applicative
import Control.Arrow
import Control.Monad
import Development.Shake
import Development.Shake.FilePath
import Development.Shake.Language.C
import qualified Development.Shake.Language.C.Target.OSX as OSX

main :: IO ()
main = shakeArgs shakeOptions { shakeFiles = "build/" } $ do
  let -- Target the device and simulator
      targets = map (uncurry OSX.target)
                    [ (OSX.iPhoneOS, (Arm Armv7s))
                    , (OSX.iPhoneSimulator, (X86 I386)) ]

  -- Declare static library for each target
  libs <- forM targets $ \target -> do
    let toolChain = OSX.toolChain
                    <$> OSX.getSDKRoot
                    <*> (maximum <$> OSX.getPlatformVersions (targetPlatform target))
                    <*> pure target
    staticLibrary toolChain
          -- Unique name for each library target
          ("build" </> toBuildPrefix target </> "libexample.a")
          (return $ 
               append compilerFlags [(Just Cpp, ["-std=c++11"])]
           >>> append compilerFlags [(Nothing, ["-O3"])]
           >>> append userIncludes ["include"] )
          (getDirectoryFiles "" ["src//*.cpp"])

  -- Build them all
  want libs