MonoGitのソースからビルドしてインストールする手順。 本文の内容は2017年08月17日時点のバージョンに基づく。

また、ビルドに使用した環境はUbuntu 16.04 LTS 64bit、本文中に掲載している所要時間はIntel Core i5-6402Pを積んだマシンで計測したもの。

ここで紹介する手順はMono本体といくつかのアセンブリをインストールするためのもの。 ディストリビューションが提供しているバージョンのMonoと共存できるようにするため、/opt/mono/masterにインストールする。

1つの環境に複数のMonoをインストールする方法についてはParallel Mono Environments - Monoで詳しく解説されている。

ビルドにはgcc、libtool、autotools、gettext、pkg-config等が必要になるので、あらかじめインストールしておく必要がある。

§1 libgdiplus

System.Drawing.dllなど、GDI+の機能を使用する場合のみ。 不要な場合はインストールを省略できる。

§1.1 依存するパッケージのインストール

sudo apt-get install \
libcairo2-dev libexif-dev libfreetype6-dev libfontconfig1-dev libglib2.0-dev libjpeg8-dev libpng12-dev \
libtiff5-dev libgif-dev libx11-dev libxrender-dev

§1.2 ソースのチェックアウトとautogen、configure

git clone git://github.com/mono/libgdiplus.git
cd ./libgdiplus
./autogen.sh --prefix=/opt/mono/master

configureの結果例。

---
Configuration summary

   * Installation prefix = /opt/mono/master
   * Cairo = 1.14.6 (system)
   * Text = cairo
   * EXIF tags = yes
   * X11 = yes
   * Codecs supported:

      - TIFF: yes
      - JPEG: yes
      - GIF: yes
      - PNG: yes

      NOTE: if any of the above say 'no' you may install the
            corresponding development packages for them, rerun
            autogen.sh to include them in the build.

---
Now type `make' to compile

§1.3 ビルド、インストール

configureした結果に問題が無ければmake, make installする。

make
sudo make install

正しくインストールできたか確認する。

$ PKG_CONFIG_PATH=/opt/mono/master/lib/pkgconfig pkg-config libgdiplus --modversion
5.4

$ PKG_CONFIG_PATH=/opt/mono/master/lib/pkgconfig pkg-config libgdiplus --libs
-L/opt/mono/master/lib -L/opt/mono/master -lgdiplus -lglib-2.0 -lcairo -lfontconfig -lfreetype -ljpeg -ltiff -lgif -lpng12 -lexif -Wl,--export-dynamic -lgmodule-2.0 -pthread -lgthread-2.0 -pthread -lglib-2.0

§2 LLVM

LLVMバックエンドを有効にする場合のみ。 不要な場合はインストールを省略できる。

§2.1 ソースのチェックアウトとautogen、configure

git clone git://github.com/mono/llvm.git
cd llvm/
./configure --prefix=/opt/mono/master --enable-optimized

§2.2 ビルド、インストール

configureした結果に問題が無ければmake, make installする。

make
sudo make install

所要時間は以下のとおり。

$ time make -j4

real	5m45.884s
user	19m49.404s
sys	0m49.328s

§3 Mono本体(コンパイラ、クラスライブラリ)

§3.1 依存するパッケージのインストール

sudo apt-get install \
cmake libncurses-dev

§3.2 ソースのチェックアウトとautogen、configure

ここでは--with-llvmを指定してLLVMバックエンドを有効にしてビルドする。 LLVMをインストールしていない場合、あるいはLLVMを無効にする場合は、--with-llvmを指定しない。

git clone git://github.com/mono/mono.git
cd mono
export MONO_USE_LLVM=1
./autogen.sh --prefix=/opt/mono/master/ --with-llvm=/opt/mono/master --with-libgdiplus=/opt/mono/master --with-ikvm-native=no --with-mcs-docs=no --with-x

configureの結果例。

        mcs source:    mcs
	C# Compiler:   roslyn

   Engine:
	Host:	       x86_64-pc-linux-gnu
	Target:	       x86_64-pc-linux-gnu
	GC:	       sgen (concurrent by default) and Included Boehm GC with typed GC and parallel mark
	TLS:           __thread
	SIGALTSTACK:   yes
	Engine:        Building and using the JIT
	BigArrays:     no
	DTrace:        no
	LLVM Back End: no (dynamically loaded: no)
	Interpreter:   no

   Libraries:
	.NET 4.x:        yes
	Xamarin.Android: no
	Xamarin.iOS:     no
	Xamarin.WatchOS: no
	Xamarin.TVOS:    no
	Xamarin.Mac:     no
	Windows AOT:     no
	Orbis:           no
	Unreal:          no
	Test profiles:   AOT Full (no), AOT Hybrid (no)
	JNI support:     
	libgdiplus:      /opt/mono/master
	zlib:            system zlib
	BTLS:            yes (x86_64)
	

Now type `make' to compile

§3.3 ビルド、インストール

準備が整ったら、make, make installする。

make
sudo make install

