交叉编译平台

Posted

技术标签:

【中文标题】交叉编译平台【英文标题】:Cross compile platforms 【发布时间】:2019-07-22 08:36:46 【问题描述】:

我想创建 sbt 跨平台(Hello world 应用程序),包括 JVM、Scala Native、android 和 scalajs,我已经成功编译了除 android 之外的所有这些,这是我的 build.sbt:

name := "Cross-Platforms-ScalaNative-JVM"

import sbtcrossproject.CrossPlugin.autoImport.crossProject, CrossType

val sharedSettings = Seq(scalaVersion := "2.11.12")

lazy val bar =
// select supported platforms
  crossProject(JSPlatform, JVMPlatform, NativePlatform)
    .crossType(CrossType.Full)
    .settings(sharedSettings)
    .jsSettings(
      libraryDependencies += "org.querki" %%% "jquery-facade" % "1.2") 
    .jvmSettings(/* ... */)
    .nativeSettings(/* ... */)

lazy val barJS     = bar.js
lazy val barJVM    = bar.jvm
lazy val barNative = bar.native

我的问题是如何在这个项目中创建一个 android 平台;我的 SBT 应该有哪些变化?

【问题讨论】:

【参考方案1】:

Android 构建基本上是一个带有额外步骤的 JVM 构建 - 获取 JVM 字节码,可选择运行 proguard 以最小化代码并将其编译为 Android 格式。

这里有很多关于如何在 sbt 中设置普通 android 构建的信息:https://scala-android.org/quickstart/。

区别在于仅将androidBuild(以及所有与 Android 相关的设置)应用于 JVM 项目:

val myProjectJVM = myProject.jvm
  .settings(androidBuild: _*)

但是,考虑到 Android 构建和普通 Scala 构建看起来会有所不同(因为普通 JVM 应用程序在架构上与 Android 应用程序几乎没有关系 - 例如 Main.main(Array[String]) 与 Android 片段和服务),最好有一个模块对于一些共享的 JVM 代码和平台特定部分的专用项目:

val commonJVM = myProject.jvm
val myProjectJVM = project.in(file("java-specific"))
  .dependsOn(commonJVM)
val myProjectAndroid = project.in(file("android-specific"))
  .settings(androidBuild)
  .dependsOn(commonJVM)

这种架构差异很可能是为什么没有人考虑让 Android 成为跨项目中的第四个选项的原因 - 你有不同的运行时依赖项,不同的启动应用程序的方式,所以你会有更多的代码部分不同于共同点。使用依赖于公共依赖(甚至是交叉编译的)的代码专用于平台的子模块是一个更好的主意。

【讨论】:

以上是关于交叉编译平台的主要内容,如果未能解决你的问题,请参考以下文章

交叉编译概述

ARM交叉编译工具链

交叉编译和交叉调试环境搭建及使用

[转] 什么是交叉编译(很好的入门文章)

交叉编译

Golang 交叉编译