Skip to main content

HADK - Hot

These might be contenders to merge to:
The intention is to begin making this a wiki.
Unofficial hadk-hot
Improve and make PR to hadk-faq if you think that particular instruction is and will be useful for longer time.
-------------------------------------------------- -------------------------------------------------- -----


* Fatal: 'rpm/kf5bluezqt-bluez4.spec' does not exist (and could not be made from a .yaml)" when building middleware. Remove the following lines in dhd:
sdk-assistant maintain $VENDOR-$DEVICE-$PORT_ARCH zypper se kf5bluezqt-bluez4 > /dev/null
if [ $ret -eq 104 ]; then
buildmw -u "" \
           -s rpm/kf5bluezqt-bluez4.spec || die
      # pull device's bluez4 configs correctly
     sdk-assistant maintain $VENDOR-$DEVICE-$PORT_ARCH zypper remove bluez-configs-mer
* "/bin/sh: ccache: command not found" when building pulseaudio-modules-droid from middleware. Do:
sb2 -t $VENDOR-$DEVICE-$PORT_ARCH -R -m sdk-install zypper in ccache
* File /etc/bluez5/bluetooth/main.conf from droid-config-*-bluez5 conflicts with file from package bluez5-configs-mer. Do:
sb2 -t $VENDOR-$DEVICE-$PORT_ARCH -m sdk-install -R zypper rm bluez5-configs-mer
* The OBS API url used to osc changed, it's now . If you have local checkout and you want to replace to url in those use something like this:
grep --include=_apiurl -rl . | xargs sed -i 's/'
grep --include=_apiurl -rl . | xargs sed -i 's/'
depending on which url you had been using before. In addition to changing it in local checkouts also fix the url in .oscrc

* 'zypper ref' doesn't really check whether url is correct or even reachable.  It doesn't even mention failed refresh metadata for unavailable repositories. It seems to be related to ssu repository plugin.


2024.02.08: Android base specific fixes

* since hybris-18:
- Do not use fetch-submodules when repo cloning repostories

Since hybris-17:
-  Add appropriate android_version_major:
- 'library "" not found': If you device do not use /odm then create sparse/odm/lib64/ (or sparse/odm/lib for 32bit minimediaservice) and put symlink pointing to /apex/ or some similar path with that library. Usually adding only one simlink is enough, sometimes you may need also and If your device use /odm and it contains valid data only in /odm/etc/ directory then mount odm partition to /.odm_root, create sparse/odm/lib* directory with needed symlinks in droid-config and bind mount /.odm_root/etc/ to /odm/etc/.
* Since hybris-16:

Before building hybris-hal run the following commands:

cd $ANDROID_ROOT/external
git clone --recurse-submodules
hybris-patches/ --mb
* Since android 8: some partitions can be mounted very early based on entries from devicetree instead android's fstab. Make sure you have all these partitions mounted in sailfish. For example samsung exynos7420.dtsi devicetree have defined efs partition which may be required to get wifi working correctly:
It can be checked also on device in:

* For android 8-10 devices which use system-as-root without separate recovery you need to disable skip_initramfs handling so kernel can use hybris-boot initramfs. In kernel init/initramfs.c history find 2 following commits and revert them: "call free_initrd() when skipping init" and "Add skip_initramfs command line option". Alternatively, you can force in source code do_skip_initramfs = 0.

* If you do not package '/system' partition like in Sailfish X AOSP build instructions then you must have actual files instead symlinks in sparse/etc/selinux. Possible error message: Servicemanager: add_service Permission denied.

hybris-20 WIP
* Use android13 branch for droid-config and build latest mce to avoid following error:
/usr/sbin/dummy_compositor: unrecognized option '--hwc-restart'
* "logd: libprocessgroup: Loading /etc/task_profiles.json for [2209] failed", then copy task_profiles.json from /system/etc to /etc and also add symlink /etc/task_profiles which points to /system/etc/task_profiles

* build libui_compat_layer in HABUILD