所要時間は以下のとおり。

$ time make -j4

real	12m59.881s
user	27m18.964s
sys	0m57.564s

Monoのビルドにはmcs(C#コンパイラ)が必要になる。 コンパイルする環境にmcsが場合は、以下のコマンドで最新のMonoLite(最小構成のmcsパッケージ)を取得することでビルドできるようになる。 ただし、通常は自動でダウンロードされるため手動で行う必要はない。

MonoLiteの取得
make get-monolite-latest

MonoLiteが入手できない場合は、以下の5つのバイナリを別の環境からコピーするなどして手動で../mcs/class/lib/monolite/に配置する。 (過去のバージョンでは有効だった手段。 現在のバージョンでも有効かどうかは未検証。)

  • mscorlib.dll
  • System.dll
  • System.Xml.dll
  • Mono.Security.dll
  • mcs.exe

§3.4 動作確認

§3.4.1 新しくMonoをインストールした場合

mono -Vでmonoが動作することを確認する。

$ mono -V
Mono JIT compiler version 5.7.0 (master/aa7cd58 2017年  8月 17日 木曜日 17:40:46 JST)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
	TLS:           __thread
	SIGSEGV:       altstack
	Notifications: epoll
	Architecture:  amd64
	Disabled:      none
	Misc:          softdebug 
	LLVM:          supported, not enabled.
	GC:            sgen (concurrent by default)

§3.4.2 既に別のバージョンのMonoが存在する環境にインストールした場合

新しく/opt/mono/masterにインストールしたMonoを参照できるように、環境変数を設定するスクリプトを用意しておく。

mono-master-env
#!/bin/bash
MONO_PREFIX=/opt/mono/master
GNOME_PREFIX=/usr
export DYLD_FALLBACK_LIBRARY_PATH=$MONO_PREFIX/lib:$DYLD_LIBRARY_FALLBACK_PATH
export LD_LIBRARY_PATH=$MONO_PREFIX/lib:$LD_LIBRARY_PATH
export C_INCLUDE_PATH=$MONO_PREFIX/include:$GNOME_PREFIX/include
export ACLOCAL_PATH=$MONO_PREFIX/share/aclocal
export PKG_CONFIG_PATH=$MONO_PREFIX/lib/pkgconfig:$GNOME_PREFIX/lib/pkgconfig
export PATH=$MONO_PREFIX/bin:$PATH

まずmono -Vで既にインストールされているmonoが動作することを確認する。

$ which mono
/usr/bin/mono

$ mono -V
Mono JIT compiler version 4.2.1 (Debian 4.2.1.102+dfsg2-7ubuntu4)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
	TLS:           __thread
	SIGSEGV:       altstack
	Notifications: epoll
	Architecture:  amd64
	Disabled:      none
	Misc:          softdebug 
	LLVM:          supported, not enabled.
	GC:            sgen

続いて、先ほど用意したスクリプトを読み込んだあとでmono -Vを実行し、新しくインストールしたmonoが動作することを確認する。

$ source mono-master-env

$ which mono
/opt/mono/master/bin/mono

$ mono -V
Mono JIT compiler version 5.7.0 (master/aa7cd58 2017年  8月 17日 木曜日 17:40:46 JST)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
	TLS:           __thread
	SIGSEGV:       altstack
	Notifications: epoll
	Architecture:  amd64
	Disabled:      none
	Misc:          softdebug 
	LLVM:          supported, not enabled.
	GC:            sgen (concurrent by default)

§3.4.3 GAC

gacutil2 -lでアセンブリがGACに登録されていることを確認する。

$ gacutil2 -l 
The following assemblies are installed into the GAC:
  :
System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.ComponentModel.Composition, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.ComponentModel.DataAnnotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
System.Configuration.Install, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
  :

GACのパスを明示的に指定する場合は-rootオプションで指定する。 例えばgacutil2 -l -root /opt/mono/master/lib/など)

