This article builds on and updates many existing articles that have made an attempt to describe the build process for Mono on Windows.
Introduction
NOTE: There is an updated version of this article available here, covering Mono 3.8.0 for Windows.
This article builds on and updates a number of existing articles which attempt to describe the build process for Mono on Windows.
If you are just looking for Mono 3.4.0 binaries to use, I have provided the resulting binaries from this walk-through here.
The baseline instructions from the Mono project can be found here.
In theory, these should be enough to get Mono compiled but, as ever in the real world, things are slightly more complex. As a result, others have written pieces on how to build Mono, and I have found "Building Mono on Windows: The Final Battle" particularly useful.
That said, these articles are now a few years old and I ran into various issues building Mono which I have attempted to address with the walk-through below.
We are going to look both at building from the current, at the time of writing, Mono release tarball (3.4.0) and then at building the "latest and greatest" directory out of the git repository.
The sequence of events is as follows:
- Install pre-compiled Mono
- Install & configure Cygwin
- Retrieve and extract tarball Mono Sources
- Build and Mono
- Modify Cygwin/Mono to address any build failures
- Install Mono and modify installation
- Fix-ups/workarounds for Xamarin Studio
- Retrieve and build git Mono Sources
This walk-through has been tested on an x64 machine running Windows 8.1.
Install Pre-Compiled Mono Binaries
A stable, pre-compiled build of Mono 3.2.3 can be downloaded here. Download and install this.
Check that it runs by opening a Mono command prompt from the start bar and typing:
mono --version
You should see Mono come up and the 3.2.3 version shown:
C:\Program Files (x86)\Mono-3.2.3>mono --version
Mono JIT compiler version 2.10.9 (tarball)
Copyright (C) 2002-2011 Novell, Inc, Xamarin, Inc and Contributors. www.mono-pro
ject.com
TLS: normal
SIGSEGV: normal
Notification: Thread + polling
Architecture: x86
Disabled: none
Misc: softdebug
LLVM: supported, not enabled.
GC: Included Boehm (with typed GC and Parallel Mark)
C:\Program Files (x86)\Mono-3.2.3>
Install Cygwin
Download and install the 32-bit version of Cygwin, which is a Unix-on-Windows tool-suite and which is used by the Mono build system. The setup bootstrap can be found here.
As you run through the setup process, you will be given the option to specify needed packages. The packages we need to build Mono aren't installed by default, so make sure to select each of these.
The Mono on Windows instructions give more in depth details, and indicate we need the following:
autoconf, automake,bison, gcc-core, gcc-g++,mingw-gcc, libtool, make, python,
The Final Battle instructions indicate some additional packages that we also need to have installed:
gettext-devel, gettext, intltool, libiconv, pkg-config
Other nice to have packages are:
wget, zip patch, openssh, vim
Configure Cygwin
It has been suggested to me on the mono-dev mailing list that Cygwin needs to be configured to mount the host system drive with a "noacl
" option, or there may be issues with file accesses. For details, see here and here.
Following these instructions, open a Cygwin terminal from the start bar and edit /etc/fstab:
# For a description of the file format, see the Users Guide
# http://cygwin.com/cygwin-ug-net/using.html#mount-table
# This is default anyway:
none /cygdrive cygdrive binary,posix=0,user 0 0
Add in the noacl
option as follows:
# For a description of the file format, see the Users Guide
# http://cygwin.com/cygwin-ug-net/using.html#mount-table
# This is default anyway:
none /cygdrive cygdrive binary,noacl,posix=0,user 0 0
You may then wish to close and reopen the Cygwin terminal to ensure this change takes effect. You can check the changes by running the 'mount
' command to see the 'noacl
' option in the output.
Retrieve Mono Release tarball
At the time of writing, the latest Mono sources release tarball is 3.4.0. There is no Windows installer for this build, the latest being 3.2.3. We will build a working set of Mono 3.4.0 binaries here.
Retrieve the Mono 3.4.0 sources from the link here. Extract them to your file-system.
You should retrieve and extract files within Cygwin. It is possible to retrieve and extract files outside of Cygwin, but without care, you may find that line endings (CRLF) have been modified which will cause problems with the build.
So open the Cygwin terminal:
$ cd /cygdrive/c $ mkdir monosources$ cd monosources
$ wget http://download.mono-project.com/sources/mono/mono-3.4.0.tar.bz2
$ tar xjvf mono-3.4.0.tar.bz2
Note: It is important that you put your source code in a relatively short path, as you may otherwise run into problems with the Windows MAX_PATH
limit (thanks mpderbec). Also, it has been reported that building as a Windows user with a space in the user-name may cause issues.
Build from Mono Release tarball
There can be build errors when building Mono, such as with missing files or with conflicts with Cygwin headers. When errors occur, we will address them with the instructions that follow, but for now, we will start a build of Mono to see how far we get.
We are going to make a destination folder for the Mono 3.4.0 installation, and we are going to configure the build for future installation to that folder, so
$ cd /cygdrive/c
$ mkdir monoinstall
$ cd monosources/mono-3.4.0
$ ./autogen.sh --prefix="C:\monoinstall" --with-preview=yes
NOTE: We are using the Win32 path specifier format for --prefix
NOT the Cygwin/*nix
format.
Autogen should complete successfully and we then configure the build, as recommended by autogen
$ ./configure --host=i686-pc-mingw32
At the end of the configuration process, we should see something similar to the following:
mcs source: mcs
Engine:
GC: sgen and bundled Boehm GC with typed GC and parallel mark
TLS: pthread
SIGALTSTACK: no
Engine: Building and using the JIT
oprofile: no
BigArrays: no
DTrace: no
LLVM Back End: no (dynamically loaded: no)
Libraries:
.NET 2.0/3.5: yes
.NET 4.0: yes
.NET 4.5: yes
MonoDroid: no
MonoTouch: no
Xamarin.Mac: no
JNI support: no
libgdiplus: assumed to be installed
zlib:
Once configuration succeeds, we can then begin the build proper with:
$ make
Build Failure #1 - PEXECUTION_STATE
The first build failure is due to an interaction between the Mono definition of PEXECUTION_STATE
and the Cygwin definition of the same variable. This results in a failure to build with error output similar to this:
/usr/i686-pc-mingw32/sys-root/mingw/include/ddk/ntapi.h:49:15:
error: conflicting types for 'PEXECUTION_STATE'
In file included from
/usr/i686-pc-mingw32/sys-root/mingw/include/windows.h:62:0,
from
/usr/i686-pc-mingw32/sys-root/mingw/include/winsock2.h:40,
from ../../mono/io-layer/io-layer.h:24,
from ../../mono/metadata/domain-internals.h:15,
from ../../mono/metadata/metadata-internals.h:8,
from ../../mono/metadata/class-internals.h:10,
from ../../mono/metadata/object-internals.h:8,
from process.c:16:
The recommended workaround is to edit the Cygin header file, within Cygwin to change the definition of PEXECUTION_STATE
to something else, e.g.
$ nano /usr/i686-pc-mingw32/sys-root/mingw/include/ddk/ntapi.h
Change:
/* FIXME: Unknown definitions */
typedef PVOID POBJECT_TYPE_LIST;
typedef PVOID PEXECUTION_STATE;
typedef PVOID PLANGID;
to read:
/* FIXME: Unknown definitions */
typedef PVOID POBJECT_TYPE_LIST;
typedef PVOID PEXECUTION_STATE_WORKAROUND;
typedef PVOID PLANGID;
Now kick off the build process again with:
$ make
Install build Mono files
Once the build has successfully completed, you can then go ahead and install to the target folder.
First, we will need to mount the folder within Cygwin, using:
$ mount "C:\monoinstall" /usr/local
NOTE: I have found that if I have this mounted during the preceding build process, then I get errors relating to libiconv
. This may be addressed with the 'noacl
' fix, but for now, the suggestion is that the mount should not be made until after make has completed successfully and we are ready to install.
Installation Failure #2 - Missing Target File
There is a missing file that should be present in the Mono 3.4.0 release tarball. For details, please take a look here.
You need to add this file in manually by creating a file:
$ nano mcs/tools/xbuild/targets/Microsoft.Portable.Common.targets
This file should contain the following:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\Microsoft.Portable.Core.props" />
<Import Project="..\Microsoft.Portable.Core.targets" />
</Project>
Install the Files
$ make install
Fix-up: Installation Issues - mono.exe
For some reason, the installation does not copy across a Win32 executable mono.exe.
This appears to be a stub function and can be copied across from your existing Mono installation, e.g.:
copy C:\Program Files (x86)\Mono-3.2.3\bin\mono.exe to C:\monoinstall\bin
With this fix-up in place, you can now execute Mono under Windows and check you have the correct version. Open a Windows command box and type:
cd c:\monoinstall\bin
mono --version
You should see something similar to the following:
Mono JIT compiler version 3.4.0 (tarball)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
TLS: normal
SIGSEGV: normal
Notification: Thread + polling
Architecture: x86
Disabled: none
Misc: softdebug
LLVM: supported, not enabled.
GC: sgen
Fix-up: Xamarin Studio - Extraneous symlink File Prevents Addition of Run-Time
If you now try to add this Mono 3.4.0 runtime to Xamarin Studio using Tools->Options, Projects->.NET Runtimes. Add, this will fail with an error message "Mono runtime not found".
This is because of the presence of an extraneous symlink file copied across during the installation.
You may not be able to see this with Windows Explorer or dir in a command box, although dir /a should show it.
If you have trouble deleting under Windows, then use a Cygwin terminal and enter:
$ cd /cygdrive/monoinstall/bin
$ rm mono
You should now be able to add the runtime to Xamarin Studio.
Workarounds: Issues With Building Projects Under Xamarin Studio
- Mono 3.x fails to build projects for me with recent Xamarin Studio builds. The error given is:
Build failed. Could not find type 'System.Globalization.SortVersion'.
This appears to be addressed in this commit which is not present in 3.4.0.
The workaround is to use an older version of Xamarin Studio as discussed here.
i.e., Download Xamarin Studio 4.2.3 from your account at Xamarin.com with "view all versions".
- You may then get a build error about UNC paths:
Error: Error building target GetReferenceAssemblyPaths:
UNC paths should be of the form \\server\share
This appears to relate to extra \\'s in configuration files as discussed here.
The workaround is to go to project options and unback "Use MSBuild engine" at which point you will be able to compile and debug applications.
Building Mono from the git Repository
At the time of writing, the sequence of events is similar to building from the 3.4.0 release tarball. It is likely that as time moves on, existing build issues will be addressed and there may be new build issues encountered so my suggestion is that you start by checking out the same git hash as the one used in this walk-through, verify that build (3.4.1) and then try again having checked out master.
As detailed above, you will need the Cygwin packages installed, and the modification to PEXECUTION_STATE
.
Open up a Cygwin terminal and:
$ cd /cygdrive/c/monosources
$ git clone git://github.com/mono/mono.git
We are working with git checkout 079c2e126f594c5a338a779c72a899951de38960
.
You may choose to check this out too with:
$ cd mono
$ git checkout 079c2e126f594c5a338a779c72a899951de38960
Make sure /usr/local is not mounted or you may get libiconv
-related build failures.
$ umount /usr/local
Then setup and kick-off the build:
$ ./autogen.sh --prefix="C:\monoinstall" --with-preview=yes
$ ./configure --host=i686-pc-mingw32
$ make
N.B. If you are using the latest Mono sources as of 10/06/14, there is an additional step needed to download monolite (thanks to @Mangolce for reporting this):
$ ./autogen.sh --prefix="C:\monoinstall" --with-preview=yes
$ ./configure --host=i686-pc-mingw32
$ make get-monolite-latest
$ make
Post-build, you will need to mount /usr/local, install the files, add mono.exe and remove the symlink
as detailed above:
$ mount "C:\monoinstall" /usr/local
$ make install
$ cd /cygdrive/c/monoinstall/bin
$ rm mono
$ cp /cygdrive/c/Program Files (x86)/Mono-3.2.3/bin/mono.exe /cygdrive/c/monoinstall/bin
At this point, you should have the latest and greatest Mono ready to run! You can open a Windows cmd box and enter:
C:\> cd c:\monoinstall\bin
C:\monoinstall\bin> mono --version
You may now wish to checkout the git master within the Cygwin terminal and build the very latest Mono sources.
$ cd /cygdrive/c/monosources/mono
$ git checkout master
Feedback
It is my intention to try to maintain and update this document as new releases of Mono become available.
Please feel free to feedback all corrections, questions and comments to me by leaving a comment below:
History
- 11th May, 2014: Initial release
- 10th June, 2014: Added get-monolite-latest step when using current source from git repository