.Net NativeAOT另外一种选择-bflat

https://www.qiufengblog.com/articles/dotnet-native-bflat.html

 

前言

说起bflat,还得先说NativeAOT,在.Net 7时,正式把NativeAOT合到Runtime中,地位是明显上升了,对NativeAOT的代码提交也越来越多了,之前还是corert时,几年也没有太大的进展.

这个时候的成果还是有ILC(ILCompiler),这时候国外的大佬,将C#带入了系统编程,就是zerosharp,zerosharp有三个示例.
  1. no-runtime: 不依赖CoreCLR运行时,限制比较多,使用值类型,加P/Invoke的方式,调用系统API,没有太多的依赖.
  2. with-runtime: 有CoreCLR运行时,可以完全使用托管和非托管及GC,生成Native原生的dll/lib,让C/C++调用
  3. efi-no-runtime: 可以让C#编写的程序,在没有系统的裸机上运行,当然也是有限制的,限制和no-runtime一样.
zerocsharp是依赖的ILC的,所以使用有一点麻烦,于是做zerocsharp的大佬,又开了一个项目,就是bflat,将ILC/.Net(.Net 7)及zerocsharp整合到一起,只需要配置一下环境变量,就可以使用了.这一点比NativeAOT使用要简单(当然这也是暂时的,下面会说是什么)

bflat生成Native原生程序

#zerocsharp地址
https://github.com/MichalStrehovsky/zerosharp.git

#bflat官网地址:
https://flattened.net/

#bflat github地址:
https://github.com/bflattened/bflat

下面看看如何使用:

#使用echo 将System.Console.WriteLine("Hello World");保存到hello.cs中
echo 'System.Console.WriteLine("Hello World");' > hello.cs

#使用bflat 编译hello.cs 为Windows可执行程序
bflat build .\hello.cs --os:windows

看一下生成的可执行程序文件大小:

bflat生成native原生程序的大小

查看生成独立程序所以的动态库:

bflat生成native原生程序依赖系统动态库

bflat生成Native原生程序,不依赖CoreCLR,没有GC

#只需要加上 --stdlib:zero  --stdlib有三个参数 <DotNet|None|Zero> 
bflat build .\hello.cs --os:windows --stdlib:zero

看文件大小和系统依赖项:

bflat生成native原生程序时,使用zero依赖时依赖系统动态库

说一下.Net 8 NativeAOT

NativeAOT在.Net 8改进依然是很大的,在.Net 8对JIT是持续的改进,GC也进行小幅度的调整,在SIMD加入了AVX512,回到整体,在.Net 8对NativeAOT改进,就是简化使用.在.Net 8之前使用NativeAOT,需要引用Microsoft.DotNet.ILCompiler包,才可以,在.Net 8只需要这样:
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <!--启用aot-->
    <PublishAot>true</PublishAot>
    <!--生成独立程序时,不生成调试符号-->
    <DebuggerSupport>false</DebuggerSupport>
    <InvariantGlobalization>true</InvariantGlobalization>
    <UseSystemResourceKeys>true</UseSystemResourceKeys>
    
    <!--ilc优化配置选项-->
    <IlcOptimizationPreference>Size</IlcOptimizationPreference>
    <IlcFoldIdenticalMethodBodies>true</IlcFoldIdenticalMethodBodies>
    <IlcDisableReflection>true</IlcDisableReflection>
    <IlcGenerateCompleteTypeMetadata>false</IlcGenerateCompleteTypeMetadata>
    <IlcGenerateStackTraceData>false</IlcGenerateStackTraceData>
  </PropertyGroup>

</Project>

测试源码:

Console.WriteLine("Hello, World!");

查看生成独立程序大小:

.Net 8使用NativeAOT生成独立程序的大小

在.Net 8 preview1时,使用NativeAOT生成独立的程序,只有1兆多一点,改进提升还是很大的,不过,在交叉编译Linux 64位程序时时失败的.

posted @ 2025-01-05 13:09  China Soft  阅读(12)  评论(0编辑  收藏  举报