Mono, the open source implementation of the CLR, is not just for non-Microsoft
platforms. In this article I will walk you through the three phases required
to build Mono on Windows without using
the .NET framework. There have already been several build processes available
before, but they mostly required using the csc.exe C# compiler from the Microsoft
.NET framework. This process is distinct in that you will use the mcs.exe Mono
C# compiler.
As I mentioned above, there are three phases in this build process:
make steps.make, and make install commands.This article finishes with a call to arms for the Mono community to improve the build and deployment process for Windows.
Requirements for this process:
|
Related Reading
Mono: A Developer's Notebook |
The first phase of the build process is to install the Cygwin environment. If previous attempts have failed, it is critical that you exorcise these demons from your machine. This is important, because if the Cygwin installer should find the remnants of a previous installation, it will follow the registry keys left and may corrupt the installation. It is always best to start with a clean system.
Note: You can skip this step and proceed to the environment setup if your system does not currently contain Cygwin.
The steps to remove a previous installation of Cygwin are as follows:
Shift and Delete simultaneously. Select
Yes from the Confirm File Delete dialog.Shift and Delete. Select Yes from the
Confirm File Delete dialog.Shift and Delete. Select Yes from the Confirm File Delete dialog. HKEY_LOCAL_MACHINE key and expand the
key. Locate the SOFTWARE key and expand it. Click on the "Cygnus Software" key and press the Delete key.These instructions should remove all traces of Cygwin, and you should be ready to begin the setup for the Mono build process.
The first phase of building
Mono involves
installing Cygwin. As mentioned in the requirements, I recommend the
1.5.7-1 version, built on 2004-01-30. You might be asking, "What is so
special about this particular build of the Cygwin environment?" Well, at
some point, Cygwin began including GNOME components as part of their X
for Windows. The underlying glib2 that the bundled GNOME/GTK+
uses is incompatible with one of the REQUIRED compiler flags, --
CC="gcc -nno-cygwin". Therefore you can use the newer Cygwin,
but you would have to go through great lengths to remove any of the
GNOME/GTK+ components before you can compile Mono
for Win32 in a way that results in an independent system (independent
of Cygwin after its initial compilation). There is a PDF
available that lists the contents of the
"magic" 1.5.7-1 release. It includes all of the packages and their
respective versions. If you have to use a Cygwin release after 1.5.7-1,
then delete any package that does not
appear in this list.
I will assume that you have the following pre-setup:
setup.exe and associated setup.ini.The following steps will lead you through the Cygwin installation process:

Figure 1. Setting up Cygwin
Note: This will take some time, so just keep an eye on the progress bars to verify progress.
Note: At this point, the Cygwin installation is complete; however, there are a few more steps to finish the environment setup.
Enter.PATH. To make these changes inside the Cygwin
environment, use the following instructions. (Note: You
may encounter difficulty
if you attempt to use a Windows text editor to make these changes. It
may introduce CR/LF characters into the file instead of the LF
characters Cygwin is used to.)
vi ./.bashrc to edit the file. At this
point, you should see the contents of the file and should be able to navigate
using the arrow keys.vi
session). Simply copy the text from Figure 2, and then click on the
Cygwin icon in the title bar of the Cygwin window. Select Edit and then
select Paste. That should fill in the text. You can also just type it
all in; that is, if you like typing.Escape when you are finished.vi line command prompt.Enter. This will write
the file to disk and quit the vi editor. Note: You need to exit and
re-enter Cygwin for these environment variables to become active.
#Environment Variables for Mono
export PATH="/usr/local/bin:/usr/local/lib:$PATH:/usr/local/icu/bin"
export ACLOCAL_FLAGS="-I /usr/share/aclocal"
export CPPFLAGS="$CPPFLAGS -I/usr/local/include"
export LDFLAGS="$LDFLAGS -L/usr/local/lib"
export CC="gcc -mno-cygwin"
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:/usr/lib/pkgconfig"
export LD_LIBRARY_PATH="/usr/local/lib:/usr/lib"
export MONO_PATH="/usr/local/lib:/usr/lib:$MONO_PATH"
export MONO_CFG_PATH="/usr/local/etc:/usr/etc:$MONO_CFG_PATH"
#Environment variables for .NET if not already in your Windows PATH
#These variables could be needed by older Mono build systems
#export PATH=$PATH:`GetNetSdkLocation -cs msnet_1.1`/v1.1.4322
#export PATH=$PATH:`GetNetSdkLocation -cs msnetsdk_1.1`/Bin
Figure 2: Setting up the environment
mkdir -p /download/tarball/.
Also make a sub-directory for the build directory; enter mkdir -p
/download/mono-x.x.x (where x.x.x represents the release number).cd / and pressing Enter.tar -xjvf /download/tarball/perl-XML-Parser-2.34-1.tar.bz2
and press Enter. This will uncompress the necessary files and place
them in the correct directory locations.If you already have the latest development version of Mono installed, you can skip this section. If not, then in this second phase you will need to download the combined installer and complete the installation.

