Mono Cross Platform AOT (Ahead Of Time) compiling

2019-08-09 07:22发布

问题:

After compiling my Mono application on the host (x86-64) I have to copy the resulting executable to my target (AARCH64).

On the target I have to run mono with the '--aot' option to improve run time performance. That's anoying, since I have to do that for every target device.

Is it possible to run AOT compilation on the host for the target in a cross-compile maner?

Best regards

-Carsten

Update:

  • It is possible to run a cross plattform command with qemu. E.g. for ARM: http://tuxthink.blogspot.com/2012/04/executing-arm-executable-in-x86-using.html
  • On Yocto there is a convenience macro 'qemu_run_binary' that can be called from a post-installation script.

The problem is that 'mono --aot' executes 'as' (and may be ld also):

...
Executing the native assembler: "as"   -o /tmp/mono_aot_ENXWoc.o /tmp/mono_aot_ENXWoc
...

I think that must be directed to the cross compile versions e.g. arm-linux-gnueabi-as, ... . I did not find out yet how to do that. I will take a look on the mono code later to find that out.

Update: Reading the code

https://github.com/mono/mono/blob/8ec9b12e53e4c0f7ab3fde48ebadf20cdb4bff1b/mono/mini/aot-compiler.c

and the man page

https://www.systutorials.com/docs/linux/man/1-mono

suggests that the following option is supported:

--aot=tool-prefix=arch64-linux- 

Update:

The above 'tool-prefix' option is not enough. Mono has to be build as a cross tool using '--host' and '--target' configure options. Otherwise assembler code for the host architecture is generated:

# mono --aot=full,tool-prefix=aarch64-linux- src/helloworld.exe 
Mono Ahead of Time compiler - compiling assembly 
/home/behlingc/projects/.../helloworld.exe
AOTID 240451E8-B522-2A5C-2EC4-7D49CE189CF7
Code: 30(6%) Info: 5(1%) Ex Info: 24(4%) Unwind Info: 17(3%) Class Info: 30(6%) 
PLT: 10(2%) GOT Info: 264(52%) Offsets: 120(24%) GOT: 216
Compiled: 2/2 (100%), No GOT slots: 1 (50%), Direct calls: 0 (100%)
Executing the native assembler: "aarch64-linux-as" -o 
/tmp/mono_aot_5J2dOf.o /tmp/mono_aot_5J2dOf
/tmp/mono_aot_5J2dOf: Assembler messages:
/tmp/mono_aot_5J2dOf:140: Error: unknown mnemonic `call' -- `call .Lp_1'
/tmp/mono_aot_5J2dOf:156: Error: unknown mnemonic `call' -- `call .Lm_0'
/tmp/mono_aot_5J2dOf:157: Error: unknown mnemonic `call' -- `call .Lm_1'
/tmp/mono_aot_5J2dOf:158: Error: unknown mnemonic `call' -- `call 
method_addresses'
/tmp/mono_aot_5J2dOf:236: Error: unknown mnemonic `jmp' -- `jmp 
*mono_aot_helloworld_got+208(%rip)'
/tmp/mono_aot_5J2dOf:253: Error: junk at end of line, first unrecognized 
character is `0'
AOT of image src/helloworld.exe failed.

From monos() configure.ac:

...
if test "x$host" != "x$target"; then
   AC_DEFINE(MONO_CROSS_COMPILE,1,[The runtime is compiled for cross-compiling mode])
...
   case "$target" in
   ...
      aarch64*-linux-*)
                  TARGET=ARM64;
                  ;;
   ...

Update:

Works with 'Cross Mono' (Extracted from my Yocto build):

aarch64-pxc-linux-mono --aot=full,tool-prefix=aarch64-pxc-linux- bin/Debug/*.exe

Result:

Mono Ahead of Time compiler - compiling assembly /home/behlingc/projects/hmi-next/build-pxc/tmp-pxc-glibc/work/aarch64-pxc-linux/dual-can-test-tool/1.0-r0/<myapp>/bin/Debug/<myapp>.exe
AOTID 80A21DF5-6E8C-5D14-9C6C-F40370586870
Code: 73100(83%) Info: 1273(1%) Ex Info: 5459(6%) Unwind Info: 626(0%) Class Info: 3367(3%) PLT: 183(0%) GOT Info: 3113(3%) Offsets: 691(0%) GOT: 4168
Compiled: 57/57 (100%), No GOT slots: 21 (36%), Direct calls: 8 (38%)
Executing the native assembler: "aarch64-pxc-linux-as"   -o /tmp/mono_aot_dlEBox.o /tmp/mono_aot_dlEBox
Executing the native linker: "aarch64-pxc-linux-ld"  -shared -o /home/behlingc/projects/hmi-next/build-pxc/tmp-pxc-glibc/work/aarch64-pxc-linux/dual-can-test-tool/1.0-r0/DualCan_WIN32_Komplett_GUI_640x480/bin/Debug/DualCan_WIN32_Komplett_GUI_640x480.exe.so.tmp  /tmp/mono_aot_dlEBox.o 

JIT time: 19 ms, Generation time: 10 ms, Assembly+Link time: 32 ms. DEBUG: Shell function do_compile finished

标签: mono yocto