前言
.NET8的AOT为了支持各个平台,比如MacOS,Linux等平台,ILC(AOT Compiler)的目标文件用的是LLVM生成的。本篇看下。
原文:.NET8 AOT与LLVM什么关系?
公众号:jianghuht,欢迎关注
详述
为了更为细致的让大家了解LLVM在AOT里面的作用,这里用一个例子演示下。以下以最新版的.NET8.0/windows11为蓝本演示。
第一步:在nuget上面下载一个ILC组件,名称:runtime.win-x64.Microsoft.DotNet.ILCompiler
第二步:找到这个包在你当前电脑的路径,一般为如下,这个路径有个objwriter.dll:
C:UsersAdministrator.nugetpackagesruntime.win-x64.microsoft.dotnet.ilcompiler8.0.0tools
第三步:操作objwriter.dll
新建一个.NET8控制台应用程序,把这个objwriter.dll放入到控制台bin/x64/debug/net8.0目录下。Main写入如下代码:
[DllImport("objwriter.dll")]
private static extern IntPtr InitObjWriter([MarshalAs(UnmanagedType.LPUTF8Str)] string objectFilePath, string triple = null);
[DllImport("objwriter.dll")]
private static extern void FinishObjWriter(IntPtr objWriter);
[DllImport("objwriter.dll")]
private static extern void EmitIntValue(IntPtr objWriter, ulong value, int size);
private IntPtr _nativeObjectWriter = IntPtr.Zero;
static void Main(string[] args)
{
IntPtr objectWriter = InitObjWriter("Demo.obj", "x86_64-pc-win32-windows");
EmitIntValue(objectWriter, 0x10, 4);
FinishObjWriter(objectWriter);
}
objwriter.dll通过LLVM_Project项目构建,应用于.NET8 ILC AOT里面。
以上代码运行之后,就会在控制台的bin/x64/debug/net8.0目录下面看到生成的目标文件Demo.obj。这个就是ILC调用LLVM生成的当前Windows平台(InitObjWriter的参数:x86_64-pc-win32-windows表示的是Windows目标文件)上面的目标文件,此后通过引导程序BootStrap(关于.NET8 AOT引导程序参考:.Net8的AOT引导程序BootStrap)链接下,即可生成独立的可执行文件。
以上就是LLVM在.NET8 AOT里面的简单应用。
题外话
微软从.NET7.0开始,就有意识的分离.NET里面的各个耦合度极高的组件。举个例子,比如说在.NET Framework里面GC和CLR分离是不可想象的,但是在.NET8.0里面,GC不仅和CLR分离,JIT也可以和CLR分离。进行独自定制。这些.NET核心组件通过动态链接库,也即是DLL的形式分发出来,可以让开发人员进行自由定制。
这里稍微列举下:
1.ILC的可移植性目标文件组件:objwriter.dll(本文所述)
2.分离的可定制GC组件:clrgc.dll(参考:自定义GC垃圾回收)
3.分离的可定制JIT组件:clrjit.dll(参考:自定义JIT即时编译)
4.分离的可定制CLR组件:coreclr.dll(参考:目前空白)
5.可自定义的运行时宿主组件:hostfxr.dll(参考:自定义宿主组件)
以上都可以进行自由定制,你在各个平台上(MacOS/Linux)看到的动态链接库DLL,都是有自定制进行各种平台的自由分发,比如国内外大热的Risc-V支持的新平台,比如国内的Arm64指令集平台等。