Figure 3. Installing Mono
|
The last phase of the build process will require you to obtain a copy of the Mono source code. The recommended way to accomplish this is by using anonymous Subversion checkout. The Mono project uses Subversion as its source code management tool. In order to use Subversion, you first need to have a Subversion client installed on your machine. Finally, once you have Subversion installed, and you have checked out and exported the Mono source code, then you can complete the build steps.
If you already have the Subversion, then you can skip this section. You will need to obtain the the Windows installer with the basic Subversion Win32 binaries. You can obtain the installer from the Tigris.org documents and files area.
When your system restarts, you should verify that the Tortoise Subversion Windows Explorer plugin was successfully installed. From within Explorer, right-click on any directory. You should see a new menu item: TortoiseSVN. Click on this entry and you should see another menu list. Select the About menu option. You should receive the TortoiseSVN 1.1.1, Build 1857 about dialog box.
In order to build Mono, you will need to
check out three source subtrees: mono, mcs, and libgdiplus. To anonymously check out
the Mono source code:
mcs and libgdiplus subtrees. In
the checkout step, substitute
the subtree at the end of the repository URL, for example:
"svn://svn.myrealbox.com/source/trunk/mcs".You are now almost ready to begin the build process. You first need to take care of few preparatory steps and then you'll be ready for the build. These fews steps will redirect the calls for the C# compiler to the Mono C# compiler, allowing you to build Mono with Mono. To finish our preparations, complete the following:
mkdir -p /opt/mono and press Enter.mount -s c:/mono/Mono-1.1.3
/usr/local and press Enter.ln -s /usr/local/bin/mcs
./csc.exe and press Enter. This will substitute the Mono C# compiler
for the C# compiler. You can test this by typing csc.exe --version.
You should receive the result shown in Figure 4.

Figure 4. Checking the CSC version
ln -s
/usr/local/bin/monoresgen.exe ./resgen.exe and press Enter. This will
substitute the Mono Resource File Generator for the .NET Framework
Resource File Generator. Confirm this by typing resgen.exe. You
should receive the result shown in Figure 5.

Figure 5. Generating the resources
Finally,
you are ready to build Mono with
Mono. From the mono subdirectory, you will complete the three-step
build process involving autogen, make, and make install. To finish the
process:
cd
/download/mono-1.1.4/mono and press Enter. This will put you in the
Mono directory of the source code../autogen.sh --prefix=/opt/mono
--with-preview=yes and press Enter. If autogen encounters any problems
with the environment or in terms of dependencies, it will stop. If the
process does not halt, you should receive a long stream of console
comments; at the end, however, it should resemble Figure 6.
make and press Enter. The make
command will take a few minutes, so please be patient. Also, just as
with the autogen command, the make command will produce a long stream
of console comments. What you should be alert for is any type of error
message that appears immediately before the make command completes. The
output should look like Figure 7.

