Skip to content

A Template for Building Scheme Applications for iPhone/Mac OS X in Xcode

I have often played with the idea of writing Mac and iPhone applications in Scheme, but as a result of not knowing the right compiler to embed (and lack of experience in Scheme), I could not execute on it. While programming in Objective-C is definitely doable (and of course you can use Objective-C++), I like to have more options for native application development.

Luckily, this month, there was one blog entry about Gambit-C on the iPhone which was a great starting point (and James has since put out more interesting posts on the topic). In addition to the fantastic advice found there, I wanted a better integration within Xcode, since for now, it seems impossible to develop (legally) for the iPhone outside of the IDE (personally, I prefer setting up builds based on cmake and make them as cross-platform as possible). In particular, I wanted a build phase to compile from Scheme to C without having to invoke the Scheme compiler manually. I have created a template for this purpose for later use and have put it on github in case other people might be interested to use it. The source is released under the new BSD license, so feel free to experiment !

The principle used is similar to the one described in James blog – all Scheme modules defined in the project are compiled to C files and linked into a single executable. When using the Gambit-C compiler, one has to pay attention to the code that it generates: when linking statically, we need to:

  • provide the -link switch to the compiler command
  • include all the Scheme source files we want to link into the executable

If we would compile each file separately with the link option there would be a flat link file for each Scheme module and we would get linker errors due to duplicate symbols. Calling gsc with all the needed Scheme modules provides it with the necessary information to generate a single flat link file. The template assumes that all the Scheme files are in the scheme sub directory. In order to invoke the compiler with the correct parameters, I added an external target (a small Ruby build script) that scans the scheme directory and feeds it to the gsc command and it also includes a clean action that removes the generated C files.

To use the template in a different environment, the user simply needs to set the variableGAMBITC_BASEPATH, which could be as simple as /usr/local. This can be set either in the .MacOSX/environment.plist or the bash .profile script in the home directory. After a change to these, the user needs to log out and log in again so Xcode can recognize the change to the user settings. I personally prefer to install development tools somewhere in my home directory, which has the advantage that I can use different configurations and don’t pollute my system directories.

The contents of my personal GAMBITC_BASEPATH look like this:

$(GAMBITC_BASEPATH)/Debug
$(GAMBITC_BASEPATH)/Release
$(GAMBITC_BASEPATH)/Debug-iphonesim
$(GAMBITC_BASEPATH)/Release-iphonesim
$(GAMBITC_BASEPATH)/Debug-iphoneos
$(GAMBITC_BASEPATH)/Release-iphoneos

These are the directories that are the parameters to the –prefix option in the configure call when compiling gambit-c (see James’ blog). In fact, I simply built a version for each platform (Mac OS X, iPhone Simulator and iPhone Device) and symlink’ed the directories to reflect the layout above, since I do not need separate Debug and Release versions for Gambit-C.

In the build rules for the main target, I added a dummy rule which specifies the output files of the “compile scheme” target. This is the only part that I find a little ugly, because whenever the list of Scheme modules changes, this list needs to be changed, so the C compiler can include these files in the builds. I still find this solution better than checking in generated files into version control or including C files in the project tree which do not exist.

The github repository contains templates for a Mac command line tool and one for an OpenGL ES application on the iPhone. Since I am a game developer, the OpenGL ES template is most useful to me, but it is pretty easy to adapt the setup for other kinds of iPhone (or Mac OS X) applications. The initialization point in my template differs from the one described in James Long’s blog: the main.mm is unmodified, instead, the Scheme system is initialized when the view is initialized, because that is the place where I currently pull up my engine.

Happy Hacking 🙂

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*