[[PageOutline]] This guide will allow you to build Qt5 and WebKit2 for N9/N950 (MeeGo Harmattan), and run MiniBrowser on the device. = 1. Setting up cross-compile environment = The easiest way to develop for Harmattan is to cross-compile using a sysroot. The Qt SDK already comes with a Harmattan sysroot and the required ARM toolchain, and we build on top of that to create a sysroot suitable for building Qt5 and WebKit2. Cross-compiling works both on Linux and on Mac OS X. == 1.1. Prepare your environment == {{{ $ mkdir ~/swork $ cd ~/swork }}} ''Note:'' This base directory is just an example used in this guide. You're free to change where you keep your sources and builds (shadow-builds), as long as you account for that when running the various commands. == 1.2. Download and install the Qt SDK == Available from http://qt.nokia.com/downloads/ Use online installer, because that one will install harmattan_10.2011.34-1_rt1.2 target, while the offline one has the old harmattan_10.2011.34-1. Both Mac OS X and Linux X11/64-bit should work fine. == 1.3. Get some convenience-scripts used in this guide and for development == {{{ $ git clone https://github.com/resworb/scripts.git browser-scripts }}} == 1.4. Set up custom MADDE target == {{{ $ browser-scripts/setup-madde-toolchain.sh }}} This will create a new target based on the original Harmattan target that comes with the QtSDK, but with different names for the ARM-toolchain binaries, and pre-installed packages needed for Qt5 development. If you get errors like ''"relocation R_ARM_MOVW_ABS_NC against `a local symbol' can not be used"'' on build then you should use '''--force''' option with setup-madde-toolchain.sh. == 1.5. Download testfonts == {{{ $ git clone git://gitorious.org/qtwebkit/testfonts.git }}} == 1.6. Get the source of Qt5 and WebKit == {{{ $ browser-scripts/clone-sources.sh --no-ssh }}} This will try to clone Qt5, Qt-Components and WebKit git repository to ~/swork/qt5, ~/swork/qtcomponents and ~/swork/webkit. {{{ #!html
Warning: Sometimes Qt5 cloning fail because of connection timeout problems. This would cause that your ~/swork/qt5/qtscript direcory stays empty and WebKit build will miss QtScript/qscriptengine.h header. In this case delete ~/swork/qt5 and re-run clone-sources.sh .
}}} If you have already a local git repo for WebKit, you can speed up the process by copying its contents to ~/swork/webkit directory. After copying you should run ''git reset --hard HEAD'' on it before running clone-sources.sh . You can update the sources by running: {{{ $ browser-scripts/update-sources.sh }}} == 1.7. Create ICECC toolchain (optional) == If you have multiple workstations configured to use [http://en.opensuse.org/Icecream ICECC], you can speed up building process significantly. Create a toolchain for distributed building (run@host): {{{ $ cd ~/swork $ ln -s /home/$USER/QtSDK/Madde/targets/harmattan_10.2011.34-1_rt1.2_qt5/bin /home/$USER/swork/browser-scripts/arm-toolchain-bin $ browser-scripts/create-icecc-env.sh --environment cross }}} The script will create a file called setup-icecc-cross-env.sh in your swork directory. Make the script runnable. == 1.8. Build sources == {{{ $ export -n QTDIR $ browser-scripts/build-sources.sh --cross-compile }}} You may use '''--with-icecc''' option for building to get speed up with icecc. This will build Qt5, QtComponents, and QtWebKit. If everything is right you should get similar result: {{{ #!html
===========================================================
 WebKit is now built (10m:22s). 
 To run QtTestBrowser with this newly-built code, use the
 "Tools/Scripts/run-launcher" script.
===========================================================
}}} If you just want to build Qt5, replace the last step with: {{{ $ browser-scripts/qt5-build.sh --cross-compile }}} == 1.9. Updating build environment == If you need to update browser-scripts, run on host: {{{ $ cd ~/swork/browser-scripts $ git reset --hard HEAD $ git pull }}} If you neet to update Qt5 and WebKit, run on host: {{{ $ cd ~/swork/qt5 $ git submodule foreach --recursive git clean -fdx $ git clean -fdx $ git reset --hard HEAD $ cd ~/swork/webkit $ git clean -fdx $ git reset --hard HEAD $ cd ~/swork $ browser-scripts/update-sources.sh }}} = 2. Configuring your device (N9/N950) = ''Note:'' It's highly encouraged that you enable open mode on your device. This disables the security system on the device (AEGIS), which lets you mount (SSHF/NFS), making development a lot easier. == 2.1 Enabling open mode == The retail N9 has a very stricky security system, called AEGIS. You can read about this at: [http://harmattan-dev.nokia.com/docs/library/html/guide/html/Developer_Library_Developing_for_Harmattan_Harmattan_security_Security_guide.html Harmattan Security Guide] The only known way to disable AEGIS restrictions is flashing an alternate kernel onto N9. {{{ #!html
Notice:: This could void the warranty! After flashing the device will show a warranty void message while booting.
}}} This section based on - http://maemo.cloud-7.de/HARM/N9/openmode_kernel_PR1.1/ - http://talk.maemo.org/showthread.php?t=81579 - http://forum.meego.com/showthread.php?t=4575&page=22 Prerequisite * Pached kernel: [http://maemo.cloud-7.de/HARM/N9/openmode_kernel_PR1.1/zImage-2.6.32.39-dfl61-20113701 zImage-2.6.32.39-dfl61-20113701] * Original firmware 20.2011.40-4 (you can download it with [http://www.symbian-toys.com/navifirm.aspx NaviFirm+], or using [https://gist.github.com/1636192 this script] on non-Windows machines.) * Nokia flasher: [http://tablets-dev.nokia.com/maemo-dev-env-downloads.php flasher_3.12.1_amd64.deb] It is recommended to flash back the device to factory state. If you have any importand data on the device, back it up first or you will lose it! Install Nokia flasher utility and download the firmware and pached kernel file to a directory. Turn off the device and disconnect it from usb. Flash the original firmware to the device: {{{ sudo flasher -F DFL61_HARMATTAN_20.2011.40-4_PR_LEGACY_001-OEM1-958_ARM.bin -F DFL61_HARMATTAN_20.2011.40-4.CENTRALEUROPE_EMMC_CENTRALEUROPE.bin -f }}} Do NOT disconnect usb cable. Do NOT restart the phone. Now, flash the pached kernel onto it: {{{ sudo flasher -f -a DFL61_HARMATTAN_20.2011.40-4_PR_LEGACY_001-OEM1-958_ARM.bin -k zImage-2.6.32.39-dfl61-20113701 }}} Now, your N9 is ready. Disconnect it from usb. It will start booting. == 2.1. Turn on developer mode == There is a tutorial for this at http://paazio.nanbudo.fi/tutorials/qt-quick/developer-mode-in-nokia-n9 Enable developer mode: Settings / Security / Developer mode. After installation the device will do a reboot. Change usb connection mode: Settings / Accessories / USB to "SDK" or "Always ask". Set up wifi internet connection. Connect usb cable. == 2.2. Set up device == {{{ $ browser-scripts/setup-device.sh }}} This will set up password-less login, install missing packages, and set up SSHFS if you're running in open-mode. From this point on you should be able to refer to the device as 'device', and the default user should be 'developer'. == 2.3. Enable root login (optional) == Login as 'developer': {{{ $ ssh developer@192.168.2.15 developer@192.168.2.15's password: ****** (getting this from N9 usb connection) }}} Switch to root (run@n9): {{{ /home/developer $ devel-su Password: rootme }}} You can create permanent password for default user 'user' (run@n9): {{{ ~ # passwd user New password: password Re-enter new password: password }}} Enable root login on ssh (run@n9): {{{ ~ #vi /etc/ssh/sshd_config PermitRootLogin yes }}} After saving sshd_config, modify default ssh options (run@n9): {{{ ~ #echo -e 'mkdir -m 0755 -p /var/run/sshd\nexec /usr/sbin/sshd $SSHD_OPTS' >> /etc/default/ssh ~ #pkill -9 /usr/sbin/sshd }}} Now you can access your N9 as root over ssh. '''Be careful: it is a huge security risc.''' (run@host) {{{ $ ssh -X root@192.168.2.15 Password: rootme }}} Maybe you should change default root password, too. == 2.4 Qt5/WebKit packages for Harmattan (optional) == If you don't want to build Qt5 from scratch you can use a repository with the Qt5 modules required by QtWebKit. Instructions on Qt wiki: http://wiki.qt-project.org/Qt_5_on_Nokia_N9 (Almost) Daily snapshots of WebKit are available in the same repository of the Qt5 packages. The package is named 'webkit-snapshot' and the version number indicates the SVN revision that it was built with. The package copies everything from WebKitBuild/Release, except the Source folder, and installs to the same target directory of Qt5, /opt/qt5. Installation (as root through developer mode "devel-su" command): {{{ apt-get update apt-get install webkit-snapshot }}} = 3.Running things on device = The best option is to mount your host on the device using either NFS or SSHFS (the latter is preferred). The alternative is to rsync files over. == 3.1a Mounting SSHFS == If you ran the `setup-device.sh` script with an open mode kernel, you should now have your host available at `/mnt/host`, as well as your home directory available. == 3.1b Transfer files with rsync == With rsync you can deploy the files to the device. Required storage: * (ext4)/home/user - 1GB * (vfat)/home/user/MyDocs - 4.3GB Download rsync for N9 * [http://repo.pub.meego.com/home:/rzr:/harmattan/MeeGo_1.2_Harmattan_Maemo.org_MeeGo_1.2_Harmattan_standard/armel/rsync_3.0.9-1.0%7erzr1_armel.deb Scp rsync installer to N9 as root (run@host): {{{ $ scp rsync_3.0.9-1.0~rzr1_armel.deb root@device:./ $ ssh root@device RM696-40-4_PR_001:~# dpkg -i rsync_3.0.9-1.0~rzr1_armel.deb RM696-40-4_PR_001:~# exit $ }}} Create public key for ssh connection, if you don't have it already (run@host): {{{ $ ssh-keygen -t rsa }}} Copy public key to N9 (run@host): {{{ $ ssh user@device "mkdir .ssh" $ scp ~/.ssh/id_rsa.pub user@device:./.ssh/authorized_keys }}} Now, you don't have to enter password for 'user' when you connect to N9. Download [attachment:rsync-scripts.tar.gz?format=raw rsync-scripts.tar.gz] and extract it to ~/swork. Initialize directory tree for Qt and WebKit files (run@host): {{{ ~/swork/rsync-scripts$ init-rsync.sh }}} Sync files to device: {{{ ~/swork/rsync-scripts$ ./all-rsync.sh }}} This script will execute ./testfonts-rsync.sh, ./qt5-rsync.sh, ./webkit-tests-rsync.sh and ./webkit-build-rsync.sh. This can take some time on first run, so get some coffee or have a lunch. If you don't want to transfer LayoutTests to N9, then you should use '''./all-rsync.sh --no-layout-tests'''. Without this argument rsync always does re-transfer on LayoutTests because of the vfat filesystem's limitation. == 3.2. Running MiniBrowser == === 3.2.1. Environment variables === Now create script for setting environment variables (run@host): {{{ ssh user@192.168.2.15 "echo 'export QTDIR=/home/user/swork/qt5/qtbase' > n9env.sh; \ echo 'export QT_IMPORT_PATH=/home/user/swork/qt5/qtbase/imports' >> n9env.sh; \ echo 'export QML_IMPORT_PATH=/home/user/swork/qt5/qtbase/imports' >> n9env.sh; \ echo 'export LD_LIBRARY_PATH=/home/user/swork/qt5/qtbase/lib:/home/user/swork/qtwebkit-webkit2-dev-builddir-armel-m6/Release/lib' >> n9env.sh; \ echo 'export QT_PLUGIN_PATH=/home/user/swork/qt5/qtbase/plugins' >> n9env.sh; \ echo 'export QT_QPA_PLATFORM_PLUGIN_PATH=/home/user/swork/qt5/qtbase/plugins/platforms' >> n9env.sh; \ echo 'export QT_QPA_PLATFORM=xcb' >> n9env.sh; \ echo 'export WEBKIT_TESTFONTS=/home/user/swork/testfonts' >> n9env.sh; \ echo '# export TZ=/usr/share/zoneinfo/America/Los_Angeles' >> n9env.sh; \ echo 'export PATH=/home/user/swork/qt5/qtbase/bin:$PATH' >> n9env.sh" }}} Load environment variables (run@n9): {{{ . n9env.sh }}} === 3.2.2. Launch browser === (run@n9) {{{ ~/swork/qtwebkit-webkit2-dev-builddir-armel-m6/Release/bin/MiniBrowser }}} [[Image(MiniBrowser.png)]] = 4. Flash back N9 to factory state = If you want to restore the original factory state of the device or flashing went wrong you may need to flash the original firmware to the N9. Flashing - If your device cannot boot up at all, you need to use rd-mode switch steps. - If you re-flash your device just for clean-up, only flashing (Step 2) is required. - If you rewrite device with EMMC binary, than all your data will be lost. Youtube example: * http://www.youtube.com/watch?v=ieeg8XW2zCo&hd=1 '''Step 1''' Disconnect your N9 device from usb. To turn on rd-mode and disable lifeguard-reset run: {{{ sudo flasher --set-rd-flags=no-lifeguard-reset --enable-rd-mode }}} Now connect usb cable and wait for finding the device. '''Step 2''' Disconnect N9 from usb. {{{ sudo flasher -F DFL61_HARMATTAN_20.2011.40-4_PR_LEGACY_001-OEM1-958_ARM.bin -F DFL61_HARMATTAN_20.2011.40-4.CENTRALEUROPE_EMMC_CENTRALEUROPE.bin -f -R }}} Now connect usb cable and wait for minimum 11% battery level, than flashing will be started. '''Step 3''' After flashing is complet and N9 device is rebooted disconnect it from usb. Turn off rd-mode and disable lifeguard-reset: {{{ sudo flasher --clear-rd-flags=no-lifeguard-reset --disable-rd-mode }}} Connect usb cable... '''More about R&D mode:''' - http://wiki.maemo.org/R%26D_mode '''Notes''' If your device has hardware error (corrupted flash storage), you will get similar results as these: {{{ Battery level 72 %, continuing. image [state progress transfer flash speed] --------------------------------------------------------------------- [x] cert-sw [finished 100 % 1 / 1 kB NA ] [x] cmt-2nd [finished 100 % 95 / 95 kB NA ] [x] cmt-algo [finished 100 % 789 / 789 kB NA ] [_] cmt-mcusw [init 0 % 1024 / 6050 kB NA ] [x] xloader [finished 100 % 23 / 23 kB NA ] [x] secondary [finished 100 % 93 / 93 kB NA ] [x] kernel [finished 100 % 2712 / 2712 kB 1271 kB/s] [_] rootfs [init 0 % 12288 / 1102340 kB NA ] ERROR: SU_GET_UPDATE_STATUS_REQ terminated with error code 1: Unknown error image [state progress transfer flash speed] --------------------------------------------------------------------- [x] cert-sw [finished 100 % 1 / 1 kB NA ] [x] cmt-2nd [finished 100 % 95 / 95 kB NA ] [x] cmt-algo [finished 100 % 789 / 789 kB NA ] [x] cmt-mcusw [finished 100 % 6050 / 6050 kB 3317 kB/s] [x] xloader [finished 100 % 23 / 23 kB NA ] [x] secondary [finished 100 % 93 / 93 kB NA ] [x] kernel [finished 100 % 2712 / 2712 kB 1271 kB/s] [f] rootfs [init 0 % 13312 / 1102340 kB NA ] Fetching error list: ======================================== bb5_rdc_cert_read failed bb5_rdc_cert_read failed bb5_rdc_cert_read failed bb5_rdc_cert_read failed bb5_rdc_cert_read failed bb5_rdc_cert_read failed mmc: Could not find device path under /sys/class/mmc_host/mmc0 mmc: Failed to init mmc block device scconf_parse_entries failed: (null) Unable to parse layout mmc: Could not remove mount directory /tmp/sudmmc9J3FtB/mnt: No such file or dir ectory mmc: Could not unlink (null): Bad address [Pipe 3] Finishing in error state with status 1 }}} = 5. Alternative methods if the above tutorial fails = This section has been tested on N9 with PR1.2 (30.2012.07.1) used with [http://maemo.cloud-7.de/HARM/N9/1.2/ openmode pached kernel]. == 5.1 Building QtWebKit with prebuilt Qt5 libraries == Sometimes you may have difficulties when you try to build Qt5. In this case you may use LMouras prebuilt Qt5 libraries: http://wiki.qt-project.org/Qt_5_on_Nokia_N9 . For this method you have to use ScratchBox as building environment, read more about this in [http://trac.webkit.org/wiki/SettingUpDevelopmentEnvironmentForN9?version=19#a1.ScratchboxInstructions previous version of the tutorial]. Inside ScratchBox: {{{ get http://qtlabs.org.br/~lmoura/qt5/conf/qt5-repository_0.3_all.deb dpkg -i qt5-repository_0.3_all.deb apt-get update apt-get install "qt5-*" }}} Repeat these steps on you N9/N950 device after you logged in as root with devel-su (password: rootme). Clone WebKit repository to your ~/swork/webkit directory. Build QtWebKit with the following inside ScratchBox: {{{ export PATH=/opt/qt5/bin/:$PATH export WEBKITOUTPUTDIR=/home/$USER/swork/qtwebkit-webkit2-dev-builddir-armel-m6 cd /home/$USER/swork/webkit ./Tools/Scripts/build-webkit --qt --release --makeargs=-j9 --no-3d-canvas }}} == 5.2 Mounting NFS == Add your key to the device if you not done already: {{{ ssh developer@device "mkdir -p .ssh" scp ~/.ssh/id_rsa.pub developer@device:./.ssh/authorized_keys }}} Install required utils and settings to your host: {{{ sudo apt-get install nfs-kernel-server portmap sudo echo "/scratchbox/users/$USER/home/$USER/swork 192.168.2.15(rw,all_squash,anonuid=1000,anongid=1000)" >> /etc/exports sudo echo "/home/$USER/swork 192.168.2.15(rw,sync,no_root_squash)" >> /etc/exports sudo /etc/init.d/nfs-kernel-server restart }}} Log in to your N9/N950 device and install: {{{ ssh developer@192.168.2.15 devel-su rootme cd /root apt-get install wget wget http://repo.pub.meego.com/home:/rzr:/harmattan/MeeGo_1.2_Harmattan_Maemo.org_MeeGo_1.2_Harmattan_standard/armel/libwrap0_7.6.dbs-maemo6.1_armel.deb wget http://repo.pub.meego.com/home:/rzr:/debian/harmattan/armel/portmap_6.0.0-2_armel.deb wget http://maemo.cloud-7.de/HARM/N9/openmode_kernel_PR1.1/opensh/opensh.deb AEGIS_FIXED_ORIGIN=com.nokia.maemo dpkg -i libwrap0_7.6.dbs-maemo6.1_armel.deb AEGIS_FIXED_ORIGIN=com.nokia.maemo dpkg -i portmap_6.0.0-2_armel.deb AEGIS_FIXED_ORIGIN=com.nokia.maemo dpkg -i opensh.deb apt-get install libxslt1.1 logout logout }}} You can create mount script on your N9/N950 by running on your host: {{{ ssh developer@192.168.2.15 "mkdir -p /home/developer/swork; \ echo 'opensh -c \"/sbin/portmap; /sbin/modprobe nfs; mount -t nfs 192.168.2.14:/home/$USER/swork /home/developer/swork\"' > nfsmount.sh; \ chmod +x nfsmount.sh " }}} Log in to your device and run: {{ ssh developer@device . nfsmount.sh }}} == 5.3 Run QtWebKit with prebuilt Qt5 on N9/N950 == You can create a script that loads the environment variables by running this on your host: {{{ ssh developer@192.168.2.15 "echo 'export QTDIR=/opt/qt5' > n9env.sh; \ echo 'export QT_IMPORT_PATH=/opt/qt5/imports' >> n9env.sh; \ echo 'export QML_IMPORT_PATH=/opt/qt5/imports' >> n9env.sh; \ echo 'export LD_LIBRARY_PATH=/opt/qt5/lib:/home/developer/swork/qtwebkit-webkit2-dev-builddir-armel-m6/Release/lib' >> n9env.sh; \ echo 'export QT_PLUGIN_PATH=/opt/qt5/qtbase/plugins' >> n9env.sh; \ echo 'export QT_QPA_PLATFORM_PLUGIN_PATH=/opt/qt5/plugins/platforms' >> n9env.sh; \ echo 'export QT_QPA_PLATFORM=xcb' >> n9env.sh; \ echo 'export WEBKIT_TESTFONTS=/home/developer/swork/testfonts' >> n9env.sh; \ echo '# export TZ=/developer/share/zoneinfo/America/Los_Angeles' >> n9env.sh; \ echo 'export PATH=/opt/qt5/bin:$PATH' >> n9env.sh" }}} Finally, you can run MiniBrowser or QtTestBrowser on N9/N950: {{{ ssh developer@192.168.2.15 . n9env.sh ./swork/qtwebkit-webkit2-dev-builddir-armel-m6/Release/bin/MiniBrowser ./swork/qtwebkit-webkit2-dev-builddir-armel-m6/Release/bin/QtTestBrowser }}}