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.
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 make 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 make 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 make cp src/bmconv ~/symbian-gcc/bin cd .. cd rcomp-7.0.1 patch -p1 < ../../../rcomp-v6.patch patch -p1 < ../../../rcomp-gcc-4.1.patch make 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/xmakesis.pl ~/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).
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 ../gcc539src.zip ~/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 ../gcc539src.zip 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.
Start by building and installing the toolchain according to the instructions above.
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 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 make install
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 | nS60_sdk_v1_2.zip | install_gnupoc_s60_12 | |
2nd Edition, WINS | s60_sdk_v2_0.zip | install_gnupoc_s60_20 | Working emulator |
2nd Edition, FP1, WINS | S60_SDK_2_1_NET.zip | install_gnupoc_s60_21 | |
2nd Edition, FP1, CW | S60_SDK_v21c_CW.zip | install_gnupoc_s60_21_cw | Working emulator |
2nd Edition, FP2, WINS | s60_2nd_fp2_sdk_msb.zip | install_gnupoc_s60_26 | Working emulator |
2nd Edition, FP2, CW | s60_2nd_fp2_sdk.zip | install_gnupoc_s60_26_cw | Working emulator |
2nd Edition, FP3 | s60_2nd_sdk_fp3.zip | install_gnupoc_s60_28 | |
3rd Edition, Maintenance Release | S60-SDK-0616-3.0-mr.3.749.zip | install_gnupoc_s60_30 | |
3rd Edition, FP 1 | S60-SDK-200634-3.1-Cpp-f.1090b.zip | install_gnupoc_s60_31 |
(Everything is tested using Wine 0.9.15 and remote X to X11.app 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 ../s60_2nd_fp2_sdk_msb.zip ~/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/wrapper.sh 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 sign.sh, which is a wrapper for signsis, to avoid having to enter the key password on the command line.
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\com.nokia.carbide.cpp.support_1.0.0 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:
[Environment] "Path"="c:\\msvcpp2003\\bin;c:\\codewarrior\\Symbian_Tools\\Command_Line_Tools;c:\\windows;c:\\windows\\system"
(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"
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 EM=noone@nowhere.com" mykey.key mycert.cer
Then sign the sis file using this certificate:
sign.sh 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 sign.sh) 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.