Starting point: one old BQ Aquaris E5 ubuntu phone, running some old version of Ubuntu Touch which had got completely stuck (UI only unfreezing for 2-3 seconds every 2-3 minutes).
Step one: flash to latest UBPorts image:
- Set up Ubuntu desktop as a host (as per https://docs.ubuntu.com/phone/en/devices/installing-ubuntu-for-devices)
sudo add-apt-repository ppa:ubuntu-sdk-team/ppa
sudo apt-get update
sudo apt-get install ubuntu-device-flash
sudo apt-get install phablet-tools
- Grab an adb-compatible recovery image (yes, seems like the right place is somsone's personal webspace...)
wget http://people.canonical.com/~jhm/barajas/recovery-vegetahd.img
- If your Ubuntu desktop is running in a VM, make sure you have USB 2.0 or 3.0 support enabled (in Virtualbox this needs the extension pack installed). USB 1 is too slow and the flash will timeout, semi-bricking the phone.
- Press volume-up and power on the phone during boot to get at the bootloader. Make sure it's not plugged into USB
- Select fastboot
- Plug into USB
- Flash the recovery image and latest UBPorts OS:
sudo ubuntu-device-flash --server=http://system-image.ubports.com touch --device=vegetahd \
--channel=15.04/stable --bootstrap --recovery-image=recovery-vegetahd.img \
--developer-mode --password=secret
- Ensure the system OS is writable. (Ubuntu Touch runs the OS partition read-only by default to protect users. In this case, you can always re-flash it if all goes wrong.)
sudo phablet-config writable-image
- Get an SSH server running on the phone before you go insane
adb shell
sudo /etc/init.d/ssh start # password is as set when flashing.
Step two: cross-compile latest Qt 5.9 for the phone.
Ubuntu 15.04 shipped with 5.4, which is pretty old now, and too old for nheko. Based on https://rm5248.com/cross-compile-qt-for-arm/
# grab the source for Qt5
git clone git://code.qt.io/qt/qt5.git
cd qt5
./init-repository
# grab the right dev headers (as qtubuntu needs dbus & atspi support)
ssh phablet@phone "sudo apt-get install libdbus-1-dev libatspi2.0-dev libssl-dev"
# grab a copy of the root filesystem on the phone for the cross-compile to run against.
# you could also sshfs mount or something if you could be bothered.
mkdir ~/phone
rsync -avz --exclude /proc --exclude /run --exclude /sys --exclude /dev \
--exclude /android --exclude /var/lib/lxc phablet@phone:/ ~/phone/system
export ROOTFS=~/phone
# install the crosscompiler.
# We probably have to use GCC 4.9 so that it can link ok against the older system libraries
# (libstdc++ etc) on Ubuntu Touch 15.04
sudo apt-get install arm-linux-gnueabihf-g++-4.9
# fix up the absolute symlinks (important!)
cd ~
git clone https://github.com/rm5248/cross-compile-tools.git
./cross-compile-tools/fixQualifiedLibraryPaths $ROOTFS /usr/bin/arm-linux-gnueabihf-g++-4.9
# define a mkspec target for armhf
cd ~/qt5
cp -a qtbase/mkspecs/linux-arm-gnueabi-g++ qtbase/mkspecs/linux-arm-gnueabihf-g++
cat > qtbase/mkspecs/linux-arm-gnueabihf-g++/qmake.conf <<EOT
#
# qmake configuration for building with arm-linux-gnueabihf-g++
#
MAKEFILE_GENERATOR = UNIX
CONFIG += incremental
QMAKE_INCREMENTAL_STYLE = sublib
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
# modifications to g++.conf
QMAKE_CC = arm-linux-gnueabihf-gcc-4.9
QMAKE_CXX = arm-linux-gnueabihf-g++-4.9
QMAKE_LINK = arm-linux-gnueabihf-g++-4.9
QMAKE_LINK_SHLIB = arm-linux-gnueabihf-g++-4.9
# modifications to linux.conf
QMAKE_AR = arm-linux-gnueabihf-ar cqs
QMAKE_OBJCOPY = arm-linux-gnueabihf-objcopy
QMAKE_NM = arm-linux-gnueabihf-nm -P
QMAKE_STRIP = arm-linux-gnueabihf-strip
!host_build {
QMAKE_INCDIR_OPENGL = $ROOTFS/usr/include/GL
QMAKE_LIBDIR_OPENGL = $ROOTFS/usr/lib/arm-linux-gnueabihf
# GCC 4.9 apparently doesn't know where its own libstdc++ headers are when cross-compiling...
QMAKE_INCDIR = /usr/arm-linux-gnueabihf/include/c++/4.9.3 \
/usr/arm-linux-gnueabihf/include/c++/4.9.3/arm-linux-gnueabihf
}
load(qt_config)
EOT
# build it!
./configure \
-v \
-confirm-license \
-prefix /opt/qt5-arm \
-sysroot $ROOTFS \
-opensource \
-nomake examples \
-nomake tests \
-opengl es2 \
-qpa ubuntumirclient \
-xplatform linux-arm-gnueabihf-g++ \
-platform linux-g++ \
-feature-accessibility \
-feature-accessibility-atspi-bridge \
-feature-webrtc \
-feature-proprietary-codecs \
-reduce-exports
make -j8
# go to lunch
make install
If anything goes wrong, a good bet (having backed up your new mkspec target) is to git clean everything:
git submodule foreach --recursive "git clean -dfx"
git clean -dfx
Step 3: compile qtubuntu for Ubuntu-specific Qt stuff like the integration with the Mir display server (hey, at this point it feels like we're building our very own zombie Ubuntu Touch 17.04... :/)
# grab dev package deps
ssh phablet@phone "sudo apt-get install libubuntu-application-api-dev libudev-dev"
rsync -avz --exclude /proc --exclude /run --exclude /sys --exclude /dev \
--exclude /android --exclude /var/lib/lxc phablet@phone:/ ~/phone/system
~/cross-compile-tools/fixQualifiedLibraryPaths $ROOTFS /usr/bin/arm-linux-gnueabihf-g++-4.9
# grab the qtubuntu source
bzr branch lp:qtubuntu
# find an version old enough that it builds against the old mir in 15.04
bzr revert -r 345
# cherrypick patches so it builds against qt 5.9...
http://bazaar.launchpad.net/~phablet-team/qtubuntu/trunk/revision/354
http://bazaar.launchpad.net/~phablet-team/qtubuntu/trunk/revision/372
http://bazaar.launchpad.net/~phablet-team/qtubuntu/trunk/revision/394
# ...we probably need others too.
/mnt/build/qt5/qtbase/bin/qmake -spec /mnt/build/qt5/qtbase/mkspecs/linux-arm-gnueabihf-g++
# we probably should have told Qt about more pkgconfig libraries when we built it, so as to not have to do it manually here...
export PKG_CONFIG_LIBDIR=$ROOTFS/usr/lib/pkgconfig:$ROOTFS/usr/share/pkgconfig:\
$ROOTFS/usr/lib/arm-linux-gnueabihf/pkgconfig/:$ROOTFS/opt/qt5-arm/lib/pkgconfig/
export PKG_CONFIG_SYSROOT_DIR=$ROOTFS
# might need to manually explicitify the --sysroot definitions in qt's qconfig.pri
# as otherwise QT_SYSROOT seems not to be getting picked up for reasons unknown
make -j4
cp src/ubuntumirclient/libqpa-ubuntumirclient.so $ROOTFS/opt/qt5-arm/plugins/platforms/
# Need to build our own libmaliitphabletplatforminputcontextplugin.so for onscreen keyboard, as
# you can't mix Qt platform plugins between versions - see https://bugreports.qt.io/browse/QTBUG-46009
cd
bzr branch lp:ubuntu/vivid/maliit-framework
cd maliit-framework
# add QMAKE_LFLAGS+='-lQt5Network -lGLESv2' to config.pri
# technically don't need to build all of maliit - only the platform inputcontext plugin is required
export QMAKEMODULES=/mnt/build/qt5/qtdeclarative/mkspecs/modules
/mnt/build/qt5/qtbase/bin/qmake -spec /mnt/build/qt5/qtbase/mkspecs/linux-arm-gnueabihf-g++
make -j4
# build the input-context plugin
cd input-context
# change the version of the plugin in main.cpp so that it's picked up by Qt 5.9 (the API hasn't changed;
# it's just the difference between an explicit and implicit version):
# Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformInputContextFactoryInterface.5.1" FILE "maliit.json")
/mnt/build/qt5/qtbase/bin/qmake -spec /mnt/build/qt5/qtbase/mkspecs/linux-arm-gnueabihf-g++
make -j4
make install
# rsync our beautiful new Qt5.9 over to the phone, including the qtubuntu plugin
rsync -avz $ROOTFS/opt/qt5-arm root@phone:/opt/
Step 4: cross-compile nheko as an experiment
# check it out
git clone --recursive git+ssh://[email protected]/mujx/nheko
cd nheko
# define a cross-compile toolchain (https://cmake.org/Wiki/CMake_Cross_Compiling)
cat > Toolchain-arm-linux-gnueabihf.cmake <<EOT
# this one is important
SET(CMAKE_SYSTEM_NAME Linux)
# this one not so much
SET(CMAKE_SYSTEM_VERSION 1)
# needed to get the right flavour of ARM
SET(CMAKE_SYSTEM_PROCESSOR armv7)
# specify the cross compiler
SET(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabihf-gcc-4.9)
SET(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabihf-g++-4.9)
# where is the target environment
SET(CMAKE_SYSROOT $ROOTFS)
SET(CMAKE_FIND_ROOT_PATH $ROOTFS)
# sort out our includes...
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
-I$ROOTFS/usr/include/c++/4.9 \
-I$ROOTFS/usr/include/arm-linux-gnueabihf \
-I$ROOTFS/usr/include/arm-linux-gnueabihf/c++/4.9")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} \
$ROOTFS/lib/arm-linux-gnueabihf/libc.so.6 \
$ROOTFS/usr/lib/arm-linux-gnueabihf/libm.so \
$ROOTFS/usr/lib/arm-linux-gnueabihf/libhybris-egl/libGLESv2.so.2")
# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
SET(CMAKE_PREFIX_PATH $ROOTFS/opt/qt5-arm)
EOT
# grab its dependencies on the phone and sync them over to your local phone FS copy
ssh phablet@phone 'sudo apt-get install liblmdb-dev'
rsync -avz --exclude /proc --exclude /run --exclude /sys --exclude /dev \
--exclude /android --exclude /var/lib/lxc phablet@phone:/ ~/phone/system
~/cross-compile-tools/fixQualifiedLibraryPaths $ROOTFS /usr/bin/arm-linux-gnueabihf-g++-4.9
# gen the makefile
sudo apt-get install cmake
cmake -DLMDB_LIBRARY=$ROOTFS/usr/lib/arm-linux-gnueabihf/liblmdb.so \
-DCMAKE_TOOLCHAIN_FILE=`pwd`/Toolchain-arm-linux-gnueabihf.cmake \
-H. -Bbuild -DCMAKE_BUILD_TYPE=Release
# remove -march=native from CMakeLists.txt
# build it
VERBOSE=1 make -C build -j4
# XXX: you might need to touch the Toolchain file and then run again to pick up
# the CXX_FLAGS correctly for some reason.
# run it!
rsync -avz $ROOTFS/home/phablet/nheko phablet@phone:/home/phablet
ssh phablet@phone "export MIR_SOCKET=/run/user/32011/mir_socket;
./build/nheko --desktop_file_hint=unity8"
# N.B. if debugging under gdb, use `handle SIGILL nostop`
Step 5: Package nheko
# make sure you have a manifest.json, nheko.png, nheko.apparmor and nheko.desktop.
# If you don't have an icon, the app won't show up.
# you can grab it from the matthew/mobile branch of github.com/matrix-org/nheko
click build ./
scp im.vector.nheko_0.1_all.click phablet@phone:
# install it
ssh phablet@phone pkcon install-local --allow-untrusted im.vector.nheko_0.1_all.click
# ...and then swipe down on the app listing to hopefully see the app there.
# if that doesn't work, you can manually launch it with:
ssh phablet@phone ubuntu-app-launch im.vector.nheko_nheko_0.1