Sunday, April 25, 2010

Magecrawl on Mac Part II (libtcod, SDL, and init code...)

This is a bunch of technical details about getting libtcod working on the mac. You might just be interested in the announcement post.

As promised, this post is a breakdown of the work it took to make libtcod work natively on the mac. By "native", I am not knocking the wonderful work Michael De Rosa did for previous releases. I'm referring to ones produced auto-magically by the cmake system,  no manual xcodeprojs, .dylibs and all.

The wonderful part of generated xcodeprojs is that they will stay in date as further changes are made. Nobody has to figure out what changes were made, and manually update things. This hopefully means that mac ports of the new version should come out same day or very soon after releases.

Enough about that...getting libtcod working on the mac involved two major sections of work.

Part I: Build system

Getting cmake to play nicely with the mac wasn't too painful. I had noted places in my CMakeLists.txt where apple variables were needed when I created them, so the first step was filling them all in. Unlike the windows builds, the mac build currently uses the framework versions of libsdl and libpng. I'm unsure if this will require users installing those frameworks before use.... I did this since I wanted .dylibs of libtcod. The only other issue that SWIG apparently doesn't ship arrays_csharp.i built in for the mac. I had to download it from svn and copy it into the right place.

Part II: Crashes on launch, init code, and mac

This is where the pain started. The sample programs crashes on launch, due to an objective c exception about preconditions not being met. After some digging, I found this. Apparently, SDL does some funny business to get initially properly on the mac. You need to include an object c file in your build and use a particular version of a main function.

What happens on the mac is when you include the SDL headers, it renames your main via macros to something else. The objective c file defines its own main statement, which does the correct initing and then calls SDL_main which calls your main.

This obviously doesn't work very well if your a C# program who doesn't have a main! I had a friend at work who know objective c well to bounce ideas off of, and then I ran into this. It's a simple objective c method I could call from C code before initing SDL that would handle the mac stuff for me. No more renaming main nonsense for me. It worked great.

Just one note, all of this doesn't apply if your use the "unix" style SDL libraries. Those you can use just normally, they don't need extra setup. However, I wanted a "real" mac port, dylibs and all. There is now code in libtcod that will fixup the mac specific stuff when you call console init. Hence, it works fine no matter the calling language.

I normally try not to get this implementation specific when writing posts, however I couldn't find all this info in one place. If somebody is trying to get an SDL based library working on the mac, particularly in C#, I hope this info finds you well...

No comments: