Building for OS X

This page contains instructions for running PySoy on Mac OS X (done on 10.6.6, although in theory it should work for all OS X >= 10.4, with minor changes to the architecture flags, etc.). These instructions have worked, with difficulty, for at least one person (anthuswilliams). Good luck!

Before we begin, make sure you have an X11 environment installed. There are a few options out there. My personal favorite is  XQuartz, which works in rootless mode, so I only have an X windowing environment where I need it, instead of it taking over the entire screen.

You'll also want MacPorts installed on your machine. You can try to make all the dependencies yourself, but it sucks. OS X doesn't have a canonical package manager unfortunately, but MacPorts is the next best thing.

Python Stuff

You will need at least two different versions of python. PySoy requires Python >= 3.0. However, in Python 3 the exception syntax was changed, which means that a number of the dependencies we will be installing will throw syntax errors. It doesn't particularly matter which versions of python you use, as long as they are on opposite sides of 3.0. At various points in the process of figuring out how to do this, I used Python 3.1, 3.2, 2.5, 2.6, and 2.7. (I used a MacPorts package instead of the system python, because I ended up (unnecessarily, as it turned out) running lipo on it to make a thin binary, and you won't catch me doing that to anything contained in /usr/bin/. I am crazy, but not that crazy).

Note that the python binaries should be 32-bit. With our Python 2.6 (I'm using 2.6 for illustration) build, a fat binary will work for everything we need. However, for actually running PySoy, we need our Python 3.2 (or 3.x) binary built only for 32-bit. Snow Leopard runs Python as 64 bit by default, and if you try to import the PySoy module, you will get an ImportError. Mach-O refuses to import the module because it thinks it's the wrong architecture. Browsing to python.org's  download page, you will see it offers a 32-bit i386/PPC binary. This is the one you want. Do NOT get the i386/x86_64 fat binary it recommends for OS X 10.6.

So you have python 3.2. Just use MacPorts to get 2.6. Don't forget to specify you want the universal variant.

$ sudo port install python26 +universal

I also like to use python_select to switch between multiple versions of python.

$ sudo port install python_select
$ sudo python_select python26

Now python_select works in your /opt/local/bin (which is where MacPorts lives in general). So it won't work for switching to python 3.2 unless we tell it where our 3.2 install is.

$ sudo vim /opt/local/etc/select/python/python32

We've created a new config file. Add the following to it:

bin/python
bin/pythonw
bin/python-config
bin/idle
bin/pydoc
bin/smtpd.py
share/man/man1/python.1
share/man/man1/python.1.gz
/Library/Frameworks/Python.framework/Versions/Current
/Library/Frameworks/Python.framework/Headers
/Library/Frameworks/Python.framework/Resources
/Library/Frameworks/Python.framework/Python

Now you should be able to switch to python 3.2 using python_select. We don't need it yet, but we will.

Dependency hell

Libsoy has a lot of dependencies, each of which have themselves a lot of dependencies. So this will take a while. Relax, take your socks off, enjoy a cup of coffee.

We will be compiling libsoy in 32-bit, so all of these dependencies should be the universal variants.

$ sudo port install orc +universal
$ sudo port install vala +universal
$ sudo port install ode +universal
$ sudo port install gtkglext +universal

The gtkglext package has a lot of dependencies, one of which is the 3D library  Mesa. I ran through this process twice, and both times, MacPorts breaks whilst building Mesa. What happens is the linker cannot find the dylinks for a Mesa dependency called OpenVG. I only found this out after I tried to make Mesa myself, and it created the OpenVG dylinks for me (even though the build process itself failed). The process I used is extremely dirty, but it worked, so I'll document it here. If you want to get OpenVG without trying to build Mesa manually, you can find some information on OpenVG  here.

Here's what I did. First, install talloc (mesa depends on it):

$ sudo port install talloc +universal

Next I  downloaded the Mesa library, and tried to configure it. We are building for Apple's i386 architecture so it will work with PySoy, so I specify that as the target.

$ ./configure --target=i386-Darwin

Now, we try to make. Make sure you specify the INCLUDE environment variable, because the build script is by default only checking in /usr/include/ and all the dependencies are in /opt/local/include, thanks to MacPorts.

$ env INCLUDE="/opt/local/include" ARCHFLAGS="-arch i386" make

Now, the build fails, but it does successfully create the OpenVG dylinks. (I told you this process was messy). So:

$ sudo port clean mesa
$ sudo port install mesa +universal

And it should install fine. You can the Mesa build dir you have been working with. That should take care of gtkglext's dependencies. So we try to install it again.

$ sudo port clean gtkglext
$ sudo port install gtkglext +universal

And it works. Moving on:

$ sudo port install libgee +universal

If you get an error trying to install gobject-introspection (one of libgee's dependencies) it is probably because you are not using the universal binary for python 2.6. Make sure you have the right python build, as described at the top of this page. Other than that, it should work fine.

One more package:

$ sudo port install liboil +universal

Building libsoy

Pull libsoy from the mercurial repo.

$ hg clone http://hg.pysoy.org/libsoy
$ cd /path/to/libsoy/

You will need to set your MACOSX_DEPLOYMENT environment variable, because by default gcc shoots for OS X 10.3, which will not work on libsoy. Also, you want to specify your architecture (and LDFLAGS) so that gcc will be able to find all the necessary dylibs

$ env MACOSX_DEPLOYMENT_TARGET=10.6 ARCHFLAGS="-arch i386" LDFLAGS="-arch i386" CFLAGS="-arch i386" ./waf configure --target=i386-Darwin
$ sudo env ARCHFLAGS="-arch i386" LDFLAGS="-arch i386" CFLAGS="-arch i386" ./waf install

If all went well, we are ready to move on to building PySoy.

Building PySoy

First, switch to python 3.2.

$ sudo python_select python32

Now, setup.py will be looking for its libraries in /usr/include. So you will want to either set the INCLUDE environment variable or create symlinks to /opt/local/include, where MacPorts has your libraries. I understand you can use the --prefix option with MacPorts when installing your libraries to place them somewhere other than /opt/local, but IMHO that is just asking for trouble.

I opted for the symlink route because using the INCLUDE variable didn't occur to me. No regrets, though. :p

$ sudo ln -s /opt/local/include/glib-2.0 /usr/include/glib-2.0
$ sudo ln -s /opt/local/include/gee-1.0 /usr/include/gee-1.0
$ sudo ln -s /opt/local/include/cairo /usr/include/cairo
$ sudo ln -s /opt/local/include/pango-1.0 /usr/include/pango-1.0
$ sudo ln -s /opt/local/include/gtk-2.0 /usr/include/gtk-2.0
$ sudo ln -s /opt/local/include/gdk-pixbuf-2.0 /usr/include/gdk-pixbuf-2.0
$ sudo ln -s /opt/local/include/liboil-0.3 /usr/include/liboil-0.3
$ sudo ln -s /opt/local/lib/gtk-2.0 /usr/lib/gtk-2.0
$ sudo ln -s /opt/local/lib/glib-2.0 /usr/lib/glib-2.0

Now, try to install PySoy.

$ hg clone http://hg.pysoy.org/pysoy $ cd /path/to/pysoy $ sudo env MACOSX_DEPLOYMENT_TARGET=10.6 ARCHFLAGS="-arch i386" LDFLAGS="-arch i386" CFLAGS="-arch i386" python setup.py install

There will be a lot of warnings (of course) but as long as there are no errors, we should be working now. Time to test.

Making sure it works

First, let's just try to import PySoy from the python interpreter.

$ python
>>>import soy

If you get an error that looks like:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dlopen(/Library/Frameworks/Python.framework/Versions/3.1/lib/python3.1/site-packages/soy.so, 2): no suitable image found. Did find:

/Library/Frameworks/Python.framework/Versions/3.1/lib/python3.1/site-packages/soy.so: mach-o, but wrong architecture

It is because you are not using the 32-bit python. Go back and make sure you have the right one.

If all goes well, import soy will return no error. So let's try to execute one of the PySoy examples.

$ python examples/TwoCubes.py

If it works, you will see a new window with two cubes colliding. Congratulations! :)