Developing with postmarketOS

A core goal of postmarketOS is to make it easy for developers to work on improving the OS itself (by fixing bugs, adding support for new devices, etc) and to use postmarketOS as a development platform for mobile/embedded devices.
This page provides an overview of how to do different kinds of development, with links to more detailed guides and documentation where available.
== Ethos ==
postmarketOS has from it's inception aimed to be friendly towards developers and tinkerers. With a goal to support as many devices as possible, it can only be met by keeping the barrier of entry as low as possible. This has certainly helped to bring in many folks who would not be interested in learning big complicated tooling to build and submit new packages to support their device.
This mindset is embodied in pmbootstrap, the tool used for all postmarketOS development. If you have ever contributed to postmarketOS you are most likely familiar with pmbootstrap. It is used by our build system to produce the binary packages and device images in our repository, and it is used by all of our contributors to build them locally. It also has a whole lot of other features. By using the same tooling in our automation as we do on our local machine, we ensure that it is:
1. Easy to set up (automatically in CI, and with a nice CLI locally)
2. Consistent
3. Straightforward to use
Basically, there is no advantage to having access to our build system. No contributor has an inherently easier time working on pmOS than any other (barring hardware limitations). Likewise, all improvements to our tooling benefit everyone in the community as well as our automation.
postmarketOS has extremely loose requirements to add a new device: it must boot (with evidence that the postmarketOS initramfs starts up), and it must have a wiki page. This way, if you never get any further, your work can be documented (and packaged!), so someone else can continue the effort in the future more easily.
== Kernel development ==
Packaging a Linux kernel is a common first contribution in the postmarketOS community, since it is required for a new device to boot for the first time. As a result, the process is pretty streamlined for many different kernel versions. See [] for more information on creating a new kernel package.
=== Mainline kernel ===
A growing number of people use postmarketOS as a reference for upstream kernel development (particularly for Qualcomm platforms). For well-established device ports this is a good choice as boot deploy will handle converting the kernel into whatever format is needed for your devices bootloader, and flashing the Android boot partition on Android phones.
As a quick overview for kernel developers:
# Install pmbootstrap and configure your device
# Establish which kernel package is used by your device, it will be listed as a dependency in the device package APKBUILD (or view dependencies on https://pkgs.postmarketos.org/packages ). For the OnePlus 6 this is linux-postmarketos-qcom-sdm845
# Run pmbootstrap pull to ensure your pmaports checkout is up to date.
# (Cross) compile your kernel as normal
# Run pmbootstrap build --envkernel linux-postmarketos-qcom-sdm845 (replace with your kernel package)
# Attach your device via USB (or determine the IP address and specify --host below)
# Run pmbootstrap sideload linux-postmarketos-qcom-sdm845
Then just reboot into your new kernel.
=== Recovery on Android devices ===
For Android devices booting with an Android boot image, one can be generated by running pmbootstrap export. If your kernel package doesn't boot for some reason, you can remove your local binary packages and generate a safe boot image with:
pmbootstrap -y zap -p
pmbootstrap export
Then fastboot boot /tmp/postmarketOS-export/boot.img.
== App development ==
Working on apps, shells, or middleware can be done in a few different ways. You may wish to edit and compile locally on-device (this is usually easiest), installing to /usr/local/ where changes can easily be reverted. You may wish to edit on your host PC but compile on the target device, or you may wish to build full packages on your host PC and sideload them to the device.
You may also wish to use QEMU for testing.
=== Edit and build on device ===
This is the most obvious / easy way to get things done. The biggest hurdles are likely to be accessing your dbus user session and wayland socket via SSH. A nice helper for this is described in Terminal_cheat_sheet#Getting_session_environment.
=== Edit locally but build on device ===
For this, a one-liner can be used to sync changes to the device on save. See Terminal_cheat_sheet#Pushing_source_changes_to_a_target
=== Build packages from local source checkout ===
This can be done with pmbootstrap build --src="$PWD" PACKAGE. This is not compatible with all packages, but works with most simple ones. It simply uses your local checkout as the source rather than the default source defined in the APKBUILD.
The resulting binary package can be installed with pmbootstrap sideload PACKAGE.
=== Testing in QEMU ===