Figure 7. Making Mono
make install and press Enter. Once
again, this will take a few minutes. A successful make install should
look like Figure 8.
Now that you have successfully built Mono, you now have a directory structure in /opt/mono that is similar to the one that the Mono Combined installer creates for Win32. Keep in mind that the resulting output does not include GTK+, Gtk#, MonoDoc, or XSP. Also missing are prerequisites that almost never change and that originate from other parties like Microsoft (as in the case for msvcr71.dll, found in C:\mono\Mono-1.1.3\bin). However, you now have the essence of the latest Mono release. Your options at this point include repackaging all of the framework and its supporting components or just using a particular library or executable that you know was just fixed in SVN.
To verify the results of the build process,
change to the prefix directory, /opt/mono, and study its
contents and structure. There are two significant kinds of files
created in the directory hierarchy. There are binary files like
/opt/mono/lib/mono/1.0/mcs.exe and /opt/mono/lib/mono/1.0/System.Xml.dll.
These are examples of managed
assemblies. Other resulting binary files include unmanaged
executables and static libraries such as /opt/mono/bin/monodis.exe and
/opt/mono/lib/libmono.a.
The build process also creates many
configuration and/or supporting files that might contain file PATH
information that is specific to the choices made when autogen.sh was
run for the first time (remember ./autogen.sh --prefix=/opt/mono
--with-preview=yes? Refer to 3.4, "Building Mono With Mono").
Examples of these files are /opt/mono/lib/pkgconfig/mono.pc and
/opt/mono/bin/ilasm. These are generic text files, so you can
edit
their contents with any ASCII-friendly text editor. Changing these
files is a critical function of the Windows Combined Installer, as you
will now see.
In theory, you could take all of the child
directories that are found in /opt/mono and simply copy and paste
them over to C:\mono\Mono-1.1.3. Unfortunately, the text
files
that I mentioned above contain an unusable path reference to /opt/mono.
The Windows operating system would not be able to resolve this path, and
your Mono installation would not work. Remember, that path is only
viable in the Cygwin environment, which is not required to run the
resulting Mono in Win32. You would also be missing some batch
files that parallel the shell scripts. The batch files are
the
ones that actually invoke the execution of the Mono runtime
(C:\mono\Mono-1.1.3\bin\mono.bat) and indispensable tools like gacutil
(C:\mono\Mono-1.1.3\bin\gacutil.bat) while in Windows. In fact, if you
were to look at the Inno
Setup installer script that was
used to
generate mono-1.1.3-gtksharp-1.9.1-win32-0.4.exe, you will notice that
the largest portion of the script goes to
searching and replacing a constant, C:\Target, by the path that the
user selects during the installation routine.
Today, building and deploying Mono on the Win32 platform without the Win32 Mono Combined installer requires extensive manual intervention. This must change. The Linux Mono community enjoys great autonomy with the Linux build process. As I have described, it is clear that the Windows Mono community does not share that same autonomy. I understand that this is partially because Mono originates from a Linux-friendly environment. However, I'm sure that the same spirit of innovation and ingenuity that has distinguished the Mono project thus far, can also help resolve this disparity. Therefore, I urge the Mono community and especially the core Mono team to provide the necessary guidance, resources, and focus to help automate the Windows build and deployment process. I'm sure that if we accomplish this goal, we will unleash significant pent-up demand for the Mono project from the Windows C# community. And if there's anything I've learned about open source software, is that it is all about the community, and the bigger the community the better.
As has been the case for me so many times before, this effort would not be possible without the determination and drive of my good friend Francisco (Paco) Martinez. Through countless hours and cups of coffee, he perfected this process and then made it seem simple as we went through it step by step. Eric Raymond once said that you're not a hacker until someone calls you one, so I'm here to say: "Paco is a hacker extraordinaire." With the continued support of O'Reilly Network, we look forward to sharing many other articles focusing on Mono for Windows geeks.
Kevin Shockey is an emerging high technology entrepreneur.
Return to ONDotnet.com.
Copyright © 2009 O'Reilly Media, Inc.