在Mac上用自己編譯出的DNX執行.NET程式

TP_funny發表於2015-05-29

由於Mono 4.0的一個bug(現已修復),目前如果要在Mac上編譯dnx,需要先簽出Mono的原始碼進行編譯,詳見 Bug 29499 – System.IO.EndOfStreamException when running dnx command 。

在Mac OS X編譯Mono的方法可以參考 Compiling Mono on Mac OS X 。用到的命令如下:
brew install autoconf automake libtool pkg-config
git clone https://github.com/mono/mono.git
cd mono
./autogen.sh --prefix=/usr/local --disable-nls
make
make install

編譯好Mono之後(編譯是一個漫長的過程),需要修改dnx中的packages/KoreBuild/build/_kpm-build.shade檔案(如果沒有這個檔案,需要先執行一下./build.sh)
exec program='cmd' commandline='/C kpm pack${pack_options} ${projectFolder} --configuration ${configuration}' if='!IsMono'
exec program='kpm' commandline='pack${pack_options} ${projectFolder} --configuration ${configuration}' if='IsMono'

將其中的kpm改為dnu(不然編譯時會報“找不到kpm”的錯誤,都是改名惹的禍):
exec program='cmd' commandline='/C dnu build${build_options} ${projectFolder} --configuration ${configuration}' if='!IsMono'
exec program='dnu' commandline='build${build_options} ${projectFolder} --configuration ${configuration}' if='IsMono'

然後執行./build.sh命令就可以成功編譯dnx。
編譯出來的東東都在artifacts/build資料夾中。其中有2個重要的資料夾:dnx-mono與dnx-coreclr-darwin-x64,前者是基於Mono的dnx,後者是基於CoreCLR的dnx,通過dnvm安裝的dnx就是這個。它們包含了執行一個.NET程式所需要的一切,它們就是.NET Execution Enviroment(.NET執行環境)。

不信,我們可以用一個非常簡單的.NET程式測試一下。
這個.NET測試程式叫HelloDnx,只有2個檔案:
1)Program.cs
using System;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello from DNX!");
    }
}

2)project.json
{
    "dependencies":{
    },
    "frameworks":{
        "dnx451":{},
        "dnxcore50":{}
    }
}

我們用自己編譯的dnx執行這個HelloDnx試試。
首先刪除以前通過dnvm安裝的dnx。
cd ~/.dnx/runtimes
rm -rf *

然後用我們自己編譯出的dnx中的dnu命令恢復nuget包包:
/Git/dotnet/dnx/artifacts/build/dnx-mono/bin/dnu restore

Microsoft .NET Development Utility v1.0.0-t150525235008

Restoring packages for /Git/dotnet/HelloDnx/project.json
Writing lock file /Git/dotnet/HelloDnx/project.lock.json
Restore complete, 159ms elapsed

接著用我們自己編譯出來的dnx執行這個HelloDnx程式。
先用基於Mono的dnx:
/Git/dotnet/dnx/artifacts/build/dnx-mono/bin/dnx . run

執行結果:
Hello from DNX!

執行成功!
接著用基於CoreCLR的dnx:
/Git/dotnet/dnx/artifacts/build/dnx-coreclr-darwin-x64/bin/dnx . run

執行結果:
Resource string id=0x17FC System.DllNotFoundException: Resource string id=0x170B
   at Interop.mincore.GetStdHandle(Int32 nStdHandle)
   at System.Console.<>c__DisplayClass0.<get_Error>b__5()
   at System.Console.EnsureInitialized[T](T& field, Func`1 initializer)
   at dnx.host.RuntimeBootstrapper.PrintErrors(Exception ex)
   at dnx.host.RuntimeBootstrapper.Execute(String[] args)
   at DomainManager.Execute(Int32 argc, Char** argv)

執行失敗。可能是少了某個程式集或者程式集版本不對,暫不去研究。基於CoreCLR的dnx目前還在開發中,出問題也正常。(這個問題的確是一個bug,詳見#issue1955
在Mac上如此折騰一下,一是可以實際體會一下.NET跨平臺的進展,二是可以隨時折騰dnx,改改dnx的程式碼,編譯出來就可以用它跑.NET程式。
來自:碼農網
相關閱讀
評論(1)

相關文章