[gpgme] generate a wheel of the python bindings

Ben McGinnes ben at adversary.org
Sun Mar 4 00:39:27 CET 2018

On Sun, Mar 04, 2018 at 02:50:52AM +0900, Matt wrote:
> Hi,
> I've been trying to package gpgme python bindings for nixos
> (www.nixos.org) since it's a dependency of the mail reader I use
> (alot) but I haven't succeeded yet.


With GPGME as a dependency ... Claws or Mutt/Neomutt?

> I manage to compile the python 2.7 bindings and to build a "wheel"
> (as required by nixos, a wheel is a zip file replacing the older
> "egg' binaries) but for some reason my wheel is empty ;/ (it has
> egg-info but not the gpg package).

This is pretty much always going to run into trouble with these
bindings due to the nature of what they are.  Unlike other wrappers
(e.g. python-gnupg) they're a bit more than simply wrapping the
command line executables with subprocess invocations.

The GPGME Python bindings are built against the version of GPGME it's
released with; functions are linked to their C counterparts with SWIG
via the gpgme.h header file for that version.  In order to have
functional bindings in the python module, you must also have a
functional copy of GPGME built at the same time, for the same platform
(architecture and OS).

Which means providing a separate, precompiled python binary like a
wheel will almost always introduce unexpected errors and failures.

> The -meager- result of my efforts is visible here
> https://github.com/NixOS/nixpkgs/pull/30429#issuecomment-370126211 and

Interesting.  I can definitely answer one part of it, though:

The reason you ended up with an "empty" module was because you were
just trying to build the module as a stand alone Python module.
Without the rest of the GPGME C API to which it's bound, it is
effectively useless.  With the two together, however, it provides a
pythonic interface to the entire GnuPG suite of software and

When GPGME is compiled it produces the gpgme.h file most relevant to
that host (from src/gpgme.h.in) and once that's done the building and
installation of the various bindings in lang/ are performed against
that gpgme.h file.

> Also I believe that if one wants to be able to run "setup.py install",
> he will need a patch similar to:
> https://github.com/teto/gpgme/compare/7da01c7352d41eb33e445968b248544d301588f9...nix

No chance.  It'd introduce too many points of failure and an
expectation that these bindings will behave the same way as PyNaCl or

Also, your repo there looks like an old release, somewhere in the beta
period before 1.10.0 was released.  There have definitely been
significant updates to both GPGME and the python bindings since then.

> I've tried asking on #python but couldn't find a solution.

Yeah, I saw that, but it seems I missed you by a couple of hours or

> I really some skilled user can help solve that as I miss my
> mailreader :)

I'm not really familiar with NixOS, but from what I've read it's
another Linux distribution with its own take on package management.
If that system can handle both binary packages and compiling packages
from source, like many other package managers, then it should be

If it only has the facility to provide binary packages then you will
need to build those binaries for every single architecture and OS type
Nix supports in order to do so.  Either that or go bloat happy and try
to support as many as possible.  This is very much *not* recommended,
however, because it is quite possible that incorporating something for
one set of architecture and system version could very easily cause
problems with others.

There are certainly other package managers which are already quite
capable of correctly building GPGME and the Python bindings.  I build
it regularly on OS X with a slightly mixed approach.  I use MacPorts
to grab all the library dependencies and build from source (actually
most of my ports are built from source, but not quite all); the gnupg2
(i.e. GPG 2.2.x) has a slightly modified configuration (compared to
the standard portfile) and then built from source.

Then I build GPGME manually while referencing the dependencies in
/opt/local, but installing to /usr/local (so it finds my preferred
installation of Python 3 instead of the MacPorts one).  After running
autogen.sh I use this configure command:

    ./configure --prefix=/usr/local --exec-prefix=/usr/local \
    --with-libgpg-error-prefix=/opt/local \
    --with-libassuan-prefix=/opt/local --enable-maintainer-mode

Followed by the usual make, make check, sudo make install (though you
can use gmake instead if there's a difference on your system).

I also adjust the portfile for Neomutt to use my manually built GPGME
in /usr/local instead of the one kicking around in /opt/local (which
is just there to tick the dependency boxes for other packages).

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <https://lists.gnupg.org/pipermail/gnupg-users/attachments/20180304/e75c2980/attachment.sig>

More information about the Gnupg-users mailing list