• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

[Dart翻译]交叉编译Dart应用程序

武飞扬头像
Sunbreak
帮助3

发布时间:2020年9月21日 - 4分钟阅读

Dart是一种很好的现代编程语言,它不仅可以编译成JavaScript,还可以被AOT编译成本地独立的可执行文件。

dart.dev/platforms

在构建Dart SDK时,人们可以轻松选择所需的目标架构,如X64和/或ARM。尽管人们可以通过这种方式对整个SDK进行交叉编译,但不幸的是,作为SDK一部分的dart2native编译器并不支持交叉编译。为了将Dart代码编译成本地ARM二进制文件,人们必须在目标上运行编译器,这不是我们正在寻找的解决方案。

学新通

问题是,要使dart2native能够在X64主机上为Raspberry Pi交叉编译ARM二进制文件,需要做些什么?好吧,让我们先看看编译器实际做了什么。从源代码中我们可以看到,它。

  1. 生成一个AOT内核。
  2. 生成一个AOT快照,并且
  3. 将结果与Dart AOT运行时相结合。

GitHub上有一个很好的wiki页面,总结了Dart中不同类型的快照。它解释说,内核快照与CPU架构无关,而AOT快照可以用Dartotruntime运行。

当涉及到dart2native时,上面列出的步骤1和2只是调用外部命令,或多或少都是这样的。

<sdk>/bin/dart <sdk>/bin/snapshots/gen_kernel.dart.snapshot \
               --platform <sdk>/lib/_internal/vm_platform_strong_product.dill \
               --aot \
               -Ddart.vm.product=true \
               -o <tmp>/kernel.dill \
               <source>.dart

生成AOT内核(gen_kernel)

<sdk>/bin/utils/gen_snapshot --snapshot-kind=app-aot-elf \
                             --elf=<tmp>/snapshot.aot \
                             <tmp>/kernel.dill

生成AOT快照(gen_snapshot)

另一方面,第3步不是执行外部命令,而是以编程方式附加a)步骤1-2产生的快照和b)Dart AOT运行时间。作为参考,这里是一个AOT编译的Dart可执行文件的最终结构。

学新通

Dart AOT可执行文件 - 结构

值得注意的是,最后一步,将最终的应用程序快照与AOT运行时合并,是可选的。它只有在编译完全独立的可执行文件时才需要。另外,人们可以直接用AOT运行时执行AOT快照,它本身就是一个可执行文件。这样,人们可以为多个Dart应用程序共享同一个AOT运行时,这可能是首选,以便在资源有限的系统中节省磁盘空间。如果你想知道这在实践中是如何运作的,请仔细看看你的Dart SDK的bin-directory. ;)


现在我们知道了dart2native在引擎盖下的作用,我们可以开始修补,看看是否可以在X64上产生ARM二进制文件。正如前面指出的,AOT内核与CPU架构无关,所以我们使用哪个Dart SDK的gen_kernel工具并不重要。让我们假设我们已经有一个为X64构建的Dart SDK。

# sdk (x64)
$ ./tools/build.py -a x64 -m product create_sdk

对于下一步,我们需要一个gen_snapshot工具,能够在X64主机架构上执行,并为ARM目标架构产生AOT快照。这并不像听起来那么复杂,因为你可以简单地为一个名为SIMARM的目标架构建立工具,以实现这一目标。

# gen_snapshot (simarm)
$ ./tools/build.py -a simarm -m product copy_gen_snapshot

注意,我们不一定需要构建整个SDK,因为我们只需要gen_snapshot工具。最后但同样重要的是,我们需要一个适用于ARM目标架构的dartaotruntime二进制文件。

# dartaotruntime (arm)
$ ./tools/build.py -a arm -m product copy_dartaotruntime

出于好奇,让我们快速检查一下目前得到的情况。

$ file out/ProductX64/dart-sdk/bin/dart2native 
[...]/dart2native: Bourne-Again shell script, [...]
$ file out/ProductX64/dart-sdk/bin/dart
[...]/dart: ELF 64-bit LSB shared object, x86-64, [...]
$ file out/ProductSIMARM/dart-sdk/bin/utils/gen_snapshot
[...]/gen_snapshot: ELF 32-bit LSB executable, Intel 80386, [...]
$ file out/ProductXARM/dart-sdk/bin/dartaotruntime
[...]/dartaotruntime: ELF 32-bit LSB shared object, ARM, [...]

如你所见,dart2native实际上只是一个执行各自快照的脚本。尽管如此,看起来我们有32位的gen_snapshot,它应该能够为ARM生成AOT快照,而且我们也有一个用于ARM的dartaotruntime。 在这一点上,我们基本上掌握了所有必要的构件。我们可以手动执行gen_kernel gen_snapshot,读取dartaotruntime,最后手工编写可执行文件,但这并不是那么简单,因为这不仅仅是附加两个文件的问题,而是需要包括正确的填充、快照偏移和一个神奇的数字。目前阻碍我们用dart2native工具做这件事的原因是,它不允许我们指定我们要使用的gen_snapshot和dartaotruntime,而是相对于dart2native查找它们。因此,我准备了一个简单的dart2native补丁,让我们可以从外部指定这两个。

github.com/jpnurmi/dar…

用上述补丁重建dart2native后,我们准备开始测试交叉编译。为了测试,我们将使用以下一小段Dart代码,从/proc/cpuinfo读取并打印CPU模型。

import 'dart:io';

void main() {
  final lines = File('/proc/cpuinfo').readAsLinesSync();
  final model = lines.firstWhere((line) => line.startsWith('model name'));
  print(model.split(':').last.trim());
}

Dart测试片段

结果,终于!

$ DART2NATIVE_X64=out/ProductX64/dart-sdk/bin/dart2native
$ GEN_SNAPSHOT_SIMARM=out/ProductSIMARM/dart-sdk/bin/utils/gen_snapshot
$ DARTAOTRUNTIME_XARM=out/ProductXARM/dart-sdk/bin/dartaotruntime

# x64
$ $DART2NATIVE_X64 cpu.dart -o cpu_x64
Generated: [...]/cpu_x64
$ file cpu_x64
cpu_x64: ELF 64-bit LSB shared object, x86-64, [...]
$ ./cpu_x64 
Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz

# arm
$ $DART2NATIVE_X64 cpu.dart --gen-snapshot $GEN_SNAPSHOT_SIMARM --aot-runtime $DARTAOTRUNTIME_XARM -o cpu_arm
Generated: [...]/cpu_arm
$ file cpu_arm
cpu_arm: ELF 32-bit LSB shared object, ARM, [...]
# on rpi
pi@raspberrypi:~ $ ./cpu_arm 
ARMv7 Processor rev 3 (v7l)

它成功了! :)

如果你想让这个问题更容易解决,请在GitHub上为以下问题竖起大拇指。👍

github.com/dart-lang/s…


通过www.DeepL.com/Translator(免费版)翻译

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanheggaki
系列文章
更多 icon
同类精品
更多 icon
继续加载