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 == && 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的文件夹结构如下:

(三)
【准备编译时需要引用的程序集】
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文件。

(五)
【准备运行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文件夹结构如下:

大功告成?没有,但即将告成。现在如果运行程序,会出现下面的错误:
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 :

企鹅只出来了上半身,这地方有点问题,暂且不管了。(这个问题后来被解决了,详见corefx#761)
再接着运行命令 runtime_mac/corerun app/HelloWorld.exe windows :

搞定!Mac.NET之路正一步一步向前迈进。
Mac OS X上用CoreCLR运行一个真正的.NET控制台程序的更多相关文章
- 如何在Mac OS X上安装 Ruby运行环境
对于新入门的开发者,如何安装 Ruby和Ruby Gems 的运行环境可能会是个问题,本页主要介绍如何用一条靠谱的路子快速安装 Ruby 开发环境.此安装方法同样适用于产品环境! 系统需求 首先确定操 ...
- Mac OS X上安装 Ruby运行环境
环境 对于新入门的开发者,如何安装 Ruby和Ruby Gems 的运行环境可能会是个问题,本页主要介绍如何用一条靠谱的路子快速安装 Ruby 开发环境.此安装方法同样适用于产品环境! 系统需求 ...
- Mac OS X上尝试编译CoreCLR源代码
CoreCLR登陆GitHub之后,体验CoreCLR首当其冲的方式就是在自己的电脑上编译它,昨天分别在Windows与Linux上成功编译了CoreCLR,详见: 1)Windows上成功编译Cor ...
- 在Mac OS X上用自己编译出的CoreCLR运行.NET程序
当昨天被Mac OS X上无法编译CoreCLR的问题困扰时(详见Mac OS X上尝试编译CoreCLR源代码),后来发现这个难题竟然被神人@kangaroo给解决了,连CoreCLR的微软开发人员 ...
- 简单理解在Mac OS X上运行ASP.NET程序
运行ASP.NET程序的三要素: 1) CLR(.NET运行时) 2) KRE(ASP.NET运行时) 3) Web服务器 所以在Mac OS X上运行ASP.NET程序,就需要对应这三要素的东西: ...
- Mac OS X 上安装 ASP.NET 5
在Mac OS X Yosemite 10.10.3 中搭建第一个 ASP.NET 5 Web 项目 终于有时间在 Mac 上安装一下 ASP.NET 5,网上有许多教程,但是多数的时间比较早了,版本 ...
- 在 Mac OS X 上创建的 .NET 命令行程序访问数据库 (使用Entity Framework 7 )
var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...
- 在 Mac OS X 上安装 TensorFlow
在 Mac OS X 上安装 TensorFlow 这个文档说明了如何在 Mac OS X 上安装 TensorFlow. 注意:从 1.2 版本开始,在 Mac OS X 上 TensorFlow ...
- Mac OS X上搭建Apache、PHP、MySQL的Web服务器
mac OS 系统太帅了,安装php的环境如此简单,大赞一个! 转载自http://jingyan.baidu.com/article/39810a23e1939fb636fda6a9.html 在M ...
随机推荐
- ajax执行完成后,再执行下面的代码的解决办法
一般ajax设置的都是异步的,但是有时候我们有这种需求,就是等ajax执行完成之后,在执行下面的函数. 1设置async:false 在jq中直接设置了ajax是异步的还是同步的 一般如果不写这个,默 ...
- 解决阿里云数据库RDS报错The table '/home/mysql/data3015/tmp/#sql_13975_23' is full
查询任何一条语句都显示 The table '/home/mysql/data3015/tmp/#sql_13975_23' is full 查看了下数据库利用磁盘空间没有满, 阿里云的处理方式: 1 ...
- 滚动div的动画
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 利用should.js进行测试
nodejs 环境 , 安装should.js包 (npm install should) var should = require('should'); //正确1, 错误0 100 precent ...
- 随笔—邀请赛前训— Codeforces Round #330 (Div. 2) B题
题意: 这道英文题的题意稍稍有点复杂. 找长度为n的数字序列有多少种.这个序列可以分为n/k段,每段k个数字.k个数可以变成一个十进制的数Xi.要求对这每n/k个数,剔除Xi可被ai整除的情况,剔除X ...
- MVC dirname(——FILE——)
1.MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法组织 ...
- (八) 一起学 Unix 环境高级编程 (APUE) 之 信号
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- servlet实现的三种方式对比(servlet 和GenericServlet和HttpServlet)
第一种: 实现Servlet 接口 第二种: 继承GenericServlet 第三种 继承HttpServlet (开发中使用) 通过查看api文档发现他们三个(servlet 和GenericSe ...
- JVM调优-关于jvm的一些基本概念
1.数据类型 java体系中,数据类型可分为2类:基本类型和引用类型.基本类型保存变量原始值,即:他代表的值就是数值本身: 而引用类型的变量保存引用值."引用值"代表某个对象的引用 ...
- MySQL Batch 与 Transaction
最近在数据库上经常遇到死锁问题. 表现的问题有 1. 有一个查询为: 1) 一个复杂的 select 查处一组大数据 2) 使用事务 update 这组数据的状态 为了让锁定的时间变短, 我将这整个大 ...