Mac OS X上用CoreCLR运行一个真正的.NET控制台程序

这个真正的控制台程序来自corefxlab,名叫CoreClrHelloWorld,是一个跨平台的.NET控制台演示程序,可以显示微软、Linux、苹果的logo。

CoreClrHelloWorld代码如下(代码中省略了拼接logo的字符串,完整代码见这里):

using System;

internal class Program
{
    private static void Main(string[] args)
    {
        if (args.Length == 1 && args[0] == "linux")
        {
            DrawLinux();
        }
        else if (args.Length == 1 && args[0] == "mac")
        {
            DrawMac();
        }
        else
        {
            DrawWindows();
        }

        Console.WriteLine();
        Console.WriteLine("Press ENTER to exit ...");
        Console.ReadLine();
    }

    private static void DrawWindows()
    {
        Console.WriteLine("Hello, Windows...");

        const int squareSize = 20;

        var colors = new[] { ConsoleColor.Red, ConsoleColor.Green, ConsoleColor.Blue, ConsoleColor.Yellow };
        for (int row = 0; row < 2; row++)
        {
            for (int i = 0; i < squareSize / 2; i++)
            {
                Console.WriteLine();
                Console.Write("  ");
                for (int col = 0; col < 2; col++)
                {
                    Console.BackgroundColor = colors[row * 2 + col];
                    Console.ForegroundColor = colors[row * 2 + col];
                    for (int j = 0; j < squareSize; j++) Console.Write(‘@‘);
                    Console.ResetColor();
                }
            }
        }
        Console.WriteLine();
    }

    private static void DrawLinux()
    {
        Console.WriteLine("Hello, Linux...");

        const string Penguin = @"...";
        foreach (char c in Penguin)
        {
            if (c == ‘\n‘)
            {
                Console.ResetColor();
                Console.WriteLine();
            }
            else
            {
                ConsoleColor cc =
                    c == ‘*‘ ? ConsoleColor.Blue :
                    c == ‘@‘ ? ConsoleColor.Black :
                    c == ‘-‘ ? ConsoleColor.Yellow :
                    ConsoleColor.White;
                Console.BackgroundColor = cc;
                Console.ForegroundColor = cc;
                Console.Write(" ");
            }
        }

        Console.ResetColor();
        Console.WriteLine();
    }

    private static void DrawMac()
    {
        Console.WriteLine("Hello, Mac...");

        const string Apple = @"...";

        Console.ForegroundColor = ConsoleColor.White;
        Console.Write(Apple);
        Console.ResetColor();
        Console.WriteLine();
    }
}

CoreClrHelloWorld

在之前的博文在Mac OS X上用自己编译出的CoreCLR运行.NET程序中,当时的控制台演示程序只是用到了mscorlib.dll,并没有用到.NET Core Framework(CoreFx)中的程序集。而CoreClrHelloWorld用到了CoreFx中的System.Console.dll,所以如果将CoreClrHelloWorld在Mac上跑起来,就可以进一步体验跨平台的.NET Core。

在Mac上折腾CoreClrHelloWorld的过程中,主要遇到了3个问题,问题出在System.Console中的ConsolePal.Unix.cs代码对Mac OS X的支持上:

1)Interop.libc.open64需要改为Interop.libc.open,open64不是POSIX标准中定义的。(详见corefx#715

2)在Mac OS X中读取terminfo的问题:在Linux中,文件路径是/lib/terminfo/x/xterm-256color;在Mac中是/usr/share/terminfo/78/xterm-256color。78是x的16进制ASCII码,而ConsolePal.Unix.cs中只根据x去读就读取不到。(详见corefx#723

3)Interop.libc.lseek64需要改为Interop.libc.lseek,原因与问题1一样。(详见corefx#733

当这3个问题被修复并合并到corefx的主分支之后,就可以在Mac上成功运行CoreClrHelloWorld了。(详见corefx/pull#716#725#736

下面分享一下详细的操作步骤,操作有些繁琐。

如果你嫌麻烦,可以从GitHub签出已经配置好的CoreClrHelloWorld,然后直接运行:

git clone https://github.com/cnblogs-dudu/CoreClrHelloWorld.git
cd CoreClrHelloWorld
runtime_mac/corerun app/HelloWorld.exe mac

最好自己一步一步操作一下,这样会有不一样的体会。具体操作步骤如下:

(一)

【准备CoreClrHelloWorld文件】

1)创建CoreClrHelloWorld文件夹:mkdir CoreClrHelloWorld;cd $_

2)创建app文件夹:mkdir app;cd $_

