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

时间:2022-09-25 09:19:00

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

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

using System;

internal class Program
{
private static void Main(string[] args)
{
if (args.Length == && args[] == "linux")
{
DrawLinux();
}
else if (args.Length == && args[] == "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 = ; var colors = new[] { ConsoleColor.Red, ConsoleColor.Green, ConsoleColor.Blue, ConsoleColor.Yellow };
for (int row = ; row < ; row++)
{
for (int i = ; i < squareSize / ; i++)
{
Console.WriteLine();
Console.Write(" ");
for (int col = ; col < ; col++)
{
Console.BackgroundColor = colors[row * + col];
Console.ForegroundColor = colors[row * + col];
for (int j = ; 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的文件夹结构如下:

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

(三)

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

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

如果你不想用mono,也可以将项目复制到Windows中用csc命令进行编译:

csc /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文件。

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

(五)

【准备运行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 {} \;

(注:感谢@问天何必提供了更简单的删除命令:rm -r -- */ )

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

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

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

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

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

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

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

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

企鹅只出来了上半身,这地方有点问题,暂且不管了。(这个问题后来被解决了,详见corefx#761

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

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

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

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

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

    对于新入门的开发者,如何安装 Ruby和Ruby Gems 的运行环境可能会是个问题,本页主要介绍如何用一条靠谱的路子快速安装 Ruby 开发环境.此安装方法同样适用于产品环境! 系统需求 首先确定操 ...

  2. Mac OS X上安装 Ruby运行环境

    环境   对于新入门的开发者,如何安装 Ruby和Ruby Gems 的运行环境可能会是个问题,本页主要介绍如何用一条靠谱的路子快速安装 Ruby 开发环境.此安装方法同样适用于产品环境! 系统需求 ...

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

    CoreCLR登陆GitHub之后,体验CoreCLR首当其冲的方式就是在自己的电脑上编译它,昨天分别在Windows与Linux上成功编译了CoreCLR,详见: 1)Windows上成功编译Cor ...

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

    当昨天被Mac OS X上无法编译CoreCLR的问题困扰时(详见Mac OS X上尝试编译CoreCLR源代码),后来发现这个难题竟然被神人@kangaroo给解决了,连CoreCLR的微软开发人员 ...

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

    运行ASP.NET程序的三要素: 1) CLR(.NET运行时) 2) KRE(ASP.NET运行时) 3) Web服务器 所以在Mac OS X上运行ASP.NET程序,就需要对应这三要素的东西: ...

  6. Mac OS X 上安装 ASP&period;NET 5

    在Mac OS X Yosemite 10.10.3 中搭建第一个 ASP.NET 5 Web 项目 终于有时间在 Mac 上安装一下 ASP.NET 5,网上有许多教程,但是多数的时间比较早了,版本 ...

  7. 在 Mac OS X 上创建的 &period;NET 命令行程序访问数据库 (使用Entity Framework 7 )

    var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...

  8. 在 Mac OS X 上安装 TensorFlow

    在 Mac OS X 上安装 TensorFlow 这个文档说明了如何在 Mac OS X 上安装 TensorFlow. 注意:从 1.2 版本开始,在 Mac OS X 上 TensorFlow ...

  9. Mac OS X上搭建Apache、PHP、MySQL的Web服务器

    mac OS 系统太帅了,安装php的环境如此简单,大赞一个! 转载自http://jingyan.baidu.com/article/39810a23e1939fb636fda6a9.html 在M ...

随机推荐

  1. Java内各种进制的表示

    不同进制的数据表现: 二进制:由0,1组成.以0b开头. 八进制:由0,1,...7组成.以0开头. 十进制:由0,1,...9组成.默认整数是十进制. 十六进制:由0,1,...9,a,b,c,d, ...

  2. 【转载自W3CPLUS】如何将页脚固定在页面底部

    该文章转载自:W3CPLUS 大漠的文章 http://www.w3cplus.com/css/css-sticky-foot-at-bottom-of-the-page 以下为全文 作为一个Web的 ...

  3. IOS推荐学习网站

    1> 个人博客:技术大牛 唐巧:http://blog.devtang.com/blog/archives/ 王巍:http://www.onevcat.com 破船之家:http://beyo ...

  4. Java的内存分配策略

    简单来说,对象内存分配主要是在堆中分配.但是分配的规则并不是固定的,取决于使用的收集器组合以及JVM内存相关参数的设定 以下介绍几条基本规则(使用的ParNew+Serial Old收集器组合): 一 ...

  5. opencv 手写选择题阅卷 &lpar;一&rpar;表格设计与识别

    (一)答题表格设计与识别 实际设计好的表格如下图 为了图像精确,表格和四角的标记都是由程序生成的,文字和数据是后期排版软件添加上去的. 图中四角的四个黑方块主要用来定位表格,然后就可以切割出每个单元格 ...

  6. mysql中select into 和sql中的select into 对比

    现在有张表为student,我想将这个表里面的数据复制到一个为dust的新表中去.answer 01: create table dust select * from student;//用于复制前未 ...

  7. 项目架构mvc&plus;webapi

    mvc+webapi 项目架构 首先项目是mvc5+webapi2.0+orm-dapper+ef codefirst. 1.项目框架层次结构: 这个mvc项目根据不同的业务和功能进行不同的区域划分, ...

  8. 历史记录 history

    设置显示行数:HISTSISE=5 或 export HISTSIZE=5 永久生效,生效,检查,同118. 储存历史记录文件:cat ~/.bash_history 控制文件:HISTFILESIZ ...

  9. Spring boot&lpar;4&rpar;-应用打包部署

    1.Spring Boot内置web spring Boot 其默认是集成web容器的,启动方式由像普通Java程序一样,main函数入口启动.其内置Tomcat容器或Jetty容器,具体由配置来决定 ...

  10. 菜鸟之旅——学习线程(Task)

    前面两篇回顾线程和线程池的使用方法,微软在.NET4.5推出了新的线程模型-Task.本篇将简单的介绍Task的使用方法. Task与线程 Task与线程或者说线程池关系紧密,可以说是基于线程池实现的 ...