Symbian development on OS X and Linux


Initially I set up my development environment on OS X according to Simon Woodside's howto, but later on patched the tools further and modified the environment some more. This is written both as a guide for others to follow and as a reference for myself if I need to reinstall everything.

For quite some time, I've been using the makefile-based build system from sdk2unix developed by Rudolf König, which is much more streamlined and straight-forward compared to the original system with bldmake/abld/makmake and lots of perlcode and automatically generated makefiles. Most of my projects have had both ordinary mmp files and makefiles. When I started to investigate how to build Series 60 3rd edition (Symbian 9.1, EKA2) binaries on Linux, I initially made another makefile-based system for this, similar to the one in sdk2unix. But I wouldn't want to maintain yet another set of build files for all projects. Instead, I started investigating GnuPoc, which uses the original build system based on mmp files.

I've now made updated versions of the GnuPoc patches for different versions of the Series 60 SDKs, supporting Series 60 1.2, 2.0, 2.1, 2.6, 2.8, 3.0 and 3.1.

For Series 60 3rd edition, you can skip right to the GnuPoc part.

Installing the tools on OS X

This is tested using OS X Tiger on both PowerPC and Intel, using XCode 2.4 with gcc 4.0. It is tested with the current version of sdk2unix (by Rudolf König) at the moment, 1.9, but newer versions might also work.

I've chosen to install the toolchain into ~/symbian-gcc and the SDKs into ~/symbian-sdks. If you choose to install into some system directory e.g. beneath /usr/local somewhere, you'll need to run the installation commands using sudo.

Start by downloading these files into a directory (~/symbian-build in my case):

And a lot of patches:

Start by extracting sdk2unix and the gcc source, and apply the necessary patches:

tar -zxvf sdk2unix-1.9.tar.gz
mkdir gcc
cd gcc
tar -jxvf ../gcc-539-2aeh-source.tar.bz2
patch -p0 < ../gcc.patch
patch -p0 < ../diff539
patch -p0 < ../sdk2unix-1.9/data/gcc539/bash-3.1.5.patch
patch -p0 < ../sdk2unix-1.9/data/gcc539/gcc-4.0.patch
patch -p0 < ../sdk2unix-1.9/data/gcc539/gcc539.patch
patch -p0 < ../gcc-osx-intel.patch

Then create a directory for building the compiler suite, configure and build it: (This takes a while...)

mkdir obj
cd obj
sh ../src/configure --prefix=~/symbian-gcc --target=arm-epoc-pe
make all-binutils all-gas all-ld all-gcc
make install-binutils install-gas install-ld install-gcc

Then patch and compile the rest of the toolchain. Some tools are built from the source in sdk2unix, others straight from source packages modified by Andre Howe.

The patch for the make rules fix some slight bugs but also add a possibility to pass flags to rcomp and petran through $(RCFLAGS) and $(PTFLAGS).

The patches to bmconv and rcomp both fix things for big endian systems but also add an option to rcomp for creating Symbian 6-compatible resource files, which is needed for building things for Series 60 1st edition. (This patch was originally written by Jarkko Oikarinen, but has been updated and adapted to support big endian systems by me.) By adding -6 to RCFLAGS your binaries will be compatible with Symbian 6-devices, as long as you don't use any functionality not present on those devices of course, even if you've compiled with a newer SDK in order to get e.g. more constant definitions. In this way, you're able to build one single binary package which is compatible with all Series 60 1st and 2nd edition devices.

The second rcomp patch fixes compilation with GCC 4.1. The makesis patch fixes a crash in one rare case.

tar -zxvf makesis-2.0.0.tar.gz
patch -p0 < makesis.patch
cd makesis-2.0.0
cp src/makesis ~/symbian-gcc/bin
cd ..
tar -zxvf petran-1.1.0.tar.gz
cd petran-1.1.0
patch -p1 < ../petran-osx-intel.patch
cp petran/petran e32uid/uidcrc ~/symbian-gcc/bin
cd ..
cd sdk2unix-1.9
cd helpers
cd bmconv-1.1.0-2
patch -p1 < ../../../bmconv.patch
cp src/bmconv ~/symbian-gcc/bin
cd ..
cd rcomp-7.0.1
patch -p1 < ../../../rcomp-v6.patch
patch -p1 < ../../../rcomp-gcc-4.1.patch
cp src/rcomp ~/symbian-gcc/bin
cd ../..
cd genaif
patch -p0 < ../../genaif.patch
cc genaif.c -o genaif
cp genaif ~/symbian-gcc/bin
cd ..
patch -p1 < ../makerules.patch
cp -rp data/gcc539/makerules ~/symbian-gcc/lib
cp data/gcc539/specs ~/symbian-gcc/lib/gcc-lib/arm-epoc-pe/2.9-psion-98r2/specs
cp bin/ ~/symbian-gcc/bin
cd ~/symbian-gcc/bin
ln -s ../lib/gcc-lib/arm-epoc-pe/2.9-psion-98r2/cpp arm-epoc-pe-cpp
ln -s arm-epoc-pe-as as

The toolchain is now installed and ready to run. You can then install any SDK using the scripts in sdk2unix, but most of these (except install_series60_21 by Simon Woodside) need wine for unpacking. If you have access to a linux machine, though, you can unpack the SDKs there and just copy them over to OS X (and update the symlinks in the bin and lib directories).

Installing the tools on Linux

On Linux, you can use the much more streamlined scripts included in sdk2unix. But you still might want to apply some extra patches to rcomp, bmconv, makesis and the make rules. (See above for description.)

Download these files:

Then apply the patches and build the toolchain in this way:

tar -zxvf sdk2unix-1.9.tar.gz
cd sdk2unix-1.9
patch -p1 < ../makerules.patch
cd helpers
patch -p0 < ../../makesis.patch
cd bmconv-1.1.0-2
patch -p1 < ../../../bmconv.patch
cd ..
cd rcomp-7.0.1
patch -p1 < ../../../rcomp-v6.patch
patch -p1 < ../../../rcomp-gcc-4.1.patch
cd ../..
bin/install_gcc539 ../ ~/symbian-gcc

Optionally, if you want to build the compiler for the THUMB target too, download a specs file for thumb and another patch for GCC. Then build GCC another time, using these commands:

unzip -q ../
chmod -R u+wx src
find src -type f -print | xargs recode -f dos..latin1
patch -p0 < data/gcc539/gcc539.patch
patch -p0 < data/gcc539/gcc-4.0.patch
patch -p0 < data/gcc539/bash-3.1.5.patch
patch -p0 < ../gcc-thumb.patch
mkdir obj-thumb
cd obj-thumb
sh ../src/configure --prefix=~/symbian-gcc --target=thumb-epoc-pe
make all-binutils all-gas all-ld all-gcc
make install-binutils install-gas install-ld install-gcc
cd ..
cp ../thumb-specs ~/symbian-gcc/lib/gcc-lib/thumb-epoc-pe/2.9-psion-98r2/specs
cd ~/symbian-gcc/bin
ln -s ../lib/gcc-lib/thumb-epoc-pe/2.9-psion-98r2/cpp thumb-epoc-pe-cpp


You can choose to install SDKs either using the install scripts in sdk2unix or using GnuPoc. The sdk2unix style doesn't support Series 60 3rd edition, however. It requires all projects to have a separate, makefile based, build system. sdk2unix has some examples included, and all Series 60 projects on my software page are buildable with this system.

The other approach is to use GnuPoc, e.g. using my patches for the Series 60 SDKs. Unfortunately, all of my GnuPoc patches require wine to use included windows binaries in one place or another, so this approach isn't feasible on OS X on PPC.



Series 60 1st and 2nd edition

Start by building and installing the toolchain according to the instructions above.

Series 60 3rd edition

Series 60 3rd edition uses a completely different toolchain, for this you have to download CodeSourcery's GCC package, select IA32 GNU/Linux and download it. (Or directly download a local copy.) Other versions might also work, perhaps after some adjustments, but this is the version bundled with the Series 60 3rd edition SDK. Extract this into a directory, e.g.:

mkdir csl-gcc
cd csl-gcc
tar -jxvf ../gnu-csl-arm-2005Q1C-arm-none-symbianelf-i686-pc-linux-gnu.tar.bz2

If you can't use these binaries (e.g. on OSX on Intel), you can compile the toolchain yourself. Download the source package from CodeSourcery (local copy), and build it:

mkdir csl-gcc-build
cd csl-gcc-build
tar -jxvf ../gnu-csl-arm-2005Q1C-arm-none-symbianelf.src.tar.bz2
tar -jxvf binutils-csl-arm-2005Q1C.tar.bz2
cd binutils-csl-arm-2005q1
./configure --target=arm-none-symbianelf --prefix=${HOME}/csl-gcc
make install
export PATH=~/csl-gcc/bin:$PATH
cd ..
tar -jxvf gcc-csl-arm-2005Q1C.tar.bz2
cd gcc-csl-arm
./configure --target=arm-none-symbianelf --enable-languages=c,c++ --prefix=${HOME}/csl-gcc
make install

Install the SDKs

Download my GnuPoc patch archive 1.02 and the SDK you want to use from Forum Nokia. The following versions are supported at the moment:

Version File name Install script Comments
1st Edition, FP1, WINS install_gnupoc_s60_12
2nd Edition, WINS install_gnupoc_s60_20 Working emulator
2nd Edition, FP1, WINS install_gnupoc_s60_21
2nd Edition, FP1, CW install_gnupoc_s60_21_cw Working emulator
2nd Edition, FP2, WINS install_gnupoc_s60_26 Working emulator
2nd Edition, FP2, CW install_gnupoc_s60_26_cw Working emulator
2nd Edition, FP3 install_gnupoc_s60_28
3rd Edition, Maintenance Release install_gnupoc_s60_30
3rd Edition, FP 1 install_gnupoc_s60_31

