.NET Core單檔案釋出靜態編譯AOT CoreRT
.NET Core單檔案釋出靜態編譯AOT CoreRT,將.NET Core應用打包成一個可執行檔案幷包含執行時。
支援Windows, MacOS and Linux x64 w/ RyuJIT codegen。
示例專案:
https://github.com/dotnet/corert/tree/master/samples/WebApi
下面來實際體驗。
首先確保安裝C++編譯環境,以及.NET Core 2.0 以上版本SDK。
新建WebAPI應用
開啟命令提示符,輸入如下:
dotnet new webapi -o zeroapi
cd zeroapi
新建WebAPI應用。
新增CoreRT到專案
目前CoreRT還是alpha版,在myget上有包。
首先新增一個nuget.config
dotnet new nuget
然後在 <packageSources> 節點新增如下:
<add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
接著新增Microsoft.DotNet.ILCompiler包引用:
dotnet add package Microsoft.DotNet.ILCompiler -v 1.0.0-alpha-*
替換預設services並處理反射
開啟Startup.cs ,將 services.AddMvc(); 替換成 services.AddMvcCore().AddJsonFormatters();
接著建立一個rd.xml 配置檔案,用於反射處理執行時,確保反射程式集編譯到程式中。
rd.xml配置檔案如下:
<Directives>
<Application>
<Assembly Name="zeroapi" Dynamic="Required All" />
<Assembly Name="Microsoft.AspNetCore.Server.Kestrel.Core">
<Type Name="Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer" Dynamic="Required All" />
<Type Name="Microsoft.AspNetCore.Server.Kestrel.Core.Internal.KestrelServerOptionsSetup" Dynamic="Required All" />
</Assembly>
<Assembly Name="Microsoft.AspNetCore.Server.Kestrel" Dynamic="Required All"/>
<Assembly Name="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv">
<Type Name="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.LibuvTransportFactory" Dynamic="Required All" />
<Type Name="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.LibuvTransportOptions" Dynamic="Required All" />
</Assembly>
<Assembly Name="Microsoft.Extensions.DependencyInjection" Dynamic="Required All">
<Type Name="Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory" Dynamic="Required All" />
<Type Name="Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteExpressionBuilder" Dynamic="Required All" />
<Type Name="Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver" Dynamic="Required All" />
<Type Name="Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator" Dynamic="Required All" />
</Assembly>
<Assembly Name="Microsoft.Extensions.Options">
<Type Name="Microsoft.Extensions.Options.OptionsManager`1[[Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions,Microsoft.AspNetCore.Server.Kestrel.Core]]" Dynamic="Required All" />
<Type Name="Microsoft.Extensions.Options.OptionsFactory`1[[Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions,Microsoft.AspNetCore.Server.Kestrel.Core]]" Dynamic="Required All" />
<Type Name="Microsoft.Extensions.Options.OptionsMonitor`1[[Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions,Microsoft.Extensions.Logging.Console]]" Dynamic="Required All" />
</Assembly>
<Assembly Name="Microsoft.AspNetCore.Mvc.Core" Dynamic="Required All" />
<Assembly Name="Microsoft.AspNetCore.Routing">
<Type Name="Microsoft.AspNetCore.Routing.Internal.RoutingMarkerService" Dynamic="Required All" />
<Type Name="Microsoft.AspNetCore.Builder.RouterMiddleware" Dynamic="Required All" />
<Type Name="Microsoft.AspNetCore.Routing.Tree.TreeRouteBuilder" Dynamic="Required All" />
<Type Name="Microsoft.AspNetCore.Routing.DefaultInlineConstraintResolver" Dynamic="Required All" />
<Type Name="Microsoft.AspNetCore.Routing.RouteOptions" Dynamic="Required All" />
</Assembly>
<Assembly Name="Microsoft.AspNetCore.Mvc.Formatters.Json">
<Type Name="Microsoft.AspNetCore.Mvc.Formatters.Json.Internal.MvcJsonMvcOptionsSetup" Dynamic="Required All" />
<Type Name="Microsoft.AspNetCore.Mvc.MvcJsonOptions" Dynamic="Required All" />
</Assembly>
<Assembly Name="Microsoft.AspNetCore.Authorization">
<Type Name="Microsoft.AspNetCore.Authorization.DefaultAuthorizationPolicyProvider" Dynamic="Required All" />
<Type Name="Microsoft.AspNetCore.Authorization.AuthorizationOptions" Dynamic="Required All" />
</Assembly>
<Assembly Name="Microsoft.AspNetCore.Http">
<Type Name="Microsoft.AspNetCore.Http.HttpContextFactory" Dynamic="Required All" />
</Assembly>
<Assembly Name="Microsoft.AspNetCore.Hosting" Dynamic="Required All">
<Type Name="Microsoft.AspNetCore.Hosting.Internal.ApplicationLifetime" Dynamic="Required All" />
</Assembly>
<Assembly Name="Microsoft.Extensions.Logging.Abstractions">
<Type Name="Microsoft.Extensions.Logging.Logger`1[[Microsoft.AspNetCore.Hosting.Internal.WebHost,Microsoft.AspNetCore.Hosting]]" Dynamic="Required All" />
</Assembly>
<Assembly Name="Microsoft.Extensions.Logging">
<Type Name="Microsoft.Extensions.Logging.LoggerFactory" Dynamic="Required All" />
</Assembly>
<Assembly Name="Microsoft.Extensions.Logging.Console">
<Type Name="Microsoft.Extensions.Logging.Console.ConsoleLoggerOptions" Dynamic="Required All" />
<Type Name="Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider" Dynamic="Required All" />
</Assembly>
<Assembly Name="Microsoft.Extensions.Logging.Debug">
<Type Name="Microsoft.Extensions.Logging.Debug.DebugLogger" Dynamic="Required All" />
<Type Name="Microsoft.Extensions.Logging.Debug.DebugLoggerProvider" Dynamic="Required All" />
</Assembly>
<Assembly Name="System.Linq.Expressions">
<Type Name="System.Linq.Expressions.ExpressionCreator`1[[Newtonsoft.Json.Serialization.ObjectConstructor`1[[System.Object,System.Private.CoreLib]],Newtonsoft.Json]]" Dynamic="Required All" />
<Type Name="System.Linq.Expressions.ExpressionCreator`1[[System.Func`2[[System.Object,System.Private.CoreLib],[System.Object,System.Private.CoreLib]],System.Private.CoreLib]]" Dynamic="Required All" />
</Assembly>
<Assembly Name="Microsoft.Extensions.ObjectPool">
<Type Name="Microsoft.Extensions.ObjectPool.DefaultObjectPoolProvider" Dynamic="Required All" />
</Assembly>
<Assembly Name="Newtonsoft.Json">
<Type Name="Newtonsoft.Json.Serialization.ObjectConstructor`1[[System.Object,System.Private.CoreLib]]" Dynamic="Required All" />
</Assembly>
<Assembly Name="System.ComponentModel.TypeConverter">
<Type Name="System.ComponentModel.TypeConverter" Dynamic="Required All" />
<Type Name="System.ComponentModel.StringConverter" Dynamic="Required All" />
<Type Name="System.ComponentModel.Int32Converter" Dynamic="Required All" />
</Assembly>
<Assembly Name="Microsoft.Extensions.Configuration.Json">
<Type Name="Microsoft.Extensions.Configuration.Json.JsonConfigurationSource" Dynamic="Required All" />
</Assembly>
</Application>
</Directives>
其中如果你要替換成自己的程式,更改 <Assembly Name="zeroapi" Dynamic="Required All" /> 中的Name。
開啟zeroapi.csproj
在<PropertyGroup>節點下將 <RdXmlFile>rd.xml</RdXmlFile> 加入。
接著將 <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.3" /> 替換成如下:
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Formatters.Json" Version="2.0.1" />
接著將 ValuesController 更改一下,確保功能正常,如下:
public class ValuesController
{
[HttpGet("/")]
public string Hello() => "Hello World! LineZero AOT";
// GET api/values
[HttpGet("/api/values")]
public IEnumerable<string> Get()
{
return new string[] { "AOT", "CoreRT" };
}
// GET api/values/5
[HttpGet("/api/values/{id}")]
public string Get(int id)
{
return "Your value is " + id;
}
}
程式改造完成,接著最重要的釋出。
還原併發布
釋出之前,使用dotnet run 確保功能正常執行。
釋出請開啟 x64 Native Tools Command Prompt for VS 2017 ,注意一定在此命令列釋出。在開始選單找到 Visual Studio 2017,開啟就能找到。
釋出命令還是 dotnet publish -r <RID> -c <Configuration>
這裡釋出Windows 64位 dotnet publish -r win-x64 -c release,初次的話會預設還原對應的包,需要一些時間。
釋出完成後,開啟bin\x64\release\netcoreapp2.0\win-x64\publish 資料夾,裡面zeroapi.exe即為最終檔案,執行即可。
可以看到最終大小為21m左右。然後訪問http://localhost:5000/ 如圖:
控制檯Demo
新建一個控制檯應用,使用AOT釋出。
單純控制檯,沒有反射的內容,無需要rd.xml 檔案。
程式碼如下:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Console.WriteLine("LineZero AOT Demo!");
Console.ReadKey();
}
}
最終 dotnet publish -r win-x64 -c release 釋出
最終單個檔案大小不到4m!
目前該技術還是早期版本,期待微軟最終帶到正式版。
GitHub:https://github.com/dotnet/corert
原文地址:https://www.cnblogs.com/linezero/p/CoreRT.html
.NET社群新聞,深度好文,歡迎訪問公眾號文章彙總 http://www.csharpkit.com
相關文章
- 【翻譯】CoreRT - A .NET Runtime for AOT
- asp .net core 靜態檔案資源
- 使用CoreRT將.NET Core釋出為Native應用程式
- asp.net core 系列之靜態檔案ASP.NET
- go編譯靜態檔案到exeGo編譯
- JIT-動態編譯與AOT-靜態編譯:java/ java/ JavaScript/Dart亂談編譯JavaScriptDart
- Asp.Net Core入門之靜態檔案ASP.NET
- .Net Core 中介軟體之靜態檔案(StaticFiles)
- .net8 aot 釋出
- ASP.NET Core靜態檔案處理原始碼探究ASP.NET原始碼
- .NET 中的動態編譯(生成exe檔案)編譯
- c# .Net Core靜態檔案伺服器學習總結C#伺服器
- Django靜態檔案輸出Django
- apache動態編譯/靜態編譯區別Apache編譯
- Angular–AOT和JIT編譯Angular編譯
- 15.ASP.NET Core 應用程式中的靜態檔案中介軟體ASP.NET
- .NET 7 的 AOT 到底能不能扛反編譯?編譯
- ASP .Net Core 中介軟體的使用(一):搭建靜態檔案伺服器/訪問指定檔案伺服器
- Xamarin.iOS專案編譯提示Could not AOT the assemblyiOS編譯
- HTML也可以靜態編譯?HTML編譯
- [譯]ASP.NET Core 2.0 本地檔案操作ASP.NET
- Asp-Net-Core開發筆記:使用NPM和gulp管理前端靜態檔案筆記NPM前端
- ASP.NET Core使用靜態檔案、目錄遊覽與MIME型別管理ASP.NET型別
- 如何編制微軟.Net Core的docker檔案?微軟Docker
- .NET5.0 單檔案釋出打包操作深度剖析
- dotnet core如何編譯exe編譯
- 利用ant編譯釋出打包jar檔案和打包api文件為rar檔案編譯JARAPI
- Sanic 靜態檔案
- 單個Nginx釋出多個react靜態頁面NginxReact
- Android NDK祕籍--編譯靜態庫、呼叫靜態庫Android編譯
- 【.Net Core】 使用 Nginx 釋出 .Net Core 3.1 專案至LInux(Centos7)。NginxLinuxCentOS
- [翻譯]EntityFramework Core 2.2 釋出Framework
- ASP.NET Core 1.0 靜態檔案、路由、自定義中介軟體、身份驗證簡介ASP.NET路由
- Reflector反編譯.NET檔案後修復編譯
- nginx偽靜態檔案Nginx
- php生成靜態檔案PHP
- Linux下快速靜態編譯Qt以及Qt動態/靜態版本共存Linux編譯QT
- .NET Core 2.2釋出一覽