使用CoreRT將.NET Core釋出為Native應用程式

weixin_34262482發表於2018-03-23

在上一篇文章《使用.NET Core快速開發一個較正規的命令列應用程式》中我們看到了使用自包含方式釋出的.NET Core應用中包含了216個檔案。我就寫一個cat命令用得著這麼動真格。。。這寫出來的命令列還有人用嗎?今天我們就來介紹一下MS的另一個開源專案CoreRT。用來解決這個棘手的問題。

什麼是CoreRT?

CoreRT 是MS一個長期開源專案,它早在一年前就已經建立了,持續到今。

專案目標

將.NET Core託管(CLR)應用程式編譯為本地(特地平臺)的單一可執行檔案。

說白了就是將.NET Core編譯為機器碼(也可以是其他東西,如C++程式碼),而不再有之前的執行時,將.NET變為真正的“靜態編譯形”語言。

基本資訊

專案地址:https://github.com/dotnet/corert

支援的平臺

  1. Windows x64
  2. MacOS x64
  3. Linux x64/ARM
  4. CppCodeGen
  5. WebAssembly(Blazor目前還是基於Mono的,如果CoreRT成型,不出意外會切換到CoreRT)

可以看到目前沒有支援x86,所以想跑在x86架構的平臺上還是老老實實的吧。。

專案狀態

目前專案版本是:alpha,也就是說非正式版,切還離得比較遠。

所以不推薦大家用在比較大型或商業專案上,會出很多問題。

但寫個小程式,小工具還是沒什麼太大問題的。

Native的優勢是什麼?

Native的優勢我一說到就激動,期待了很久。從早期Core beta2還有這個功能,到後面被擱置(來不及釋出)經歷了期望與失落。。剋制住情緒,下面我們來理性分析一下Native的好處。

更少的釋出檔案

Native後釋出檔案明顯減少,一般情況下我們的.NET應用,每引用一個packages就至少增加一個檔案(*.dll)Native會將這些dll都打包在一起。這樣極大方便了釋出和部署。

啟動速度更快

我們都知道託管語言(.NET、Java)第一次執行(不僅僅是啟動,所有的方法、語句第一次執行都一樣)都很慢(《在.net中為什麼第一次執行會慢?》),這是託管語言的優勢也同樣是劣勢。

Native後就不存在虛擬機器技術(CLR、JVM)也就沒有的即時編譯這個動作了。得到的好處就是第一次執行跟第二次執行是一樣的。

更少的記憶體資源

Native後會進一步減少記憶體的使用,不需要載入一些核心“框架”(JIT)等。

Native的缺點?

Native並不是萬能的,也存在缺點。但我覺得整體上利大於弊。

更強的針對性

Native後就基本不能跨平臺了(這邊的跨平臺是指一次釋出到處執行,並不是指程式不能跨平臺)

也就是說,如果你要執行在windows上需要單獨為windows進行一次釋出,執行在MacOS上也需要單獨進行一次釋出,執行在Linux上同樣也需要單獨進行一次釋出(當然還包括x86\x64\ARM這樣的變更,都需要重新發布)

同樣JIT也無法為程式碼提供執行編譯優化,可以參考之前文章中,關於CPU個數的程式碼優化。

使用CoreRT釋出你的第一個Native應用程式

新增Packages

首先,因為這個專案還沒有正式釋出,所以你需要新增dotnet團隊的每日構建nuget源,地址為:https://dotnet.myget.org/F/dotnet-core/api/v3/index.json

然後安裝packages:Microsoft.DotNet.ILCompiler

或者你可以在你的專案路徑下執行下面的命令:

dotnet add package Microsoft.DotNet.ILCompiler -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json –v 1.0.0-alpha-*

設定RuntimeIdentifiers

RuntimeIdentifiers可設定的內容可以參考上面的平臺支援

為對應的平臺進行釋出

最終你的專案檔案可以像下面這樣

image

執行釋出命令

dotnet publish –c Release –r win-x64

dotnet publish –c Release –r linux-x64

image

我們就可以去具體的釋出輸出目錄看到釋出結果了

image

可以看到大小為3.7MB還是有優化的空間的,畢竟現在還不是正式版。

go引用fmt後的build大小差不多是1.9MB。

CoreRT目前存在的最大問題

CoreRT為什麼不推薦大家現在使用?很大的一個問題就是現有所有用到反射的型別,都必須制定一個Mapping檔案。異常麻煩。配置檔案內容大概如下:

image

泛型也行也得一個個完全去指定,所以不推薦大家在太複雜的應用下使用。當然官方最終應該不會允許這個檔案存在的。目前官方已經開了對應的issue用來討論如何解決這個現狀。

我們就再耐心等等吧。

相關文章