Click here to Skip to main content
Click here to Skip to main content
Go to top

How to build Mono 3.4.0 / 3.4.1 / 3.6.1 on Windows

, 8 Sep 2014
Rate this:
Please Sign up or sign in to vote.
A refreshed article on how to build the older releases of 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 areready 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 see 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

(1) 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"

(2) 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 builds (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

NB. 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 feed back all corrections, questions and comments to me here.

History

11/05/2014 Initial Release
10/06/2014 Added get-monolite-latest step when using current source from git repository

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Alex J Lennon
CEO Dynamic Devices Ltd
United Kingdom United Kingdom
Founded Dynamic Devices in 2004 to deliver high quality embedded solutions.
 
Alex is an experienced engineer with a deep knowledge and wide experience of both software development and project management. He has provided cutting edge hardware and software design solutions to industry in the United States and Europe and has successfully brought a wide range of products to market.
 
His technical expertise includes the architectural design and development of embedded systems software, deployment of large scale assured data delivery systems and the creation of low-level device drivers in a number of languages.
 
During the past decade Alex has worked predominantly with Linux and Windows CE based embedded and wireless devices, customizing O.S builds, developing device drivers, and creating internet-aware mobile applications with accessible user interfaces.
 
Specialties:Embedded Linux and Windows CE platform ports, device driver development, application development, C#, C, Java, GSM GPRS/UMTS, Wireless, Mesh
Follow on   LinkedIn

Comments and Discussions

 
QuestionBuilding mono 3.6.1 from Git requires additional step before make [modified] PinmemberMangoIce10-Jun-14 3:31 
Thanks a lot for this amazingly detailed and well written article. It did save me a lot of time.
I did clone the latest mono from git for the first time on an empty Windows 8.1 box.
This requires additional step before make:
$ make get-monolite-latest
 
so the following section in the article:
Then setup and kick-off the build
$ ./autogen.sh --prefix="C:\monoinstall" --with-preview=yes
$ ./configure --host=i686-pc-mingw32
$ make
 

should read like:
Then setup and kick-off the build
$ ./autogen.sh --prefix="C:\monoinstall" --with-preview=yes
$ ./configure --host=i686-pc-mingw32
$ make get-monolite-latest
$ make
 

to avoid build failure with the error below:
*** [build/deps/basic-profile-check.exe] Error 127
*** The compiler 'gmcs' doesn't appear to be usable.
*** You need Mono version 2.4 or better installed to build MCS
*** Check mono README for information on how to bootstrap a Mono installation.


modified 10-Jun-14 14:50pm.

AnswerRe: Building mono 3.6.1 from Git requires additional step before make PinmemberAlex J Lennon10-Jun-14 3:36 
GeneralRe: Building mono 3.6.1 from Git requires additional step before make PinmemberMangoIce10-Jun-14 8:56 
GeneralRe: Building mono 3.6.1 from Git requires additional step before make PinmemberAlex J Lennon10-Jun-14 22:35 
QuestionMicrosoft.Portable.Common.targets contains invalid XML Pinmembercocowalla28-May-14 2:45 
AnswerRe: Microsoft.Portable.Common.targets contains invalid XML [modified] PinmemberAlex J Lennon28-May-14 2:48 
QuestionDirectory path lengths Pinmembermpderbec12-May-14 6:16 
AnswerRe: Directory path lengths PinmemberAlex J Lennon12-May-14 6:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140905.1 | Last Updated 8 Sep 2014
Article Copyright 2014 by Alex J Lennon
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid