Phosh Development Guide#
Introduction#
Welcome aboard! This is a highly opinionated guide on doing code contribution to Phosh ecosystem.
The aim of this guide is to help you with various tips and gotchas that you might encounter in the
journey. You can consider this guide as a preface before jumping into the project specific
HACKING.md.
Why we call this opinionated? Because most of the recommendation is from our personal experience and might be distribution or editor or personal taste specific. With that said, you are always encouraged to suggest changes and improvements by opening an issue.
If you are looking for a quick and to-the-point guide, then please check the respective project’s
HACKING.md. For example, see Phosh shell’s
HACKING.md.
Getting Started#
Before your first contribution, we expect that you are comfortable with the tech-stack we use.
Phosh, Phoc and other software of this ecosystem are written in C and Rust. So a familiarity with the language used by the respective project is essential. How much familiar? is a question for which we don’t have an answer. It depends on the exact issue you are working with. But if you are good with the basics, then we are here to help you with anything you are stuck, with respect to the issue.
Next you should have a good knowledge of GTK and other GLib based libraries. If you are new, then browsing the Additional documentation of GObject and GTK documentation can help.
If you want to contribute to the shell itself, then see Getting started with Phosh development for an overview of how the shell works and the libraries used.
If the above are satisfied, you are 99% ready to start your first contribution. The remaining 1% is knowledge of Git, GitLab, command-line, Linux fundamentals etc.
Running Phosh#
During development, you would want to test your changes. Thanks to the way Phosh works, you can run the shell directly on your computer. We call it a nested session because it runs inside your existing desktop session.
Please read Developing for Mobile Linux with Phosh and Phosh blog-posts on development for the instructions on how to run the Phosh shell in a nested session.
The Flow#
Issue#
Most of the contribution is done by going through the list of open issues and selecting the (unassigned) one you feel comfortable.
Sometimes you might want a new feature and after having had a discussion on Matrix, you can open up a new issue explaining the feature request.
The pattern is same for a bug report too. After confirming from Matrix that it is indeed a bug in upstream Phosh, you can open up a new issue explaining the details.
Finally, no matter the path you take, now you have an issue to work with! 🎉
Merge Request#
We follow a merge request style of working. It means, first you have to fork the repository and
create a new branch. Next you work on your issue, making code changes as required. This might be a
good time to check the project’s HACKING.md as it explains the file structure, API conventions
etc.
Once you have crossed the minimal viable product stage with the code, you might want to push the changes to your repository. Once done, you can open a merge request giving details about the issue, how you fixed it etc.
At this point a developer or an other contributor will go through the code and let you know what can be improved. You make the changes and push again and it gets reviewed again. This goes on till the code reaches a satisfying state. That’s when the glorious moment of merging happens. Once your merge request is merged, the corresponding issue is also closed. Congrats and thanks for your contribution!
Debugging#
Debugging is of course part of the development process. Using a debugger along with your IDE/editor’s debugging mode can help you narrow down and fix the issue.
GNU Debugger (GDB) is a powerful debugger that can aid you in the process. But to extract most out of it, you need to build the software in debug mode.
Most projects by default build in debug-optimized mode, so simply building them is enough to be
used with a debugger. However for other libraries like GTK, having debug
symbols is recommended. They give you additional
details like line numbers, function names etc.
You should refer to your distribution documentation to know how to install the debug symbols. But to simplify the process, there is also Debuginfod which automatically fetches the symbols for you.
So in short, installing Debuginfod and pointing it to a server (please check your distribution’s documentation for the details) gives you a base to get started.
Segmentation Faults#
Segmentation faults are the notorious yet easy
to find out bugs. Instead of filling your code with printf statements, you can use
Coredumpctl to get the
backtrace. Combined with Debuginfod, you can pinpoint the faulty line easily.
For example, your typical workflow will be like the following.
$ G_MESSAGES_DEBUG="phosh-wifimanager" GSETTINGS_BACKEND=memory ../phoc/_build/run -E _build/run
…
< do something to crash Phosh >
…
Segmentation fault (Core dumped)
$ # Launch GDB on latest core dump
$ coredumpctl debug
…
< stack information >
…
This GDB supports auto-downloading debuginfo from the following URLs:
<https://debuginfod.debian.net>
Enable debuginfod for this session? (y or [n]) y
Debuginfod has been enabled.
To make this setting permanent, add 'set debuginfod enabled on' to .gdbinit.
…
< details about the crash >
…
(gdb) bt
…
< backtrace of the crash >
…Others#
Learning GDB is a rewarding experience. You can use it to inspect variables, set breakpoints and do a lot of things that makes debugging a pleasant experience.
Logs and Backtraces - How to provide meaningful problem reports offers more about the art of debugging along with the commands. Give it a read 😉.
Coding Style#
As Guido van Rossum has said,
Code is read much more often than it is written.
Definitely, the contribution you do has to be maintained. Maintaining can be anything from fixing bugs in the future versions to upgrading libraries etc. All this means that your code is read a lot of times.
Having a consistent and good coding style ensures your code is readable by others. Automated code formatting can also be used to automatically align your code to match the coding style.
For C, we use Uncrustify. Projects ship an Uncrustify
configuration at .gitlab-ci/uncrustify.cfg.
To run Uncrustify on a file, you would do the following.
uncrustify your-file.c -c .gitlab-ci/uncrustify.cfg
# Check the changes
diff your-file.c your-file.c.uncrustify
# Incorporate the changes (e.g. using `uncrustify --replace` and `git add -p`Check man uncrustify for more details. You should also check your IDE or editor for better
integration.
Similarly for Rust, we use rustfmt with configuration
rustfmt.toml located at the root directory.
Even after automated formatting, it is suggested to give the changes a glance to avoid surprises!
Diff Noise#
Diff noise occurs when the changes you perform does more than what the issue needs. For example, say you added a few lines to an existing function and used Uncrustify to format. This could have affected the other portions of the code causing your diff to be vague or noisy. When someone reviews your merge request, it will be difficult for them to understand the why behind the changes.
One solution is to work on only your portion of code. It means, formatting only your code fragments and leaving the rest as it is for now.
Next, commit the changes. Now if you think that the remaining portion of the file is messy, then you can format them and make a new commit. So your commit history will be like the following.
qaz235: changed-file: Format to match the coding style
edc816: changed-file: Add foo to barIf the formatting changes are more significant, then making it a separate merge request would be a good idea.
How would you know which is the best option? The nice thing is - you are not alone. The person who is reviewing your code will suggest you the optimal solution. 😊
Wrapping Up#
We have come to the end of this guide and the beginning of your contribution journey! Have any doubts, suggestions, improvements? Please let us know via Matrix or by opening a new issue!