3)下载CoreClrHelloWorld.cs至app文件夹:

curl -O https://raw.githubusercontent.com/dotnet/corefxlab/master/demos/CoreClrConsoleApplications/HelloWorld/HelloWorld.cs

(二)

【准备CoreCLR】

运行CoreCLR需要三大组件:corerun, libcoreclr.dylib, mscorlib.dll。

1)git签出最新版的coreclr代码库:git clone https://github.com/dotnet/coreclr.git

2)编译coreclr:./build.sh

3)编译成功之后,在CoreClrHelloWorld中创建runtime_mac文件夹:mkdir ../CoreClrHelloWorld/runtime_mac

4) 将编译出来的corerun与libcoreclr.dylib复制到CoreClrHelloWorld/runtime_mac文件夹

cp binaries/Product/amd64/debug/corerun binaries/Product/amd64/debug/libcoreclr.dylib ../CoreClrHelloWorld/runtime_mac

5) 下载之前博文中用到的mscorlib.dll文件至CoreClrHelloWorld/runtime_mac(该文件由@kangaroo提供,在运行CoreClrHelloWorld时使用,详见这里

cd ../CoreClrHelloWorld/runtime_mac
curl http://files.cnblogs.com/files/dudu/mscorlib.dll.zip | tar -xf- -C .
rm -r __MACOSX

这2步之后CoreClrHelloWorld的文件夹结构如下:

(三)

【准备编译时需要引用的程序集】

1)在CoreClrHelloWorld中创建compile_r_lib文件夹:mkdir compile_r_lib; cd $_

2)下载nuget.exe:curl -L -O https://nuget.org/nuget.exe

3)安装nuget中的System.Console包包:

mono nuget.exe install System.Console -Source https://www.myget.org/F/dotnet-corefx/ -Prerelease

4)将子文件夹中的System.Console.dll与System.Runtime.dll文件复制到compile_r_lib文件夹:

find . -wholename ‘*/aspnetcore50/System.Console.dll‘ -exec cp {} \. \;
find . -wholename ‘*/aspnetcore50/System.Runtime.dll‘ -exec cp {} \. \;

5)下载编译时要引用的mscorlib.dll至compile_r_lib文件夹(该文件也由@kangaroo提供,在编译HelloWorld.cs时使用,详见这里):

curl http://files.cnblogs.com/files/dudu/mscorlib_contract.dll.zip | tar -xf- -C .
rm -r __MACOSX

(四)

【编译HelloWorld.cs文件】

用mono的mcs命令进行编译。

1)回到CoreClrHelloWorld文件夹:cd ..

2)运行编译命令:

mcs -nostdlib  -r:compile_r_lib/mscorlib.dll -r:compile_r_lib/System.Runtime.dll -r:compile_r_lib/System.Console.dll app/HelloWorld.cs

编译成功后,就会在app文件夹中看到HelloWorld.exe文件。

(五)

【准备运行HelloWorld.exe所需的程序集】

1)由于System.Console还依赖一些其他程序集,都得要通过nuget下载下来,下载到compile_r_lib文件夹中。

