.NET Core publish static single-file compilation AOT CoreRT
https://www.cnblogs.com/linezero/p/CoreRT.htm
.NET Core publish static single-file compilation AOT CoreRT, the .NET Core applications packaged into a single executable file and contains the runtime.
Support Windows, MacOS and Linux x64 w / RyuJIT codegen.
Sample project:
https://github.com/dotnet/corert/tree/master/samples/WebApi
Let's actual experience.
First make sure to install the C ++ compiler environment, as well as .NET Core 2.0 or later SDK.
New applications WebAPI
Open a command prompt, type the following:
dotnet new webapi -o zeroapi
cd zeroapi
New WebAPI application.
Adding to the project CoreRT
Currently CoreRT still alpha version, has a bag on myget.
Start by adding a nuget.config
dotnet new nuggets
Then <packageSources> node add the following:
<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" />
Then add Microsoft.DotNet.ILCompiler package references:
dotnet add package Microsoft.DotNet.ILCompiler -v 1.0.0-alpha-*
Services and processes to replace the default reflection
Open Startup.cs, the services.AddMvc (); replace services.AddMvcCore () AddJsonFormatters ().;
Rd.xml then creates a profile for the run-time reflection treatment, the reflection assembly to ensure compiled into the program.
rd.xml configuration file as follows:
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
<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>
If you where to be replaced with their own procedures, change < Assembly the Name = "zeroapi " Dynamic = "All the Required " /> in the Name.
Open zeroapi.csproj
The <at <PropertyGroup> node RdXmlFile> rd.xml </ RdXmlFile> was added.
Then <PackageReference Include = "Microsoft.AspNetCore.All" Version = "2.0.3" /> replaced with the following:
<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" />
Then ValuesController changes to make sure that the normal function, as follows:
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; } }
Program transformation is complete, then the most important release.
Restore and publish
Before publishing, make sure to use dotnet run function properly.
Open publishing x64 Native Tools for VS 2017 the Command Prompt , attention must be released in the command line. Find Visual Studio 2017 in the Start menu, open the find.
Issued an order or publish -r DOTNET <RID > -c <the Configuration >
Here released Windows 64-bit dotnet publish -r win-x64 -c release, for the first time, then by default the corresponding reduction package, take some time.
After publishing is complete, open the bin \ x64 \ release \ netcoreapp2.0 \ win-x64 \ publish folder, which shall be final zeroapi.exe file, you can execute.
We can see the final size of about 21m. Then visit http: // localhost: 5000 / Figure:
Console Demo
Create a new console application, using AOT release.
Simple console, there is no reflection of the content, no need rd.xml file.
code show as below:
class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); Console.WriteLine("LineZero AOT Demo!"); Console.ReadKey(); } }
The final dotnet publish -r win-x64 -c release issued
The final single file size is less than 4m!
Currently the technology is still in earlier versions, Microsoft finally look forward to the official version.
GitHub:https://github.com/dotnet/corert
.NET Core publish static single-file compilation AOT CoreRT, the .NET Core applications packaged into a single executable file and contains the runtime.
Support Windows, MacOS and Linux x64 w / RyuJIT codegen.
Sample project:
https://github.com/dotnet/corert/tree/master/samples/WebApi
Let's actual experience.
First make sure to install the C ++ compiler environment, as well as .NET Core 2.0 or later SDK.
New applications WebAPI
Open a command prompt, type the following:
dotnet new webapi -o zeroapi
cd zeroapi
New WebAPI application.
Adding to the project CoreRT
Currently CoreRT still alpha version, has a bag on myget.
Start by adding a nuget.config
dotnet new nuggets
Then <packageSources> node add the following:
<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" />
Then add Microsoft.DotNet.ILCompiler package references:
dotnet add package Microsoft.DotNet.ILCompiler -v 1.0.0-alpha-*
Services and processes to replace the default reflection
Open Startup.cs, the services.AddMvc (); replace services.AddMvcCore () AddJsonFormatters ().;
Rd.xml then creates a profile for the run-time reflection treatment, the reflection assembly to ensure compiled into the program.
rd.xml configuration file as follows:
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
<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>
If you where to be replaced with their own procedures, change < Assembly the Name = "zeroapi " Dynamic = "All the Required " /> in the Name.
Open zeroapi.csproj
The <at <PropertyGroup> node RdXmlFile> rd.xml </ RdXmlFile> was added.
Then <PackageReference Include = "Microsoft.AspNetCore.All" Version = "2.0.3" /> replaced with the following:
<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" />
Then ValuesController changes to make sure that the normal function, as follows:
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; } }
Program transformation is complete, then the most important release.
Restore and publish
Before publishing, make sure to use dotnet run function properly.
Open publishing x64 Native Tools for VS 2017 the Command Prompt , attention must be released in the command line. Find Visual Studio 2017 in the Start menu, open the find.
Issued an order or publish -r DOTNET <RID > -c <the Configuration >
Here released Windows 64-bit dotnet publish -r win-x64 -c release, for the first time, then by default the corresponding reduction package, take some time.
After publishing is complete, open the bin \ x64 \ release \ netcoreapp2.0 \ win-x64 \ publish folder, which shall be final zeroapi.exe file, you can execute.
We can see the final size of about 21m. Then visit http: // localhost: 5000 / Figure:
Console Demo
Create a new console application, using AOT release.
Simple console, there is no reflection of the content, no need rd.xml file.
code show as below:
class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); Console.WriteLine("LineZero AOT Demo!"); Console.ReadKey(); } }
The final dotnet publish -r win-x64 -c release issued
The final single file size is less than 4m!
Currently the technology is still in earlier versions, Microsoft finally look forward to the official version.
GitHub:https://github.com/dotnet/corert