[Mono-devel-list] A how to for Mono on OS X Panther Building (w/ JIT and GC to boot)

Dave Morford david at morford.org
Mon Jan 26 06:22:39 EST 2004

Building Mono on OS X has always been a chore. Many OS X users are new 
the platform, new to the tool chains involved in building open source 
libraries and applications and accustomed to IDE environments or better 
documented (but not particularly better) and integrated build systems.

Thus we've been of little help. I think we can now change that. The 
work on the PPC JIT combined with huge number of UNIX/Linux changes and 
additions in OS X Panther seem to have converged enough to get working 
into DarwinPorts and Fink. However the garbage collector has been 
problematic as has been the different runtime architecture of the 
Mach-O format and shared dynamic libraries and the subtle and annoying 
conflicts between GNU libtool, the built-in libtool on OS X which has 
nothing to do with the GNU tool chain and the various compiler and 
linker flags to disable the Apple Preprocessor, choosing between flat 
and two-level namespaces and improper or flags that are unneeded such 
as -pthread, which is built into libSystem.dylib.

I've spent the past weeks since the holidays trying to understand where 
the problems come from and I've been able successfully build and use 
the latest snapshots, as well as CVS, on a regular and predictable 
basis. The issues are the outdated config.sub, config.guess and 
ltmain.sh which are based on GNU libtool 1.4.2 or thereabouts. OS X 
Panther has later versions of the autoconf tools, such as libtool 1.5, 
and I've found that by copying config.sub, config.guess and ltmain.sh 
from /usr/share/libtool into a freshly unarchived snapshot and/or 
running the auto* tools in the order below along with the configure 
flags will result in a successful compile, link, install and that of 
the 140 tests in the mono/tests directory, only 21 fail. Doing this on 
many other libraries I've had problems building in the past has also 
resulted in success.

To test all of this, I basically chucked DarwinPorts off my PowerBook 
and brought down the latest versions of glib2, pkgconfig, gettext and 
boehm-gc, used the process described above and detailed below 
reconfiguring and building each one into /usr/local, because after all, 
that's what /usr/local is for. Three things to note:

	1. Boehm GC 6.3a4 is required. I could never get the built-in version, 
the stable version hand built or the port from DarwinPorts work.
	2. In every case, I ran configure with --disable-static to disable 
building the static versions of libraries or if that option was ignored 
I deleted every .la static library installed. These are not needed and 
only waste space, all that is needed is the .dylib's and the symlinks 
for versioning.
	3. I did not, and will not, try this on OS X Jaguar. The differences 
are too great and I think using Panther as the working target for 
success moving forward is the best option.
	4. As implied in 3, I did all of this on OS X 10.3.2 with the Apple 
Developer Tools installed + Xcode 1.1 update.

Before starting on building Mono from a snapshot or release, do the 

a. Grab the latest Boehm Garbage collector, version 6.3a4, build and 
install it to the place your choice. I recommend try out all of this in 
/usr/local, as that it what it is for.

b. If you use Fink or Darwin Ports, make sure you've installed 
pkg-config, glib2 and get-text. Personally, I find the various 
alternate locations annoying and confusing, in particular for casual 
developers. If you installed Boehm GC 6.2 from either DarwinPorts or 
Fink, you'll need to either uninstall it and build and install version 
6.3a4 or, when you configure it, use an alternate location. In reality, 
you could put it in its own special location, say 
/opt/local/boehmgc-6.3a4. I've personally experimented with more 
descriptive, understandable and admittedly verbose alternative similar 
to the GoboLinux install and file system structure, building libraries 
and applications into specific named and versioned location paths such 
as /SystemEx/Libraries/BoehmGC/6.3a4 and then using the include and lib 
paths passed to configure scripts or by setting the appropriate 
compiler and linker environment variables.

To build Mono, follow these steps after extracting the archive:

1. Set the following in your shell environment (setenv in tcsh, export 
in bash, I use tcsh, so...):

setenv ACLOCAL_FLAGS "-I /usr/share/aclocal -I /usr/local/share/aclocal"
setenv PKG_CONFIG_PATH /usr/local/lib/pkgconfig

2. Run the following tools in the order specified below in the root of 
the mono snapshot:

glibtoolize --force --copy
automake --add-missing --gnu

3. Run configure with these options:

./configure --prefix=/usr/local --disable-static 
LDFLAGS=-L/usr/local/lib CFLAGS=-I/usr/local/include 
CPPFLAGS=-I/usr/local/include --with-gc=boehm 

Note that the paths specified here will differ if you are using 
DarwinPorts or Fink. It also worth noting the lack of many of the 
common compiler and linker options here. flags such as -no-cpp-precomp, 
-fno-common and -flat_namespace are taken care of when you run the 
tools against the source trees because the config.sub, config.guess and 
other options are correctly accounted for. The Fink project contains 
many instances of well-known problems with version of libtool prior to 
libtool 1.5.

	BUGBUG: With the latest snapshot, one of the tools will insert an 
invalide check for Glib 1.xx. This occurs for me around 20045. There 
will be two lines that specify and check the glib version. You can 
safely remove these two lines and re-run configure. I believe this 
might have happened because I built pkg-config by hand, which appears 
to include some modules from glib1 in it. This error did not occur when 
I did all of this using the DarwinPort installed pkg-config or glib2.

4. Make the following change before running make:
	a. comment out the #ifdef __APPLE__ at the top of the file 
mono/io-layer/sockets.h. This is not needed on 10.3, only 10.2.
	b. in mono/mini, run: grep -n "version-script" Makefile. This should 
return, at least on the 0.30 Previews, the following: 157:#monoldflags 
= -Wl,-version-script=$(srcdir)/ldscript. If this line is not commented 
out and/or has a ./ldscript instead of $(srcdir)/ldscript, you can 
comment it out or remove the "-Wl,". I commented it out to no problems 
as well as removed the "-Wl,", which fails when linking.

5. Run make, then, if all went well, sudo make install. Make sure the 
install location is in your path and try out some compiles and runs 
with mcs and mono.

6. Go to mono/tests and run make test to run all the tests and report 
any failures to the Mono developers and file bugs in Bugzilla.

Tests on primes, fibonacci, reflection, language and runtime/vm objects 
and ops (class, interface, cast, box, etc) all seem to pass in 
mono/tests. PInvoke, threads, appdomains, vararg and setenv stand out 
as tests that fail currently.

Some unresolved issues:

1. Some of the assumptions in the configure scripts, in particular 
threading, need to be examined. gcc does not need the -pthread flags to 
be specified according to Apple's documentation for the 10.3 Developer 
tool chain. Most of the standard library modules live in 
libSystem.dylib, which is always linked in.

2. The ICU check looks for icu-config and fails but ICU *is* present on 
OS X Panther in /usr/lib/libicucore.dylib but the icu-config tool is 
not present. Perhaps a better check for this is possible? Does it need 
to be linked in or is icu-config called or used anywhere?

3. Interop needs some work. I was able to get one or two PInvoke calls 
through to some NS* objects in AppKit and Foundation in the Cocoa API, 
but anything that did Windowing punted. I've just installed the latest 
CHUD tools from Apple, so these will help in looking at the problems.

I look forward to any feedback or additional thoughts on this. I've 
received a healthy number of replies to working towards a Mono OS X 
subproject to help debug, tighten and optimize Mono for OS X and in 
particular for the G5/PPC 970 as well as exploring building an 
installer, Mono.framework package and a Cocoa interop package.

Dave Morford
"Computation is about insight, not numbers" - Richard Hamming

More information about the Mono-devel-list mailing list