いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Mono 2.8でC#4.0のプログラムをコンパイル (mcs, gmcs, dmcs, dynamic)


以下メモ書きです。


たまにMonoを触っているのですが、Monoの場合コンパイラ
以下のように複数存在します。

  • mcs
  • gmcs
  • smcs
  • dmcs

Microsoft .NETの場合もバージョン毎に
csc.exeが存在するので同じようなものですが
名前が異なっているので、知らない人も多いみたいです。


で、Mono 2.8でC# 4.0のプログラムをコンパイルするには
Mono 2.6から追加された「dmcs」を利用します。


私の環境は、Mono 2.8.2を利用しています。

xxxx:~ gsf$ mono --version
Mono JIT compiler version 2.8.2 (tarball Tue Jan  4 15:08:58 MST 2011)
Copyright (C) 2002-2010 Novell, Inc and Contributors. www.mono-project.com
	TLS:           normal
	SIGSEGV:       normal
	Notification:  Thread + polling
	Architecture:  x86
	Disabled:      none
	Misc:          debugger softdebug 
	LLVM:          supported, not enabled.
	GC:            Included Boehm (with typed GC)


以下のコードを用意します。

using System;
using System.Collections.Generic;
using System.Linq;

namespace Gsf.Samples
{
    class MainClass
    {
        static void Main()
        {
            var query = from x in new int[]{ 1, 2, 3, 4, 5 }
                        where x % 2 == 0
                        select x;

            foreach (var i in query)
            {
                Console.WriteLine(i);
            }

            dynamic obj = 100;
            Console.WriteLine(obj);
        }
    }
}


LINQとdynamicを利用しているサンプルです。
これを、「mcs」でコンパイルすると

xxxx:~ gsf$ mcs ./test.cs
./test.cs(21,13): error CS1980: Dynamic keyword requires `System.Runtime.CompilerServices.DynamicAttribute' to be defined. Are you missing System.Core.dll assembly reference?
Compilation failed: 1 error(s), 0 warnings


コンパイルエラーが発生します。
んで、同じソースを「gmcs」でコンパイルすると

xxxx:~ gsf$ gmcs ./test.cs
./test.cs(21,13): error CS1980: Dynamic keyword requires `System.Runtime.CompilerServices.DynamicAttribute' to be defined. Are you missing System.Core.dll assembly reference?
Compilation failed: 1 error(s), 0 warnings


やっぱり、コンパイルエラーになります。
で、最後に「dmcs」でコンパイル。

xxxx:~ gsf$ dmcs ./test.cs


うまくいきました。
後は、動作確認です。

xxxx:~ gsf$ mono ./test.exe
2
4
100


ちゃんと実行できました。


ちなみに、現在の最新版であるMono 2.10系では
コンパイラの仕組みが大きく変わり
mcsコンパイラの内部実装がIKVM.Reflectionを利用するように
なりました。これにより、どのバージョンのプロファイラーで
も動作するようになった模様です。
(-sdk:PROFILE オプションを指定する)

mcs以外のコンパイラは、まだSystem.Reflection系の実装と
なっています。今後、IKVM.Reflectionになっていくのでしょう。



================================
過去の記事については、以下のページからご参照下さい。