§3.4.4 mcs(C#コンパイラ)・mono(Monoランタイム)

mcs(C#コンパイラ)およびmono(Monoランタイム)の動作を確認する。

test.cs
using System;

class Test {
  static void Main()
  {
    Console.WriteLine(Environment.Version);
  }
}
$ mcs test.cs && mono test.exe
4.0.30319.42000

MonoのC#コンパイラであるmcsは、.NET Frameworkのcscコンパイラと同じコンパイルオプションを指定してコンパイルすることができる。 コンパイルして作成した実行可能ファイルは直接実行する代わりにmono test.exeのようにmonoコマンドを使って実行する。


LLVMバックエンドを有効にした場合の動作を確認する。 mono --llvmとすることでLLVMバックエンドを有効にした状態でmonoランタイムを実行させることができる。

$ mono -v --llvm test.exe | grep "Main"
converting llvm method Test:Main ()
LLVM Method Test:Main () emitted at 0xb603de70 to 0xb603de84 (code length 20) [test.exe]
$ mono -v test.exe | grep "Main"
converting method Test:Main ()
Method Test:Main () emitted at 0xb605dce8 to 0xb605dd05 (code length 29) [test.exe]

§3.4.5 csharp(C#シェル)

csharpシェルが動作するか確認する。

$ csharp -e 'Environment.Version;'
4.0.30319.42000

$ csharp -e 'Environment.OSVersion;'
Unix 4.4.0.89

$ csharp
Mono C# Shell, type "help;" for help

Enter statements below.
csharp> Enumerable.Range(0, 10).Sum();
45
csharp> quit; 

§4 その他のアセンブリ・ライブラリ

§4.1 mono-basic

VB.NETコンパイラやMicrosoft.VisualBasic.dllを使用する場合は、mono-basicをインストールする。

ソースのチェックアウトとautogen、configure。

git clone git://github.com/mono/mono-basic.git
cd mono-basic/
./configure --prefix=/opt/mono/master/

configureの結果例。

mono-basic 4.0.1 module configured to use prefix=/opt/mono/master/

問題が無ければ、make, make installする。

make
sudo make install

vbnc2(VB.NETコンパイラ)の動作を確認する。

test.vb
Imports System

Module Test
  Sub Main()
    Console.WriteLine("Hello, world!")
  End Sub
End Module
$ vbnc2 test.vb && mono test.exe
Visual Basic.Net Compiler version 0.0.0.5943 (Mono 4.0.1 - master/b8011b2)
Copyright (C) 2004-2010 Rolf Bjarne Kvinge. All rights reserved.

Assembly 'test, Version=0.0, Culture=neutral, PublicKeyToken=null' saved successfully to '/home/smdn/test.exe'.
Compilation successful
Compilation took 00:00:01.4471880
WARNING: The runtime version supported by this application is unavailable.
Using default runtime: v4.0.30319
Hello, world!

§5 トラブルシューティング

§5.1 System.Drawing.dllがTypeInitializationExceptionスローする

以下のようにSystem.Drawing.dllのメンバを参照しようとした際にTypeInitializationExceptionがスローされる場合の対処について。

$ mcs test.cs -r:System.Drawing.dll && mono test.exe

Unhandled Exception:
System.TypeInitializationException: The type initializer for 'System.Drawing.GDIPlus' threw an exception. ---> System.DllNotFoundException: /opt/mono/master/
  at (wrapper managed-to-native) System.Drawing.GDIPlus:GdiplusStartup (ulong&,System.Drawing.GdiplusStartupInput&,System.Drawing.GdiplusStartupOutput&)
  at System.Drawing.GDIPlus..cctor () [0x000cc] in <1917aa1c39d94b1a91807b8cd9f03350>:0 
   --- End of inner exception stack trace ---
  at System.Drawing.Bitmap..ctor (System.String filename, System.Boolean useIcm) [0x0002b] in <1917aa1c39d94b1a91807b8cd9f03350>:0 
  at System.Drawing.Bitmap..ctor (System.String filename) [0x00000] in <1917aa1c39d94b1a91807b8cd9f03350>:0 
  at (wrapper remoting-invoke-with-check) System.Drawing.Bitmap:.ctor (string)
  at Test.Main () [0x00000] in <8d1ccbab6ffd4bc3b78e43e6e0f0b3a5>:0 

上記のようにTypeInitializationExceptionがスローされ、さらにその原因として<prefix>が見つからずにDllNotFoundExceptionがスローされている場合は、libgdiplus.soのパス解決に失敗している。

この場合、<&var{prefix};>/etc/mono/configを以下のように修正する。 (ここで、<prefix>configure--prefixオプションで指定したインストール先のパス。 ここでは/opt/mono/master。)

<prefix>/etc/mono/config
@@ -29,8 +29,8 @@
 		<dllentry dll="__Internal" name="MoveMemory" target="mono_win32_compat_MoveMemory"/>
 		<dllentry dll="__Internal" name="ZeroMemory" target="mono_win32_compat_ZeroMemory"/>
 	</dllmap>
-	<dllmap dll="gdiplus" target="/opt/mono/master/" os="!windows"/>
-	<dllmap dll="gdiplus.dll" target="/opt/mono/master/"  os="!windows"/>
-	<dllmap dll="gdi32" target="/opt/mono/master/" os="!windows"/>
-	<dllmap dll="gdi32.dll" target="/opt/mono/master/" os="!windows"/>
+	<dllmap dll="gdiplus" target="/opt/mono/master/lib/libgdiplus.so" os="!windows"/>
+	<dllmap dll="gdiplus.dll" target="/opt/mono/master/lib/libgdiplus.so"  os="!windows"/>
+	<dllmap dll="gdi32" target="/opt/mono/master/lib/libgdiplus.so" os="!windows"/>
+	<dllmap dll="gdi32.dll" target="/opt/mono/master/lib/libgdiplus.so" os="!windows"/>
 </configuration>

インストール先の<&var{prefix};>/etc/mono/configを編集できない場合は、/home/user/.mono/configに同様のファイルを配置してそこに記述することもできる。