我是一个需要尝试编译一些C#代码才能工作的Unix人.我已经下载了Mono for Mac和mcs命令行工具.这个库附带了一个csproj文件,其中包含了我需要编译的所有文件的XML.
Mono/mcs可以读取此csproj文件并从中生成DLL吗?
我目前正在参与一些有趣的编程语言研究,到目前为止,该研究主要围绕使用一些非常强大的基于程序员生产力的功能扩展即将推出的Java 7.0编译器.该工作应同样适用于相关的编程语言,如C#.
我目前正在寻找原型化C#端口功能的选项.我更喜欢开源选项,以便可以与最广泛的受众分享这项工作的成果.因此,Mono C#编译器似乎是最明显的起点.我是一位经验丰富的C#开发人员,所以编写代码不是问题.我主要关心的是以可维护和支持的方式扩展编译器.在关于这个主题的单声道常见问题解答(链接)中,声称"Mono已被用作尝试C#语言的新思想的基础(有三个或四个编译器派生自Mono的C#编译器)".不幸的是,没有比此更多的指示,到目前为止,谷歌的搜索还没有任何改变.
我想知道是否有任何人有这方面的任何信息.是mcs/ gmcs/ dmcs有一个标准的可扩展性模型?具体来说,我将在程序的抽象语法树上执行一些有趣的转换.是否有一种标准机制,用于在抽象语法树生成和类型检查器之间插入功能到编译器链中,然后生成代码?
到目前为止,我已经为代码编写了一些特别的扩展(主要是在代码生成器中),但这似乎不是一个可维护的解决方案,特别是考虑到我打算让我的扩展更新为Git主干单声道尽可能多.此外,能够更新我的扩展,而不必每次进行更改时都重新编译整个编译器,这将是很好的.我希望能够将我的所有AST操作包装到一个可由mcs/ gmcs/ 动态加载的.NET程序集中,dmcs而不必直接破解核心编译器代码.
任何有关扩展Mono C#编译器的想法或指示都将非常感激!
更新(2010年10月23日)
在回答我的问题时,我决定开始研究Mono的一个分支,以便为编译器创建一个简单的可扩展性模型.这是在它的早期阶段,但它在GitHub:
http://github.com/rcook/mono-extensibility
主要提交是:http://github.com/rcook/mono-extensibility/commit/a0456c852e48f6822e6bdad7b4d12a357ade0d01
如果有人有兴趣合作这个项目,请告诉我!
我们正在启动一个跨平台项目,以部署到Android和iOS.显然,很多代码都要在两者之间共享,而一些代码在很大程度上依赖于.NET框架项,就像sqlite-net库那样.
在两个项目之间共享代码的最佳方式(afaik)是使用PCL - 这样就可以在解决方案中使用来自iOS和Android项目的共享代码来引用项目,并将所有内容重新编译并链接到一个很好的方式.
但是,使用gmcs编译器编译在MonoDevelop中创建的PCL,并且在这种情况下无法构建一些外部依赖项(即,在这种情况下使用的框架缺乏System.Func<T, TResult>,仅提供System.Func<T1, T2, ..., T9, TResult>).反过来,MonoTouch的编译器(smcs)能够完美地编译PCL(通过用smcs二进制替换gmcs二进制文件来证明).从我在谷歌搜索后发现的,gmcs使用2.0 .NET框架,而smcs使用名为2.1框架的smth,实际上是更新的.NET的混合体.
这里有一个问题:在MonoDevelop中构建PCL(作为另一个项目的依赖项)时,是否可以指定使用哪个编译器?
我想从我的常规.NET 3.5应用程序中使用Mono的编译器作为服务.
我已经下载了最新的位(2.6.7),在Visual Studio中创建了一个简单的控制台应用程序并引用了Mono.CSharp dll.
然后,在我的控制台应用程序中(直接在线样本):
Evaluator.Run("using System; using System.Linq;");
bool ress;
object res;
Evaluator.Evaluate(
"from x in System.IO.Directory.GetFiles (\"C:\\\") select x;",
out res, out ress);
foreach (var v in (IEnumerable)res)
{
Console.Write(v);
Console.Write(' ');
}
Run Code Online (Sandbox Code Playgroud)
这会在Evaluator.Run(第一行)引发异常:
Illegal enum value: 2049.
Parameter name: access
Run Code Online (Sandbox Code Playgroud)
这是因为dll是使用Mono.exe编译的,而不是csc.exe,我相信.
我已经尝试直接从demo-repl.zip文件中的http://tirania.org/blog/archive/2010/Apr-27.html下载Mono.CSharp dll ......这不会引发异常. ..但是在调用Evaluator.Evaluate之后out参数(res)是null ...所以我不确定出了什么问题.没有例外被抛出......
所以,我想弄清楚为什么我从demo-repl.zip下载的dll返回null.
编辑:我弄清楚它为什么返回null.看起来由于某种原因,编译器没有拿起System.Linq命名空间......虽然我不知道为什么......如果我只是评估"System.IO.Directory.GetFiles(\"C:\\ ")",它工作正常.
更新:看起来Mono编译器拾取引用的系统程序集似乎有问题.如果我直接复制其csharp控制台工具的示例:
csharp> var list = new int [] {1,2,3};
csharp> var b = from x in list
> where x > 1
> select x; …Run Code Online (Sandbox Code Playgroud) 我test.cs使用dmcsMac 的可执行文件和以下命令行程序编译了文件(引用第三方库):
dmcs /out:program.exe test.cs /target:exe /reference:/Users/kevin/path/to/bin/Debug/project.dll
Run Code Online (Sandbox Code Playgroud)
编译没有问题(排除/ reference参数导致问题).这program.exe在当前目录中创建了一个可执行文件.当我试图像这样运行它:
mono program.exe
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
Unhandled Exception:
System.IO.FileNotFoundException: Could not load file or assembly 'project, Version=3.4.1.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.
Run Code Online (Sandbox Code Playgroud)
我能解决这个问题的唯一方法是将project.dll文件复制到包含该program.exe文件的目录中.复制project.dll到同一目录后,程序运行正常.
我可以传递一个额外的参数mono来指定不同程序目录中的DLL吗?或者,是否有一个标志我可以传递给dmcs它来直接将DLL编译成二进制文件?
为什么不用这个C#typecheck?在这个例子中,我试图传递一个类型的方法string -> string作为Func<string, string>.在传递适当类型的函数的名称时,能够省略lambda语法似乎是完全合理的.
using System;
using System.Linq;
class WeakInference
{
public static void Main (string [] args)
{
// doesn't typecheck
var hellos = args.Select (AppendHello);
// have to do this:
// var hellos = args.Select (s => AppendHello (s));
}
static string AppendHello (string s)
{
return s + "hello";
}
}
Run Code Online (Sandbox Code Playgroud) 安装Mono的基本说明是:
tar xzvf mono-X.XX.tar.gz; cd mono-X.XX ./configure --prefix =/usr/local; 使; make install
所以我从http://download.mono-project.com/sources/mono/下载了最新版本并将其解压缩(但是这是一个bz2,使用了tar的j选项).
配置似乎工作正常.当我运行make时,它会在此之前插入大约40分钟左右:
make[5]: Entering directory `/usr/local/src/mono-2.11.2/mcs'
make[6]: Entering directory `/usr/local/src/mono-2.11.2/mcs'
make[6]: gmcs: Command not found
make[6]: *** [build/deps/basic-profile-check.exe] Error 127
make[6]: Leaving directory `/usr/local/src/mono-2.11.2/mcs'
make[6]: Entering directory `/usr/local/src/mono-2.11.2/mcs'
*** The compiler 'gmcs' doesn't appear to be usable.
*** Trying the 'monolite' directory.
make[7]: Entering directory `/usr/local/src/mono-2.11.2/mcs'
make[8]: Entering directory `/usr/local/src/mono-2.11.2/mcs'
Corlib not in sync with this runtime: expected corlib version 102, found 100.
Loaded from: /usr/local/src/mono-2.11.2/mcs/class/lib/monolite/mscorlib.dll …Run Code Online (Sandbox Code Playgroud) 我试图用linux上的mono编译我的项目.我的cmd看起来像......
gmcs Pages/UserProfile.cs Properties/AssemblyInfo.cs queues.cs watch_editor.cs Class1.cs -define:USE_SQLITE -r:System -r:System.Collections -r:System.Collections.Generic -r:System.Collections.ObjectModel -r:System.Collections.Specialized -r:System.Configuration
Run Code Online (Sandbox Code Playgroud)
但很长.我得到了输出
error CS0006: cannot find metadata file `System.Collections'
error CS0006: cannot find metadata file `System.Collections.Generic'
error CS0006: cannot find metadata file `System.Collections.ObjectModel'
...
Run Code Online (Sandbox Code Playgroud)
我该如何解决这个问题?
我也尝试过相反的方式(下面),并在它们的末尾与.dll有相同的错误信息
gmcs -define:USE_SQLITE -r:System.dll -r:System.Collections.dll -r:System.Web.UI.WebControls CommentCenter.cs cookies.cs db.cs Default.aspx.cs
Run Code Online (Sandbox Code Playgroud)