mono nuget.exe install System.Diagnostics.Contracts -Source https://www.myget.org/F/dotnet-corefx/ -Prerelease
mono nuget.exe install System.Diagnostics.Debug -Source https://www.myget.org/F/dotnet-corefx/ -Prerelease
mono nuget.exe install System.Diagnostics.Tools -Source https://www.myget.org/F/dotnet-corefx/ -Prerelease
mono nuget.exe install System.Globalization -Source https://www.myget.org/F/dotnet-corefx/ -Prerelease
mono nuget.exe install System.IO.FileSystem.Primitives -Source https://www.myget.org/F/dotnet-corefx/ -Prerelease
mono nuget.exe install System.Reflection -Source https://www.myget.org/F/dotnet-corefx/ -Prerelease
mono nuget.exe install System.Resources.ResourceManager -Source https://www.myget.org/F/dotnet-corefx/ -Prerelease
mono nuget.exe install System.Runtime.Extensions -Source https://www.myget.org/F/dotnet-corefx/ -Prerelease
mono nuget.exe install System.Runtime.Handles -Source https://www.myget.org/F/dotnet-corefx/ -Prerelease
mono nuget.exe install System.Runtime.InteropServices -Source https://www.myget.org/F/dotnet-corefx/ -Prerelease
mono nuget.exe install System.Text.Encoding.Extensions -Source https://www.myget.org/F/dotnet-corefx/ -Prerelease
mono nuget.exe install System.Threading -Source https://www.myget.org/F/dotnet-corefx/ -Prerelease

2)将compile_r_lib中所有通过nuget下载的包包的aspnetcore50文件夹中的程序集复制到runtime_mac文件夹中。

