Introduction
Update: I now have Mono building in an automated fashion on the Appveyor CI platform. To achieve this a configuration script was created which Appeyor uses to install dependencies, autogen, configure, make and install Mono. The resulting binaries are packaged up as artifacts for further testing and use. For further details see this Appveyor project and the configuration script.
If you are just looking for Mono 3.8.0 binaries to use, I have provided the resulting binaries from this walk-through here.
If you are looking for Mono 3.10.0 binaries to use, I have provided the resulting binaries from this walk-through here.
This article builds on and updates a number of existing articles which attempt to describe the build process for Mono on Windows.
It is taken from my previous article here which covers build of Mono 3.4.0 - 3.6.1. The older article may still be of use to people wishing to build older variants of Mono, so rather than update it, I have taken the core and refreshed it into this piece.
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.8.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 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-runtime, 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.8.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.8.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
NOTE: The following steps reference 3.8.0 but are applicable to 3.10.0. However 3.10.0 was released with a broken Windows build as of 17/10/2014 so ensure to follow the additional step to patch the problem
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.8.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.8.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:
Host: i686-pc-mingw32
Target: i686-pc-mingw32
GC: sgen and Included 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
Fix-up: Mono 3.10.0 - patch mono/utils/sha1.h
The Mono 3.10.0 release, as of 17/10/14, fails with the following error
libtool: compile: i686-pc-mingw32-gcc -DHAVE_CONFIG_H -I. -I../..
-I../.. -I../../mono -I../../libgc/include -I../../eglib/src
-I../../eglib/src -DWINVER=0x0502 -D_WIN32_WINNT=0x0502
-D_WIN32_IE=0x0501 -D_UNICODE -DUNICODE -DWIN32_THREADS
-DFD_SETSIZE=1024 -g -O2 -fno-strict-aliasing -fwrapv
-Wdeclaration-after-statement -Wno-unused-but-set-variable -g -Wall
-Wunused -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes
-Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wno-cast-qual
-Wwrite-strings -Wno-switch -Wno-switch-enum -Wno-unused-value
-mno-tls-direct-seg-refs -Werror-implicit-function-declaration -MT
sha1.lo -MD -MP -MF .deps/sha1.Tpo -c sha1.c -DDLL_EXPORT -DPIC -o
.libs/sha1.o
In file included from sha1.c:20:0:
./sha1.h:25:1: error: expected '=', ',', ';', 'asm' or '__attribute__'
A change needs to be made to mono/utils/sha1.h to fix this
Edit the file to change __BEGIN_DECLS to G_BEGIN_DECLS and _END_DECLS to G_END_DECLS
G_BEGIN_DECLS
void SHA1Init(SHA1_CTX *);
void SHA1Pad(SHA1_CTX *);
void SHA1Transform(guint32 [5], const guint8 [SHA1_BLOCK_LENGTH]);
void SHA1Update(SHA1_CTX *, const guint8 *, size_t);
void SHA1Final(guint8 [SHA1_DIGEST_LENGTH], SHA1_CTX *);
char *SHA1End(SHA1_CTX *, char *);
char *SHA1File(const char *, char *);
char *SHA1FileChunk(const char *, char *, off_t, off_t);
char *SHA1Data(const guint8 *, size_t, char *);
G_END_DECLS
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.
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.8.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.8.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) You may get build failures due to a missing mcs.bat file, e.g.:
Build failed. The specified executable is not a valid application for this OS platform.
If so, you need to delete the mcs file in the installation folder and copy across the mcs.bat file from your existing Mono installation.
$ cd /cygdrive/monoinstall/bin
$ rm mcs
$ cp /cygdrive/c/Program Files (x86)/Mono-3.2.3/bin/mcs.bat /cygdrive/c/monoinstall/bin
(2) You may 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 uncheck "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.8.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.8.x) 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 813d6610ecafd24e5cf428938b342810d70d5c25
.
You may choose to check this out too with:
$ cd mono
$ git checkout 813d6610ecafd24e5cf428938b342810d70d5c25
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
Post-build, you will need to mount /usr/local, install the files, add mono.exe and remove the symlink as detailed above. Also, you will need to remove mcs and add mcs.bat.
$ 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
$ rm mcs
$ cp /cygdrive/c/Program Files (x86)/Mono-3.2.3/bin/mcs.bat /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 here.
History
- 11/05/2014 Initial release (Building Mono 3.4)
- 10/06/2014 Added get-monolite-latest step when using current source from git repository
- 05/09/2014 Release of Building Mono 3.8, based on Mono 3.4 article
- 17/10/2014 Added fixups to build Mono 3.10
- 27/10/2014 Added notes on Appveyor build