[Mono-devel-list] A how to for Mono on OS X Panther Building (w/ JIT and GC to boot)
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
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
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
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.
"Computation is about insight, not numbers" - Richard Hamming
More information about the Mono-devel-list