find . -wholename ‘*/aspnetcore50/*‘ -exec cp -n {} ../runtime_mac \;

3)删除compile_r_lib中所有的nuget包包文件夹

find . -type d -exec rm -rf {} \;

于是最新的CoreClrHelloWorld文件夹结构如下:

大功告成?没有,但即将告成。现在如果运行程序,会出现下面的错误:

Unable to continue due to missing library.

当前的System.Console.dll是从nuget上取下来的,并不支持Mac OS X。我们需要从corefx中自己编译出System.Console.dll,这就是接下来的一项重要工作。

(六)

【编译System.Console】

这一步操作要在Windows上进行。

1)签出corefx的代码库:git clone https://github.com/dotnet/corefx.git

2)打开Visual Stuiod的命令行(为了能运行msbuild命令)

3)进入corefx所在的文件夹,运行msbuild命令:

msbuild src\System.Console\src\System.Console.csproj /p:OS=Unix;DefineConstants=TRACE /t:clean,build

(注:一定要加上DefineConstants=TRACE,这样在debug模式下编译时会去除代码中的Debug.Assert。因为Debug.Assert在运行时会引发CoreCLR出现"UNIXTODO: Implement string loading from resources"错误)

4)编译成功之后,将Windows中的corefx\bin\Debug\System.Console\System.Console.dll文件复制到Mac的Coreclrhelloworld\runtime_mac文件夹中,替换已有的System.Console.dll。

(七)

【用CoreCLR运行HelloWorld.exe】

回到Mac中,进入CoreClrHelloWorld文件夹,运行如下命令:

runtime_mac/corerun app/HelloWorld.exe mac

激动人心的时刻到来了!运果结果如下:

接着运行命令 runtime_mac/corerun app/HelloWorld.exe linux :

企鹅只出来了上半身,这地方有点问题,暂且不管了。

再接着运行命令 runtime_mac/corerun app/HelloWorld.exe windows :

搞定!Mac.NET之路正一步一步向前迈进。

时间: 2024-10-05 21:20:35

Mac OS X上用CoreCLR运行一个真正的.NET控制台程序的相关文章

Mac OS X上安装 Ruby运行环境

环境 对于新入门的开发者,如何安装 Ruby和Ruby Gems 的运行环境可能会是个问题,本页主要介绍如何用一条靠谱的路子快速安装 Ruby 开发环境.此安装方法同样适用于产品环境! 系统需求 首先确定操作系统环境,不建议在 Windows 上面搞,所以你需要用: Mac OS X 任意 Linux 发行版本(Ubuntu,CentOS, Redhat, ArchLinux ...) 强烈新手使用 Ubuntu 省掉不必要的麻烦! 以下代码区域,带有 $ 打头的表示需要在控制台(终端)下面执行

如何在Mac OS X上安装 Ruby运行环境

本页主要介绍如何用一条靠谱的路子快速安装 Ruby 开发环境. 系统需求 首先确定操作系统环境,不建议在 Windows 上面搞,所以你需要用: Mac OS X 以下代码区域,带有 $ 打头的表示需要在控制台(终端)下面执行(不包括 $ 符号) 步骤1 - 安装 RVM (ruby version manger ruby 版本管理) RVM 是干什么的这里就不解释了,后面你将会慢慢搞明白. $ \curl -L https://get.rvm.io | bash -s stable --rub

Mac OS X上尝试编译CoreCLR源代码

CoreCLR登陆GitHub之后,体验CoreCLR首当其冲的方式就是在自己的电脑上编译它,昨天分别在Windows与Linux上成功编译了CoreCLR,详见: 1)Windows上成功编译CoreCLR源代码 : 2)Linux上成功编译CoreCLR源代码 . Windows与Linux上编译成功之后,有一个挡不住的冲动——在Mac上编译CoreCLR.虽然微软目前优先考虑的是Windows与Linux两个平台,CoreCLR的编译暂时不支持Mac OS X,但我最期待的却是在Mac O

在Mac OS X上用自己编译出的CoreCLR运行.NET程序

当昨天被Mac OS X上无法编译CoreCLR的问题困扰时(详见Mac OS X上尝试编译CoreCLR源代码),后来发现这个难题竟然被神人@kangaroo给解决了,连CoreCLR的微软开发人员也大吃一惊(详见#105). @kangaroo This is awesome! Thank you so much for doing it! I’ll start reviewing it in the morning. 今天发现,@kangaroo修改后可在OS X上编译的版本已被合并到Co

ruby运行环境怎么在mac os x上安装

今天给大家讲讲ruby入门教程,主要针对新入门的ruby开发这,教大家如何在mac os x上安装ruby开发环境,本页主要介绍如何用一条靠谱的路子快速安装 Ruby 开发环境. 此安装方法同样适用于产品环境! 系统需求 首先确定操作系统环境,不建议在 Windows 上面搞,所以你需要用: Mac OS X 任意 Linux 发行版本(Ubuntu,CentOS, Redhat, ArchLinux ...) 强烈新手使用 Ubuntu 省掉不必要的麻烦! 以下代码区域,带有 $ 打头的表示需

简单理解在Mac OS X上运行ASP.NET程序

运行ASP.NET程序的三要素: 1) CLR(.NET运行时) 2) KRE(ASP.NET运行时) 3) Web服务器 所以在Mac OS X上运行ASP.NET程序,就需要对应这三要素的东西: 1) CLR - Mono(目前只有Mono可以用,以后可以用Core CLRE) 2) KRE - KRE-Mono(基于Mono的KRE) 3)Web服务器 - Kestrel 接着,用下面的4个命令将这三样东西安装上即可: brew tap aspnet/k brew install kvm

Mac OS X上IntelliJ IDEA 13与Tomcat 8的Java Web开发环境搭建

这标题实在有点拗口,不知道怎么写好,但看了标题也就明白文本的内容.最近几天在折腾这些玩意儿,所以写写总结.除了环境搭建,本文还是一篇入门级的上手教程. 去下载一些东西 JDK安装 Tomcat安装 Tomcat的配置 配置管理员账号 配置Tomcat端口 配置HTTPS 添加web应用 IntelliJ的安装 创建Java Web项目 运行Java Web项目 打成war包 去下载一些东西 老样子,先废话几句,IntelliJ IDEA,这个名字不知道谁想出来的,也真够拗口的,发音大致如此:[i

Swig在Mac OS X上的安装

网上有很多类似文章介绍Swig怎么在Mac OS X上安装和配置,一般来说就是: 下载pcre,configure & make & make install 下载swig,configure & make & make install 但实际上我在第一次按照这个步骤执行的时候,会发现在configure swig的时候,报pcre找不到的问题.然后使用–with-pcre-prefix=强制指定pcre的路径,configure没问题了.然后在make时,又找不到pcre

在 Mac OS X 上安装 Docker(转)

http://www.oschina.net/translate/installing-docker-on-mac-os-x?print 在 Mac OS X 上安装 Docker 注意:Docker支持Mac OS X 10.6 "Snow Leopard" 及其以上版本. Docker引擎使用了Linux内核特定的特性,所以要让它运行在OS X上我们需要用一个轻量型的虚拟机(vm).用OS X的Docker客户端来控制虚拟Docker来构建,运行以及管理Docker容器. 为了使过