最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • [Dart翻译]交叉编译Dart应用程序

    正文概述 掘金(Sunbreak)   2021-05-27   1064

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

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

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

    问题是,要使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
    
    <sdk>/bin/utils/gen_snapshot --snapshot-kind=app-aot-elf \
                                 --elf=<tmp>/snapshot.aot \
                                 <tmp>/kernel.dill
    

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

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

    值得注意的是,最后一步,将最终的应用程序快照与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补丁,让我们可以从外部指定这两个。

    用上述补丁重建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());
    }
    

    结果,终于!

    $ 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上为以下问题竖起大拇指。?


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


    起源地下载网 » [Dart翻译]交叉编译Dart应用程序

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元