Gentoo - add own patches to ebuild

August 2017

User patches provides users with an integrated method of applying site-specific patches. This is often preferable to forking the ebuild in a local overlay, since the latter will require ongoing maintenance to keep up with the Gentoo tree.

Thanks to EAPI=6, You can put your patches into /etc/portage/patches/<CATEGORY>/<PF|P|PN>[:SLOT]/ and those will by applied automatically when package is being merged.

Do You use Gentoo/Portage on application servers? Think of applying your patches (that upstream developer do not want to include for some reason) automatically when new version is ready to be deployed.


Keepassx is cross platform password manager I use as a local credentials (and other data) storage. It’s light interface is missing one keyboard shortcut important to me - copy notes. Let’s add this simple feature to GUI.

Keepassx - before

Keepassx - before.

Obtain source code and prepare .patch file

Let’s create development environment in /tmp/keepassx-patch directory. We can use gentoo’s ebuild tool to download tarball with source code for us. In the end - clone unpacked source code directory for easy .patch file creation with diff.

$ mkdir -p /tmp/keepassx-patch
$ cd /tmp/keepassx-patch/
$ ebuild /usr/portage/app-admin/keepassx/keepassx-2.0.3.ebuild fetch
>>> Downloading 'rsync://gentoo.prz.rzeszow.pl/gentoo/distfiles/keepassx-2.0.3.tar.gz'
Services available:
-------------------

receiving incremental file list
keepassx-2.0.3.tar.gz
      1,540,235 100%  295.97kB/s    0:00:05 (xfr#1, to-chk=0/1)

sent 47 bytes  received 1,541,449 bytes  181,352.47 bytes/sec
total size is 1,540,235  speedup is 1.00
 * keepassx-2.0.3.tar.gz SHA256 SHA512 WHIRLPOOL size ;-) ... [ ok ]
$ tar zxf /usr/portage/distfiles/keepassx-2.0.3.tar.gz -C .
$ cp -a keepassx-2.0.3/ keepassx-2.0.3.new

For medium and big projects I advise to use SCM’s diff command (example: git-diff) to compare the file in your sandbox with the proposed change in the incoming change set.

GUI shortcuts are defined in src/gui/MainWindow.cpp file. I will define mine as well.

$ vim keepassx-2.0.3.new/src/gui/MainWindow.cpp
(add to MainWindow::MainWindow())
    m_ui->actionEntryCopyNotes->setShortcut(Qt::CTRL + Qt::ALT + Qt::Key_N);

Source is ready. Let’s create .patch file. The simplest invocation is diff -u oldfile newfile, which will create a list of differences in unified format between oldfile and newfile. To operate over directories instead, use diff -urN olddir newdir.

$ diff -u keepassx-2.0.3/src/gui/MainWindow.cpp keepassx-2.0.3.new/src/gui/MainWindow.cpp 
--- keepassx-2.0.3/src/gui/MainWindow.cpp	2016-09-04 17:57:47.000000000 +0200
+++ keepassx-2.0.3.new/src/gui/MainWindow.cpp	2016-11-13 12:45:50.730497877 +0100
@@ -92,6 +92,7 @@
     m_ui->actionEntryDelete->setShortcut(Qt::CTRL + Qt::Key_D);
     m_ui->actionEntryClone->setShortcut(Qt::CTRL + Qt::Key_K);
     m_ui->actionEntryCopyUsername->setShortcut(Qt::CTRL + Qt::Key_B);
+    m_ui->actionEntryCopyNotes->setShortcut(Qt::CTRL + Qt::ALT + Qt::Key_N);
     m_ui->actionEntryCopyPassword->setShortcut(Qt::CTRL + Qt::Key_C);
     setShortcut(m_ui->actionEntryAutoType, QKeySequence::Paste, Qt::CTRL + Qt::Key_V);
     m_ui->actionEntryOpenUrl->setShortcut(Qt::CTRL + Qt::Key_U);

$ diff -u keepassx-2.0.3/src/gui/MainWindow.cpp keepassx-2.0.3.new/src/gui/MainWindow.cpp > /tmp/keepassx-patch/CopyNotesShortcut.patch 

Patch ready to serve! Choose the location for patch file, depending on the package name and the version(s) it is intended for. Use the following locations and optionally append :${SLOT} to any of them:

  • /etc/portage/patches/${CATEGORY}/${P}
  • /etc/portage/patches/${CATEGORY}/${PN}
  • /etc/portage/patches/${CATEGORY}/${P}-${PR}

Examples:

  • /etc/portage/patches/app-admin/keepassx
  • /etc/portage/patches/app-admin/keepassx:2
  • /etc/portage/patches/app-admin/keepassx-2.0.3
  • /etc/portage/patches/app-admin/keepassx-2.0.3-r1

Create the directory:

$ mkdir -p /etc/portage/patches/app-admin/keepassx

Now that the directory is ready, drop in the patches. Only files with .patch suffix are considered and they are applied in the order determined by their name.

$ mv /tmp/keepassx-patch/CopyNotesShortcut.patch /etc/portage/patches/app-admin/keepassx

The patch is ready to be procesed by portage. Let’s confirm it.

$ ebuild /usr/portage/app-admin/keepassx/keepassx-2.0.3.ebuild prepare
 * keepassx-2.0.3.tar.gz SHA256 SHA512 WHIRLPOOL size ;-) ...                         [ ok ]
 * checking ebuild checksums ;-) ...                                                  [ ok ]
 * checking auxfile checksums ;-) ...                                                 [ ok ]
 * checking miscfile checksums ;-) ...                                                [ ok ]
>>> Unpacking source...
>>> Source unpacked in /tmp/portage/app-admin/keepassx-2.0.3/work
>>> Preparing source in /tmp/portage/app-admin/keepassx-2.0.3/work/keepassx-2.0.3 ...
 * Applying patches from /etc/portage/patches/app-admin/keepassx ...
 *   CopyNotesShortcut.patch ...                                                      [ ok ]
 * User patches applied.
>>> Source prepared.

Compile and install keepassx again.

$ emerge keepassx

Run keepassx and new shortcut (Cltr-Alt-N, copy Notes section) should be available

Keepassx - after

Keepassx - after. New shortcut available.