* dmesg errors:
kernel: loop_set_status: loop0 () has still dirty pages (nrpages=
kernel: print_req_error: I/O error, dev loop1, sector 0
kernel: Buffer I/O error on dev loop1, logical block 0, async page read
apexd: Failed to LOOP_SET_BLOCK_SIZE: Try again
Leads to apexd-bootstrap failure, ueventd start and reboot to fastboot mode. Apply this:
* 'Buffer I/O error on dev loop2, logical block 0, async page read'
Try adding loop.max_part=7 to kernel cmdline to makes loop images partitionable

* Starting ueventd can be caused by failure of some important services with reboot_on_failure option like apexd. This should be fixed in hybris-patches to ease early debugging.

* For devices which use dynamic partitions without real block devices for system, vendor or product either follow aosp hadk way and package all dynamic partitions or use to map them and then mount by some script or custom systemd mount units. List of dynamic partitions can be found in BoardConfig*.mk and android's fstab. 
Example solution for dynamic partitions handled via systemd:
- Do not forget enabling these mount units
- To prevent droid-hal creating incorrect systemd mount units add all dynamic partitions to makefstab_skip_entires similar to:
- If your kernel have enabled selinux in permissive instead enforcing mode, files in /etc/selinux are correct and logcat shows:
Unknown class service_manager
Could not self register servicemanager
- If apexd-bootstrap fails beacause of not updatable/flattened apexes here is experimental fix:
-------------------------------------------------- -------------------------------------------------- -----

2023.07.12: Recommended revisions
- droidmedia:0.20230605.1
- droid-hal-device:<= 960d6af?
- droid-hal-configs:<= 414d96c
- sensorfw-qt5-hybris:0.14.4 (for old hal interface)
- droidmedia:0.20211101.0
- droid-hal-device:<= 960d6af

Sometimes you may need to git clean -xdf sources before rebuilding with different revision


2023.02.05: Release specific issues

- End of bluez4 compatibility: lipstick-jolla-home-qt5 requires kf5bluezqt was updated and bluez4 patches were droped
- 'tracker-extract-3 Failed to load seccomp rules'  on some <= 3.4 kernels. Either add check for ECANCELED in or add support for Seccomp BPF to kernel: generic_seccomp-bpf_3.0.x patch is outdated and cause random kernel panic.
- remove /var/cache/ssu and run 'ssu ur' before OTA upgrade to be sure that adaptation-common repo is enabled during OTA and packages will be upgrade otherwise you will have issues like:
hybris.c:53: __resolve_sym: Assertion `ptr != NULL' failed: because too old packages:
* 4.2.0.x:
- mapplauncherd[1497]: Connection: getMountNamespace: stat failed for pid 1497: No such file or directory
Mount Namespace /proc/<pid>/ns/mnt was added in kernel 3.8 and probably backported to some 3.4 kernels. If your kernel do not have it then git am 12 patches (since "vfs: Add setns support for the mount namespace") for 3.4 kernel from: Not needed for mapplauncherd >= 4.2.2
- Everyone using old hal versions of sensorfw and geoclue hybris plugins (used on android base versions <= 7, but some might use even on newer android bases): before building new release images you need to update patterns to manually fix the package names (to geoclue-provider-hybris-hal and hybris-libsensorfw-qt5-hal) if you need hal versions
* 4.0.1.x:
- psmisc, bash and procps have been replaced by busybox. busybox pidof cause /etc/profile.d/ failure on login. busybox bash/ash is limited and also cause some strange issues. busybox killall is not compatible with bluetooth-rfkill-event <= 1.0.
To install non busybox version of bash and psmisc tools add to patterns:
Requires: gnu-bash
Requires: psmisc-tools
- Migrate from patterns to meta packages:
After transition make sure you have either patterns-sailfish-device-tools or zypper and busybox-static in patterns-sailfish-device-configuration-$
- Move your systemd services from /lib/systemd/system/ to /usr/lib/systemd/system/
- adaptation0 repo can't be refreshed on fresh platform sdk < 4.1.0.x:
    sudo ssu domain sailfish


2023.05.28: General info and various issues

* sailfishos-porters channel logs search: It's case sensitive!
* Latest sdk target url usually points to not latest sailfish release so always use versioned target url when preparing sdk:
* HADK pdf: 
It really means "WRITE ALL IN ONE LINE", do not split it and be careful when you copy/paste text splitted by arrows
- use 'repo init -u -b hybris-X'  instead 'repo init -u git:// -b hybris-X'
- gstdroidcamsrc-0.conf created by mk-cam-conf is no longer needed
- local manifest: $DEVICE.xml
First you need to find your device specific repository for example in (or in some custom github if your device is not supported by lineageos) like: and add appropriate entry to local manifest. Then cm/lineage.dependencies file will tell you what other device specific repositories you may need like android_device_sony_sm8350-common according to: and add it also. In common repository you may find another cm/lineage.dependencies file with kernel or some hardware repository: Usually you need to add all of device specific repositories to local manifest. Some android_hardware_* repos might be already in xmls. 
- fixup-mountpoints converts your by-name path defined in android's fstab (find it on device or in device repo) and .rc files (for example: /dev/block/platform/msm_sdcc.1/by-name/system) to block device (for example: /dev/mmcblk0p23) which is needed to create working systemd mount units: /usr/lib/systemd/system/*.mount. They will take care of mounting your partitions before droid-hal-init starts. So to create correct map (entry in fixup-mountpoints) for your device you need entries from your fstab (find it in $ANDROID_ROOT/device/$VENDOR/*/rootdir/ or directly on device) and ls -l */by-name/* (according to HADK) output from device for coressponding block device (e.g. /dev/sda24). Do not assume that your device use "block/bootdevice/by-name/" or "block/platform/msm_sdcc.1/by-name" path for all partitions, check fstab instead! Do not follow _a/_b syntax in fixup-mountpoints used for official devices like pdx213 unless you really have these suffixes in fstab
* mer-kernel-check: do not enable OPTIONAL filesystems unless you plan to use them.

* Make sure that after making hybris-hal, you have fstab* and ueventd*rc in out/target/product/$DEVICE/root/:
If they are not there and you are using old android base then 'make modules' (on hybris-18 use 'allmod') can help figuring out name of modules you need and build it like: 'make fstab.qcom ueventd.rc'. If there are no such modules or files are still not copied to out/ directory then do it manually. Read $ANDROID_ROOT/droid-hal-$DEVICE.log to confirm that mount units for /system and other partitions are created. If android's fstab do not include '/system' (or '/' in case of system-as-root), '/vendor' or '/boot' entry then you might need to add them manually.
Generally it is a system partition with init files (part of ramdisk) and with another /system directory and if mounted incorrectly strange looking symlinks like /system/etc -> /system/etc. This should be handled automatically by droid-hal scripts provided your android's fstab in out/ contains proper entry for system partition. In that case system partition is mounted to /system_root and /system_root/system is mounted to /system. Some devices which use system-as-root uses '/system' mountpoint for system partition entry in fstab instead '/' which needs to be changed to get correct systemd mount units generated: system_root.mount and system.mount.
* For some devices ueventd*rc file do not contains all needed rules. Common missing rule is /dev/ion but can be anything else. In that case, copy ueventd*rc somewhere from /vendor partition or /system_root as ueventd.$DEVICE.rc to appropriate place in out/ directory.
* Format /data partition before flashing sailfish to remove full disk encryption (FDE) or file based encryption (FBE) which will cause permission issues later (failed: Required key not available)
* If you kernel crash very early without any logs in console-ramoops after enabling CONFIG_VT, check whether you have breaking commit "tty: move tty_port workqueue to be a kthread" in drivers/tty/tty_buffer.c recent history and revert it. There are usually 2 or 3 more related commits with "tty_port_set_policy" changes in drivers/tty/ which needs to be reverted too . Mostly for some lineage-15/16 kernel sources but not always.
* If your device reboots after 60s without any sign of life in dmesg then check whether you have enabled CONFIG_USB_CONFIGFS_*RNDIS
* TWRP is known to fail when unpacking sailfish rootfs. Check /tmp/recovery.log for the exact reason: tar OOM or lack of bunzip2. There are many possible solution like downgrading TWRP, telnet to hybirs-boot without flashing whole image and unpacking image manually, copying static busybox from build environment and using it to unpack image or switching from bzip2 to gzip for sailfish image. 
gzip instead bunzip: Do not forget to update local repo metadata.
* When creating local manifest add device specific repositories from device/*/*/{cm,lineage}.dependencies files
* Updating and building droidmedia:
git fetch, pull and checkout to specific revision
make droidmedia (in HABUILD) --gg
Be careful if you use not recommended version for particular release. These steps will build only droidmedia but not droidmedia-devel which is used during gst-droid build done on jolla's servers
* To access scratchbox target as root: sb2 -t $VENDOR-$DEVICE-$PORT_ARCH -m sdk-install -R
* To access scratchbox target for building manually (cmake, make,..): sb2 -t $VENDOR-$DEVICE-$PORT_ARCH -m sdk-build
* HABUILD 'sudo: account validation failure, is your account locked?'
sudo pwck -q --root "$PLATFORM_SDK_ROOT"/sdks/ubuntu
* Latest ubuntu sdk do not have cpio installed which is required to create initramfs
* fails with: "usage: mb2 [global-opts] <command> [command-opts]": update platform sdk to >=
* journal: 'systemd: Failed to create /user.slice/user-100000.slice/user@100000.service/init.scope control group: Permission denied
systemd: Failed to allocate manager object: Permission denied
systemd: Failed to create cgroup /user.slice/user-100000.slice/user@100000.service/*: Permission denied'
If that doesn't help then add systemd.legacy_systemd_cgroup_controller=yes to kernel command line
* Sailfish browser use now gmp-droid instead gst-droid. If you used "dont-use-droid-convert" quirk or have some playback issues then you probably need:
Now gecko-camera-droid-plugin?
* fails: 'File /etc/ofono/ril_subscription.conf
   from install of
      droid-config-$DEVICE-1* (local-$DEVICE-hal)
   conflicts with file from package
      ofono-configs-mer-* (@System)'
      or similar for 'File /etc/ofono/binder.conf' and ofono-configs-binder conflicts
sb2 -t $VENDOR-$DEVICE-$PORT_ARCH -m sdk-install -R zypper --plus-repo $ANDROID_ROOT/droid-local-repo/$DEVICE in droid-config-$DEVICE
* droid-hal-version-$DEVICE.log: Problem: the to be installed droid-config-$DEVICE-1-202111031520.armv7hl requires '$DEVICE-bluez-configs', but this requirement cannot be provided:
    sb2 -t $VENDOR-$DEVICE-$PORT_ARCH -m sdk-install -R zypper --plus-repo $ANDROID_ROOT/droid-local-repo/$DEVICE in droid-config-$DEVICE
* No vibration:
Check what driver your device use. For memless driver evdev_trace command (from mce-tools package) should prints device with FF_RUMBLE or other supported effects.
For driver with sysfs based interface (timed_output) update your $ANDROID_ROOT/system/core:
Also make sure permissions are not overwritten by some other init*rc files in /system or /vendor partition
* logcat: 'E/qdoverlay( 2142): getRotDevFd failed to open rotator device' or 'HWRotator::Open: open /dev/mdss_rotator failed err = 13 errstr = Permission denied':
Change *_rotator group to graphics in: device/$VENDOR/*/ueventd.*.rc:/dev/*_rotator 0664 system graphics
* logcat: 'QC-time-services: Daemon:genoff_init_config: RTC initilization failed'. Disable time_daemon or vendor.time_daemon in disabled_services.rc: On some older hybris base time_daemon is defined in some init*rc file which is parsed before /usr/libexec/droid-hybris (see logs). In that case you must disable service in that init*rc file. Sometime there can be also vendor.time_daemon defined somewhere in /vendor.
* Touchscreen doesn't work: remove :/dev/input/eventX from droid-hal-device.conf to enable auto detection of touchscreen node. If that doesn't help use evdev_trace (from mce-tools package) or 'cat /dev/input/eventX' to figure out correct node. (`for f in /sys/class/input/event*/device/name ; do printf "%s: %s\n" $f $(cat $f); done` can give an idea which device is which)
* Black background in homescreen or black images in gallery:
* After upgrading target rpm fail: 'error: db4 error(-30971) from dbenv->open: DB_VERSION_MISMATCH: Database environment version mismatch
error: cannot open Packages index using db4 -  (-30971)
error: cannot open Packages database in /var/lib/rpm':    
sb2 -t $VENDOR-$DEVICE-$PORT_ARCH -m sdk-install -R rm -rf /var/lib/rpm/__db.00*
* If your kernel do no have NETFILTER_XT_MATCH_QTAGUID then add "!" in mer-kernel-check script to make it optional:
* Do not upload tmp/ or documentation.list in droid-config to github. These are temporary files recreated every time droid-config is build and they make your commits more obscure
* ' max77843-fuelgauge: driver failed to report `status' property: -22' this kind of spam in dmesg is usually caused by broken drivers which reports property which they do not support. Suppresing error printing in power_supply_sysfs.c can lead to several issues so real bug must be fixed in particular driver. For example following driver pretends to support status property: 
but clearly status is not handled neither in max77843_fg_get_property nor in max77843_fg_set_property. Removing POWER_SUPPLY_PROP_STATUS should fix issue for this particular driver but other drivers might require different fixes. Fixing one bug might reveal another:
    'max77843-fuelgauge: driver failed to report `charge_full' property': It support setter but not getter so add 'return -ENODATA in appropriate get_property function'
    'bq51221-charger: driver failed to report `current_now' property'
    Be careful: these are just examples and you are dealing with Li-Ion related drivers.
* USB cable detection is handled by usb-moded. It expects online/present and type events from power_supply devices for proper functioning. For debugging issues use 'udevadm monitor -p'  and -D argument in /var/lib/environment/usb-moded/usb-moded-args.conf. 
Some devices doesn't send online/present udev events on usb connection/disconnection but still set this parameters: /sys/class/power_supply/*/{uevent,present,online,type}. In that case adding power_supply_changed(<usb power_supply pointer>) to driver might be enough to get everything working:
Alternative way is tracking ext_con or android_usb devices:
* Plugins: which one you should use is really device and adaptation/stock android version specific
- ofono plugin:
ofono-ril-plugin <= android 7
ofono-ril-binder-plugin <= android 10
ofono-binder-plugin >= android 10: binder-list -d /dev/hwbinder | grep IRadio
Additionally you need configuration files in sparse/etc/ofono, different for each plugin. See sony droid-config repos to figure out correct configs for plugin.
- pulseaudio plugin:
pulseaudio-modules-droid-jb2q <= android 10
pulseaudio-modules-droid >= android 11
audio calls:
If you device have only 32bit audio library e.g. /vendor/lib/hw/ but without 64bit version e.g. /vendor/lib64/hw/ then hidl_compat wrapper may help you:
Make sure is not disabled in disabled_services.rc. Currentl it may not work with non jb2q modules
- sensorfw plugin:
hybris-libsensorfw-qt5: >=android 8: binder-list -d /dev/hwbinder | grep ISensors
hybris-libsensorfw-qt5-hal <= android 7: test_sensors
- bluetooth:
On recent android bases you need to install bluedroid and enable HCIVHCI and some other configs:

*  Random kernel <= 3.10 crash at:
'fs/sysfs/dir.c' called by sysfs_remove_dir: BUG_ON(sd->s_flags & SYSFS_FLAG_REMOVED);
* Some 3.4 and 3.10 kernels requires following patches to  get systemd and sailjail/firejail working
* ohmd failing twice or more with error: 'ohmd.service: Failed at step NAMESPACE spawning /usr/sbin/ohmd: No such file or director' is caused by mising namespace options from mer-kernel-check and CONFIG_USER_NS
* Updated for python3: Make sure you use right "apiurl =" in ~/.oscrc

* 4.2.0.x: gst-droid: upgrade-4.2.0 (if you have recording issue then try to revert last commit and report it)


2022.07.31: Generating logs:

* Always provide full logs with information of what you did so far, full command you are running with arguments and shell prompt in paste so it's clear what you execute and where: host, device, sdk, target sdk or ubusdk. If you are debugging issues on device: reboot (so it is not filled with too much noise) and make sure logs contains early boot messages. It's better to highlight relevant part than providing partial log. Do not paste long logs directly to channel, use paste services instead: - full of ads, - raw view links expire quickly or similar. ubuntu one without raw view and lack of horizontal scrollbar is worst choice. Better alternatives are welcome
Always upload your latest changes in droid-config/hal/kernel so it's easy to inspect them. Crazy ideas: read logs and search for errors from the top before you upload them
* In TWRP sailfish root path / is under /data/.stowaways/sailfishos/
* Connecting device to pc shortly after powering it on and running dmesg in your host system can reveal whether you are booting hybris initframfs, android init or there is no sign of life on usb from your device
* If ifconfig shows that inet address is not assigned and you can't telnet to device: Sometimes init*usb*.rc file can mess up your usb connection after droid-hal-init is started. To avoid it you must prevent that particular *.rc file from being included and parsed. This is probably done in some more general init*.rc file.  Sometimes masking usb-moded can help also untill you get gui working.
* If your device bootloops but you can force boot straight to TWRP then cat /proc/last_kmsg or /sys/fs/pstore/console-ramoops might contains logs from faulty boot but only if kernel crashed. Make sure this log are really from sailfish boot attempt instead TWRP or android.
* If you are on 23 telnet port then device stuck in initramfs, cat init.log and diagnosis.log will tell you why switching to real rootfs failed
* If your device bootloop fast enough or reboot to some different mode so you can't access telnet check in TWRP whether /data/.stowaways/sailfishos/init.log exists if no then your device did not pass or even reach initramfs stage. In that case make sure your hybris-boot.img contains valid initramfs: 'abootimg -i hybris-boot.img'. If init.log is generated you can stop booting device in /init-debug script by creating /data/.stowaways/sailfishos/init_enter_debug2 which might allows you to telnet.
* dmesg: usually useful to confirm whether selinux is disabled at boot time: 'SELinux:  Disabled at boot' for hybris <=16 or initialized: 'SELinux:  Initializing' for hybris >= 17. Also if something fails very early before systemd is started or some droid-hal-init logs are partialy in dmesg and partially in journal. Kernel buffer can be small so you need to be fast to grab early boot messages. Arguments:
    -w (live log, not supported on very old kernels)
* journalctl: enable persistent logging if you have trouble with getting access to device, you kernel is noisy or you are too slow so early boot logs are lost: Journal binary log can be also retrieved from /var/log/journal via TWRP. 
    --no-pager (shows everything without paging)
    --no-tail -f (shows everything and continuously prints new messages)
    -b0 (only from current boot, useful if you have persisten logging enabled) -b-1 (from previous boot)
* /usr/libexec/droid-hybris/system/bin/logcat: for android part debugging. Can produce different logs as regular user than root user.
* If droid-hal-init do not print: 'Parsing file *.rc' or you have: 'output lines suppressed due to ratelimiting' in dmesg then add 'printk.devkmsg=on' to kernel cmdline to enable unlimited logging from user space applications
* Always add audit=0 to kernel bootparams to suppress audit spam and clean up logs unless you plan to use audit/selinux.
* binder-list from libgbinder-tools package:
 binder-list -d /dev/hwbinder
 binder-list -d /dev/vndbinder

-------------------------------------------------- --------------------------------------------------------

I have telnet but not gui:

* Check in .config, zcat /proc/config.gz or dmesg whether selinux is set up correctly. When you build kernel, defconfig is used as source from which out/target/product/$DEVICE/obj/KERNEL_OBJ/.config is generated. If you forgot about dependencies in defconfig then it will not match generated .config. Sometimes defconfig is stripped from some configs so it's good to regenerate it: build kernel without any hybris changes in defconfig, copy generated .config back to defconfig and commit that change. Disabling CONFIG_AUDIT which is part of CONFIG_SECURITY_SELINUX dependencies is common mistake.

* Search for "droid mount" in journal and make sure /system and other partitions are mounted

* Search for firmware loading failure. If particular driver needs firmware before partitions are mounted and is not triggered then building driver as module and creating systemd service (like for wlan) which will modprobe it might help.

* droid-hal-init (modified android init) must not fail and usually can't be started twice unless it fails on early stage or you clean up some files it created before starting it again. If you want to strace it then mask service and reboot: 'systemctl mask droid-hal-init'. logcat can be used only after droid-hal-init started.

* compositor used by sailfish is called lipstick. For debugging gui issues use 'systemctl mask user@100000' and reboot device. This will prevent lipstick starting/failing and ease test_hwcomposer/minimer use.

To test android part, mask user@100000, reboot an start surfaceflinger:    
# On android >= 11 you may also need:
ANDROID_ROOT="/system" /system/bin/bootanimation

-------------------------------------------------- --------------------------------------------------------

2022.02.23: OBS ( tips and tricks

* For account ping Keto at #sailfishos IRC channel
* You can add new relases using "Meta" tab instead via "Add repositories"
* '<path project="sailfishos:*" repository="latest_armv7hl"/>' should be latest in projects list in "Meta"
* devel repo is for you and your testers development. It should have only one release sailfish_latest_armv7hl. Testing repository might have releases for every no EA (Early Access) sailfish version like sailfishos_4.2.0.21.
* Copy and adapt "Project Config" from fp2-sibon to your device:
* OBS targets are not added at the same time as new sailfish os version is announced. Search for "sailfishos:4." in to be sure that you can build for particular release. "sailfishos:latest" for devel repository is updated only after some time when full release is out. Confirm here:
* Always disable old releases before you create new in testing repo. You can do this in "Repositories" tab by setting "Build Flag" to disable or manually in "Meta" tab (see fp2-sibon example). If you do not do this then you will override your old release. Alternatively you can create subproject for each release which will ease maintenance
* Add droid-config/hal/version and other adaptation packages but do not add packages like qt5-feedback-haptics-native-vibrator or community-adaptation-* which are already in repositories enabled on your device:,$RELEASE/jolla-hw/adaptation-common/$PORT_ARCH/ (since 4.3.0) or in$RELEASE/jolla/$PORT_ARCH/ unless you need to build some different version.
* Only droid-hal and droidmedia needs to by uploaded because they are build from android sources. For all other packages, create _service file and fill it with: You can set revision to HEAD but sometimes latest version for particular package which is under development can not be used then you can set revision to tag or git commit hash. OBS will fetch sources from git and build automatically. If you want to rebuild package then use "Trigger services" button.
* osc can be also used for uploading new packages:
* Package name determine which spec file will be used to build it. Here sensorfw-qt5-hybris.spec will be used but if you use binder backend then you need sensorfw-qt5-binder.spec thus:
* Package blocked for very long time with following message: "downloading 1 dod packages". Ping OBS maintainer
* Your $ANDROID_ROOT/*.ks file which is used by "mic" during image creation by default use local repository on your disk for adaptation packages and common/jolla repos for other packages. Also build_packages -i/--mic overrides your *.ks file. One way to use your new OBS repo is: download droid-config-$DEVICE-ssu-kickstarts*.rpm: and unpack *.ks with your new adaptation-community-$DEVICE repo, update droid-local-repo metadata then run mic manually: 
sudo mic create fs --arch=$PORT_ARCH \
 --record-pkgs=name,url \
 --pack-to=sfe-$DEVICE-$RELEASE$EXTRA_NAME.tar.bz2 \
 $ANDROID_ROOT/Jolla-@RELEASE@-$DEVICE-@ARCH@.ks #--verbose --debug
* .ks file change sometimes together with new target and droid-config so download new one for every release
* mic installs only one package patterns-sailfish-device-configuration-$DEVICE defined in *.ks file when sailfish image is created. That means every other package installed in image is pulled by droid-config/patterns/patterns-sailfish-device-configuration-$ For optional packages which can be removed later without uninstalling other adaptation packages use weak dependencies like: "Recommends: jolla-developer-mode" instead "Requires: jolla-developer-mode".
* Ports do not recieve updates in Settings page. For upgrade disable 3th party repos and use "ssu release $RELEASE; version --dup". If it fails for some unknown reason try zypper ref; zypper dup --details to figure out what is broken.
* When using OBS web interface to upload rpm package with '+' in file name OBS will rename plus sign to space and copy will fail. To solve this explicitly set correct "Filename" at "Add File" page when you upload such rpms.
* _pattern is no longer used for new releases, forget about it