zoukankan      html  css  js  c++  java
  • .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="zeroapiDynamic="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,初次的话会默认还原对应的包,需要一些时间。

    发布完成后,打开binx64 elease etcoreapp2.0win-x64publish 文件夹,里面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

     
    分类: .NET Core
    好文要顶 已关注 收藏该文  
    26
    0
     
     
     
    « 上一篇: Orchard Core Framework:ASP.NET Core 模块化,多租户框架
    » 下一篇: .NET Core UI框架Avalonia
  • 相关阅读:
    【C++】资源管理
    【Shell脚本】逐行处理文本文件
    【算法题】rand5()产生rand7()
    【Shell脚本】字符串处理
    Apple iOS产品硬件参数. 不及格的程序员
    与iPhone的差距! 不及格的程序员
    iPhone游戏 Mr.Karoshi"过劳死"通关. 不及格的程序员
    XCode V4 发布了, 苹果的却是个变态. 不及格的程序员
    何时readonly 字段不是 readonly 的?结果出呼你想象!!! 不及格的程序员
    object file format unrecognized, invalid, or unsuitable Command 不及格的程序员
  • 原文地址:https://www.cnblogs.com/webenh/p/11574537.html
Copyright © 2011-2022 走看看