- 1 Building Packages
- 2 Building Binaries Locally
- 3 Packaging formats
- 4 Changelog generation
Packages may either be built locally (using
sb2 using the Platform SDK), or remotely (using the Mer OBS). Building locally has the advantage of being quick, simple, and low-latency. Building remotely has the advantage that build dependencies and other packaging requirements are enforced more strictly, and that upgrading packages built from OBS can be done via system upgrade rather than sideloaded via direct installation using `rpm`.
Building Packages Remotely
Packages may be built using the Open Build Service instance. This requires the user to create a home project, and then create a package under that project, with the appropriate `_service` file to specify how the project should be built and packaged. Once the build has been triggered, OBS will attempt to pull in the required dependencies and build the package.
See the page about deploying packages for information on how to install the package once built.
Building Packages Locally
Once the user has installed the Platform SDK and set up an SDK target, they can build packages locally for the target architecture using the build script called
mb2 invoked from the Platform SDK. This script is a wrapper around ScratchBox2 (
rpmbuild which makes it simple to build packages from source repositories, given an RPM specification (.spec) file.
The mb2 script is invoked as follows to build a package:
mb2 -s <path/to/rpm.spec> -t <SDK_target> build
Note that the first two parameters are optional if there is only one single .spec file contained under the rpm/ subdirectory of the project.
For example, the following command will build most projects and package the results into an .rpm ready for installation, when run from the Platform SDK chroot prompt, within the project directory, assuming that an SDK target called "SailfishOS-armv7hl" has been installed:
mb2 -t SailfishOS-armv7hl build
The output .rpm files will be contained under the RPMS/ subdirectory of the project, and these may be installed to the device or SDK target as described in the page on deploying packages.
Installing Missing Dependencies
In some cases, the developer will have to add or enable repositories within their SDK target, if the
mb2 script complains that a dependency cannot be installed. To do so, the user should enter ScratchBox2 within the SDK chroot environment, and then use:
ssu ar <repo_name> <repo_url>
to add repositories, and
ssu er <repo_name>
to enable repositories, and then
zypper ref -f
to update the installable package information.
ssu lr may be used to list known repositories, and
ssu rr <repo_name> will remove a repository.
# enter the Platform SDK chroot ~ $ /srv/mer/sdks/sdk/mer-sdk-chroot # enter ScratchBox2 root shell in sdk-install mode PlatformSDK ~ $ sb2 -t SailfishOS-armv7hl -m sdk-install -R # enable the mer-core repository if not already enabled [SB2 sdk-install SailfishOS-armv7hl] ~ # ssu er mer-core # reload the package list [SB2 sdk-install SailfishOS-armv7hl] ~ # zypper ref -f
To determine which repository provides a given package, a contributor should use the search feature of the Mer OBS instance, at https://build.merproject.org/search
It should be noted that device or hardware-platform-specific packages (especially those needed to build hybris-related packages) are best installed into a separate SDK target, to avoid complications. See Platform SDK Target Installation for more information on how to create new SDK targets.
Building Binaries Locally
In some cases, you will not want to build an entire package (.rpm) to install, but instead want to build a single binary from a simple (most likely Qt-based) project. This can be handy, for example, during testing or prototyping.
In this case, you simply need to build the project from within a build-mode ScratchBox2 prompt. For example, to build a simple Qt-based project (called "test", located under ~/test/ of the host) the following steps could be taken:
# enter the Platform SDK chroot ~ $ /srv/mer/sdks/sdk/mer-sdk-chroot # enter ScratchBox2 shell in sdk-build mode PlatformSDK ~ $ sb2 -t SailfishOS-armv7hl -m sdk-build # run qmake && make from within sb2 build prompt [SB2 sdk-build SailfishOS-armv7hl] ~ $ cd ~/test && qmake && make
The resulting ARMv7 binary can be copied to the device with
scp and executed directly.
tar_git packaging structure
Package in Sailfish OS are mostly packaged with format called tar_git. This format is relatively simple and as long as one follows some basic instructions tools like
mb2 work nicely and if
mb2 works then it is quite likely that also the package builds fine after integrating as part of the release process.
Some basic things to remember: the rpm .spec files are located in
rpm/*.spec. There is no need to have .changes file, except for historical reasons, and in that case those are located in
rpm/*.changes. Also all other files in
rpm/ directory must be marked either with SourceX: or PatchX:. Package version is determined from the latest suitable Git tag. The Version: and Release: tags in the .spec file are ignored – setting them to "0" and "1" respectively is the preferred convention.
tar_git package source code location in git
The sources are usually located either within the same git tree, in case the code upstream is Sailfish OS itself. It can be in the root of the git tree or src dir or something similar depending a bit on the package. Example of such package is for example mce at https://git.merproject.org/mer-core/mce/tree/master
If the package has upstream somewhere else and there are no heavy modification needed for the sources, the sources are usually located in directory named the same as the package Name: in .spec file. Example of such package crda at https://git.merproject.org/mer-core/crda/tree/master and usage instructions.
Then there is the third option where there are many modifications to the upstream that are not accepted as a part of the upstream (at least yet). In such cases there is submodule usually called upstream as well as directory matching to Name: in .spec that contains a copy of the upstream with the modifications. Example of such package e.g. connman at https://git.merproject.org/mer-core/connman/tree/master and usage instructions.
There can be also cases where there is no submodule located in the git tree, which usually is because upstream is either tarball, cvs or svn based and git submodule can not be done. TODO: add link to example of such package.
tar_git packages with patches
Some packages have patches but are not copied as separate tree from upstream, in such cases the patches are located in
rpm/*.patch. Pulseaudio is an example of such package at https://git.merproject.org/mer-core/pulseaudio/tree/master
Those patches can be applied with
mb2 apply to the submodule and can be unapplied with
mb2 -R apply.
This is obsolete format and is something that should not be used anymore and any packages using this should be converted to tar_git format explained above. These dumb packages are basically packages where the .spec file with tarball are located in the root of the git tree. Example of such packaging can be found at https://git.merproject.org/mer-core/libtalloc/tree/bb16d36c3aa6e85e4c75803beb076ae239fa428a
Such packages do not compile with the normal
mb2as the packages done with tar_git format, but these need to be build with more conventional tools, for example:
git clone https://git.merproject.org/mer-core/example-dumb-package.git cd example-dumb-package sb2 -t SailfishOS-armv7hl rpmbuild --define "_topdir `pwd`" --define "_sourcedir `pwd`" -bb *.specinstead of
Should be noted that when using
rpmbuild you need to manually install also package build dependencies, where
mb2 does that automatically.
Changelogs are generated from git commits in tar_git packaged packages. Basically how it works is that each line that follows following format is added to the changelog:
[key] Summary. Contributes to xyz#123 [packaging] Updated Y to version X. Fixes xyz#124
mb2 --help inside the SDK to learn how to generate changelogs when building a package with mb2 locally
This line does not need to be the first line in the git commit message and there can be multiple lines within one git commit message.
There are couple of ways to refer bugs in the git commit messages
|Contributes to xyz#123||Means that this change contributes to the referred bug number, but does not fully fix it yet. This kind of lines are usually used when the required fixes to one bug are needed across multiple packages or for example the fix improves the issue, but there might still be some corner case that it might be reproduced.|
|Fixes xyz#124||Means that this change fixes the bug.|
Currently known and accepted bug tags for the above xyz are:
|MER||For bugs at https://bugs.merproject.org/|
|NEMO||For bugs at https://bugs.nemomobile.org/|
|JB||For bugs in internal Jolla Bugzilla|
These lines are picked to the changelog based on tags, meaning that between two tags all the lines that are following the format are picked up and added to the changelog.