我有一个项目可以构建两组目标。一种是用于各种版本的手持设备的固件,最终为每个设备创建.dfu文件。这使用了arm编译链。另一组是用于编译构建平台代码的那些相同设备的模拟器(通常,无论如何)。我继承的Makefiles在cc!= gcc的任何环境中都不能正常工作,因为将编译器传递给递归制作会出现问题。
我正在考虑在摇动中重写构建文件,但是想知道它是否可以处理想要进行“发布”的问题。然后,使用不同的编译器或标志多次编译同一组源文件,以生成不同类型的二进制文件。我之前没有遇到任何问题,根据我的谷歌搜索,并没有很多人公开谈论过。
答案 0 :(得分:2)
我没有意识到人们使用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将立即递归创建两个版本。
答案 1 :(得分:2)
也许看看shake-language-c。它目前正在与移动和Web交叉编译工具链一起使用,但它应该直接与其他工具链接口。
以下是为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