(Everything is tested using Wine 0.9.15 and remote X to on OS X, things might work better on other setups.)

Example on installing an SDK:

tar -zxvf gnupoc-s60-1.02.tar.gz
cd gnupoc-s60-1.02
./install_gnupoc_s60_26 ../ ~/symbian-sdks/s60_26

The install scripts makes almost all files lowercase and patches the build scripts. The exception to the lowercase rule is the GLES include directory and libGLES_CM.lib, for compatibility reasons.

In order to use the SDK, you'll have to set the EPOCROOT environment variable to point to your SDK and add the toolchain directory and the epoc32/tools directory of the SDK to your PATH. This might be cumbersome if frequently switching between different SDKs. To ease that situation, you can install some wrapper scripts:

./install_wrapper ~/gnupoc

If you've installed the toolchains to other directories than mentioned here, edit ~/gnupoc/ and set EKA1TOOLS and EKA2TOOLS to point to where you've installed them. With these wrappers, you only have to have this single directory in your PATH, and depending on the EPOCROOT variable, the correct toolchain is included and scripts from the current SDK are called. This also includes, which is a wrapper for signsis, to avoid having to enter the key password on the command line.

Wine setup

All of the SDKs use Wine more or less, and thus you need a working setup of that. Additionally, some of the tools assume they can find uidcrc.exe in the path. Therefore, you must copy this file from the epoc32/tools directory (is shouldn't matter which SDK) to a directory in your wine path, e.g. ~/.wine/drive_c/windows. This is all you have to do if you only want to build binaries for the real device.

If using external makefiles (as for building icons in 3rd edition), copy make.exe and mifconv.exe, too. make.exe probably can be used from any SDK version, but you'll need mifconv.exe from the 3.0 SDK, since mifconv.exe in 3.1 has some problems starting within wine.

In order to build binaries for the emulator, you'll need a windows compiler. Unfortunately, these have to be copied from a real installation. (Perhaps it's possible to do the complete installation of them within wine?)

For the WINS compiler, I've used Visual C++ Toolkit 2003, set up according to this page. Just copy over the C:\Program Files\Microsoft Visual C++ Toolkit 2003 directory to e.g. ~/.wine/drive_c/msvcpp2003.

For the WINSCW compiler, you can install Carbide C++ from Forum Nokia. These instructions apply to Carbide C++ 1.0, for newer versions you might need to use slightly different paths. Copy C:\Program Files\Carbide\plugins\ to e.g. ~/.wine/drive_c/codewarrior.

These have to be added to the wine path. Edit ~/.wine/user.reg, and add this after the WINE REGISTRY Version 2 line:


(Of course, if you've already got a similar environment definition in that file, add it there instead.)

When using the CW compiler, you'll also need to add these variables to your unix environment (the perl build scripts need them, adding them to the wine environment isn't enough, and if set in the unix environment, they're also automatically available in wine):

export MWCSym2Includes="c:\\codewarrior\\symbian_support\\MSL\\MSL_C\\MSL_Common\\include;c:\\codewarrior\\symbian_support\\MSL\\MSL_C++\\MSL_Common\\include;c:\\codewarrior\\symbian_support\\MSL\\MSL_Extras\\MSL_Common\\include"
export MWSym2Libraries="+c:\\codewarrior\\symbian_support"
export MWSym2LibraryFiles="MSL_All_MSE_Symbian.lib;gdi32.lib;user32.lib;kernel32.lib"

Using it

After installing everything, you're able to compile things in the same way as on windows.

In order to compile most projects, the usage of upper/lowercase for filenames must be cleaned up somewhat. The install scripts clean up the usage of lower/upper case in the bundled examples (by forcing them to lowercase), so the should all be buildable directly. (Or at least it tries to, it might not work reliably in stranger examples.)

To build the hello world example on a S60 3rd edition SDK, do the following:

export PATH=~/gnupoc:${PATH}
export EPOCROOT=~/symbian-sdks/s60_30/
cd ~/symbian-sdks/s60_30/s60ex/helloworldbasic/group
bldmake bldfiles
abld build gcce urel
cd ../sis
makesis helloworldbasic_gcce.pkg helloworldbasic.sis

For 1st and 2nd edition, use the paths for those SDKs and build using abld build armi urel instead. The .pkg files for those examples are written for the THUMB target. Either update the .pkg file and replace all occurrances of thumb with armi or build them using abld build thumb urel (which requires that you built a thumb compiler).

On 3rd edition, all sis files must be signed before they can be installed. If you haven't already got a key and certificate pair, generate them:

makekeys -cert -password mypassword -dname "CN=Joe Bloggs OU=Development OR=Acme Ltd CO=GB" mykey.key mycert.cer

Then sign the sis file using this certificate: helloworldbasic.sis helloworldbasic.sisx mycert.cer mykey.key

The newly generated .sisx file can then be installed on a device.

Note that signsis (and thus can't handle absolute paths in unix format, i.e. paths starting with /. Relative paths in unix format, and absolute paths in windows format work fine.


// Martin Storsjö ()