The Mer Wiki now uses your Mer user account and password (create account on https://bugs.merproject.org/)
SDK on VirtualBox/Design
Contents |
Overview
The virtualised SDK architecture supports multiple devices and emulators with a single Build Engine.
The main components are:
- Build Engine
- Qt Creator
- Virtualbox Emulator(s)
- Physical device(s)
VirtualBox shared folders are used for sharing files between the host and the build engine and emulators for:
- Configuration
- SSH keys
- Home directory
- Targets
- Other source directory trees
current
There are 3 shared folders at the moment.
mersdk:/etc/mersdk is mapped to the SailfishOS application areas mersdk folder and contains: configuration, targets and the ssh keys
home:/home/mersdk is mapped to the users 'home' directory
srcN:/home/srcN are each mapped to source directory areas on the host
planned
The upcoming SDK will have 4 shared folders on the Engine and 2 on the Emulator:
- ./vmshare is shared as 'config' to MerSDK and emulators mounted under /etc/mersdk/share
./vmshare/ssh/private_keys/$index/$user private keys to ssh to emulators ./vmshare/devices.xml device description/config
- ./mersdk/targets is shared as 'targets' to MerSDK mounted under /host_targets/
./mersdk/targets/$name/ Targets ./mersdk/targets/targets.xml Target description
- ./mersdk/ssh is shared as 'ssh' to MerSDK mounted under /etc/sshd/authorized_keys
./mersdk/ssh/$user/authorized_keys authorized_keys for sshd
- ./emulator/$index/ssh is shared as 'ssh' to Emulator $index mounted under /etc/sshd/authorized_keys
./emulator/$index/ssh/$user/authorized_keys authorized_keys for sshd
Notice that there may be multiple emulators so each one has an 'internal persistent DeviceID' (ie not something changeable and user visible like a name) A simple index will be enough - we can use the same index for the internal LAN (see below)
Additional src dir mappings will look like this:
- QtCreator asks for a shared src path
- Runs:
VBoxManage sharedfolder add MerSDK src<N> --hostpath <path>
- Also adds the path to:
./share/qtcreator/MerProject/QtCreator.ini at MerSDK/SharedSrc<N>
- Then run sdk-manage --srcdir --add 1
- This adds and mounts a /home/src<N> mountpoint (using systemd). Change --add to --remove to remove
- The current version of scripts in sdk-utils/sdk-vm assumes these paths
Networking
Overview
The SDK network serves the following purposes:
- Host -> Build Engine for ssh/web
- Host -> Emulator for ssh/debugging
- Host -> Device for ssh/debugging
- Build Engine -> internet for updates and information
- Build Engine -> Device with ssh to support deployment
- Build Engine -> Emulator with ssh to support deployment, execution and debugging
- Emulator -> internet for updates and information
- Device -> Build Engine to authorise SDK activity
To do this the Emulator and Build Engine will have 2 network adaptors.
An adaptor running in NAT mode allows open outbound access and permits some incoming connections (ssh, www and gdb). This also handles Engine > Device connectivity.
A second adaptor is setup on the Build Engine and Emulators as a VirtualBox internal adaptor and supports open Build Engine <> Emulator(s) connectivity.
Note in the discussion the emulator 'index' is just a low value integer to support multiple emulator configurations.
QtCreator and the Build Engine need to collaborate to setup the Emulator internal networking.
To share information between QtCreator, the Build Engine and the Emulators there is a devices.xml file stored on the 'config' shared folder.
It looks like this:
<devices> <engine name="Mer SDK" type="vbox"> <subnet>10.220.220</subnet> <version>VER</version> <available acknowledged_on="timestamp">NEWVER</available> </engine> <device name="Nemo N9" type="real"> <ip>192.168.0.12</ip> <sshkeypath>ssh/private_keys/d1</sshkeypath> <!-- relative to this XML file --> <version>VER</version> <available acknowledged_on="timestamp">NEWVER</available> </device> <device name="SailfishOS Emulator" type="vbox"> <index>2</index> <!-- this is used to make the IP address --> <subnet>10.220.220</subnet> <!-- hardcode 10.222.222 as default for now --> <sshkeypath>ssh/private_keys/2</sshkeypath> <mac>08:00:5A:11:00:02</mac> <!-- used to by Emulator to identify itself --> <version>VER</version> <available acknowledged_on="timestamp">NEWVER</available> </device> </devices>
Build and Deployment
The primary goal of the SDK is to make it easy to build application packages.
The build process aims to follow the Qt-way and at the same time make the creation of packages as simple as possible.
It should be easy to do simple things and possible to do complex things.
The solution we use is to do every build as a proper package build but to avoid repeating steps or executing uneeded ones.
This ensures that any errors in the project such as using assets not handled by the install step are caught early - it also means that making a package is incremental and not a burden at the end of a project.
Packaging
The ultimate goal is to deliver a quality package to your end-user. This package is an rpm and will contain your binaries, QML and any assets such as sound and image files.
Building
When an application is built the normal qmake/make steps are run - but they happen as they would in a package build.
Deployment
We supports two deployment styles: package and fast
Package deployment
Normal deployment using rpm -i/-U will install to / - eg /usr/lib/<pkg> ie system locations
So when a build is finished and you want to deploy QtC will run a 'make install', package up the files and create an rpm which installs under / like any other package.
Fast deployment
However, during development you probably don't want to build a full rpm package and re-install it just to check a tiny change in a qml file.
So the SDK supports fast (incremental) deployment.
Clearly it is not ideal to simply install files all over a device potentially overwriting system files and certainly making it hard to clean up later - so the fast deployment installs within a development area.
Simply the build process runs 'make install' and then uses rsync to copy any changed files over to an area on the device/emulator known as the "deployment root" - /opt/sdk/<pkg>
To enable this to work DEPLOYMENT_ROOT environment variable is set for code running in this manner.
The cleanest mechanism is for code to be aware of the mechanism:
QString(getenv("DEPLOYMENT_ROOT"))+QString("/usr/share/translations"));
engineeringEnglish->load("app_eng_en", QString(getenv("DEPLOYMENT_ROOT"))+QString("/usr/share/translations"));
Alternative build-time solutions could also be devised.
Deployment mechanism
The Build engine handles the actual transfer of data since it has rsync and access to src/build results and there are no cross-platform issues. To do this it needs network and credential information about the device. QtC manages an XML file about the devices and shares this as the devices.xml described on this page.
This xml will also contain a list of emulators and info about them.
mb2 is now able to look at this and run rsync or copy and install the rpm
Packaging Metadata
The SDK allows the management of the metadata for a package.
Ths is done by allowing the user to
- use simple SDK UI
- extend the metadata for more complex packages
- edit the yaml file
- discard all assistance and use the raw spec file
This should include rpm package dependencies obtained from .pro and manually added dependencies.
One new requirement is that the Build engine and emulator need to talk to each other over tcp so we need to add a host-only network. This is needed for some future features too so that's acceptable.