在前一篇文章中,我们简略的介绍了jws.mono的安装使用,以及我们如何自己动手做一个jws.mono出来。
在文章发表之后的几天里,我一直觉得有点不妥之处,直到后来猛然的意识到:我们自己动手做的jws.mono虽然可以见到info页面,但实际上却是无法挂载任何的.NET站点的。因此这也有必要写下这篇的续篇来对前面的疏漏进行填补。
马上进入本节主题,在本节中我们主要讲述:
(1)、分析jws.mono的组成及相关组件的作用
(2)、此mono非彼mono:bin目录详解
1、jws.mono组成及介绍
总的来说,jws.mono包含了两个部分,jexus以及提供它运行环境的mono。下面是“jws.mono.tar.gz”解压之后的组成(注:本篇文章针对的是前一篇中下载获得的jws.mono,其他的可能结构不一样):
直接开始分析吧,如上图所示,jws.mono的根目录包含了四个目录,它们的作用分别是:
bin:包含Mono编译器的可执行文件目录
etc:包含.NET默认配置文件的目录(machine.config等)
jexus:顾名思义,放jexus的目录
lib:里面包含了.NET的程序集、我们编译mono和libgdiplus所得到的so库文件
目录以及结构大概就是这样,各位读者分别点击进入相关的目录之后定会眼前一种熟悉的感觉。
2、bin目录详解
点击进入到bin目录:
各位读者如果对比自己手上编译得出的mono/bin目录,这里的bin目录就显得轻量多了,是的,此处的bin目录是经过裁剪,仅仅包含了提供.NET运行所需的核心组件,并没有其他更多的东西。出了mono-sgen,其余均有脚本组成,而dmcs、gmcs以及mcs分别供给FramWork版本为4.0、2.0(3.5)以及4.5的程序的程序调用。
使用VIM打开其中一个脚本文件:
这里面仅包含了一条命令,命令的作用是调用同级目录下的mono,并指定它的framework版本。
回到文件目录中,我们再仔细观察一下文件“mono”的大小(有兴趣的读者可以看看自己编译的Linux.NET中可执行文件“mono”的大小,相差甚大),大小只有1KB,显然这个叫“mono”的文件绝不会是编译器“mono”,只是一个同名的文件而已。
我在前文中曾说过,出了mono-sgen以外,其余的均是脚本文件,因此我们仍然可以继续用Vim打开它:
到了这里,我们已经一目了然了,这个“mono”文件的作用其实就是先设置并载入与Linux.NET运行相关的资源文件(程序集文件、machine.config等),然后把处理交给了“mono-sgen”处理(提示:mono-sgen里面包含了mono的JIT以及Sgen垃圾回收等组件,好东西)。
这一个文件很重要,我们所有的.NET程序的运行都要经过这一个文件,因此如果这个文件里面的参数(目录之类的)有任何的差错,都会导致我们的.NET程序无法编译运行。
再留意“--runtime”这里,在此处,无论你使用的是那个版本的framework库,其实在jws.mono运行时都是使用framework 4.0(事实上目前流行的CLR主要有2.0和4.0两个版本,而在mono中CLR 4.0是可以兼容CLR 2.0的库,MS.NET则不行)。
回到起点,开篇的时候,我提到的那个问题,各位读者现在知道是什么原因造成的了吗?