Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does not build against older gpgme versions #6

Closed
mtrmac opened this issue Apr 26, 2016 · 12 comments
Closed

Does not build against older gpgme versions #6

mtrmac opened this issue Apr 26, 2016 · 12 comments

Comments

@mtrmac
Copy link
Contributor

mtrmac commented Apr 26, 2016

The bindings provide symbols added in recent versions of gpgme, which makes it impossible to build them e.g. on Fedora 22 (gpgme 1.4.3) or RHEL 7 (gpgme 1.3.2).

I’m afraid I don’t know how to fix this cleanly; we probably can’t do a gpgme version check at compilation time using the native Go facilities, so this would involve adding a Makefile and conditional compilation tags… much uglier than the current clean package where a simple go build suffices.

Holding the bindings back to and old gpgme version is not good enough either.

For now, I am maintaining https://github.com/mtrmac/gpgme/tree/gpgme143 and https://github.com/mtrmac/gpgme/tree/gpgme132 branches as the simplest way to build on these older systems, and this works well enough; still, I thought that it would be useful to file this here, either because somebody smarter can find a clean fix now, or so that it can be fixed sometime later after it becomes feasible.

@proglottis
Copy link
Owner

Yeah. I thought we'd hit this issue eventually. I think build tags can handle this https://golang.org/pkg/go/build/

I'd imagine splitting out things like pinentry into their own file and adding the build tag like this:

// +build !gpgme1.3.2

And use go build -tags 'gpgme1.3.2'. Would this suit you?

Another option might be to package the gpgme.h file in the repo. I think this would work fine for constants, but we'd have to conditionally stub out the C functions that don't exist. Also I'm not sure licensing allows this.

@mtrmac
Copy link
Contributor Author

mtrmac commented Apr 27, 2016

And use go build -tags 'gpgme1.3.2'. Would this suit you?

If I understand the go build system correctly, this would leak into users of this module, and worse, transitively their users; go build $user-of-user-of-user-of-gpgme would still need to include -tags gpgme1.3.2, even when $user-of-user-of-user-of-gpgme has no idea gpgme is even used somewhere down in the stack. A simple go get of a package would not work without telling the user about -tags gpgme1.3.2.

In my particular case, we use make anyway, and I do know that I am using gpgme, so yes, using build tags would work for me.

I don’t particularly like this, but then none of the other options I can see are appealing either.

(Using the mtrmac/gpgme:master branch has the advantage of keeping go get working without asking the user, or anyone else, to do anything extra, OTOH it leads to a long-term fork which might become unmaintained.)

@proglottis
Copy link
Owner

Here's another idea that at least puts the gpgme version requirement with the application writer. You create separate packages for functions and constants that only newer gpgme versions support. Then they only get compiled when explicitly included by the application dev.

Here's a test I wrote to check. Still go get-able even though the thing package wont compile.
https://github.com/proglottis/cgopackage

It would be trivial to split out pinentry, but pretty hard to split out new constants. It would also not be backwards compatible

@mtrmac
Copy link
Contributor Author

mtrmac commented Apr 30, 2016

It would also not be backwards compatible

Yeah. The mtrmac/gpgme repository kind of implements this (by having mtrmac/gpgme be the limited package and proglottis/gpgme the full-featured one).

So, basically, I have a good enough solution for my needs, and hopefully over time the version drift will diminish or cgo will grow more conditional compilation capabilities. Until/unless that happens, this issue can serve just as a convenient URL to refer to the problem space.

@ikrabbe
Copy link

ikrabbe commented Aug 30, 2016

I may be able to help here, but I'm still not perfect, using C here, too. Maybe we should also include a vendor library for gpgme, so we don't need to link against the systems one.
On my system (gentoo) the error was, that gpgme.h could not be found, as it is installed in /usr/include/gpgme/gpgme.h, so the include statement would be #include <gpgme/gpgme.h>.
After fixing these include statements, your package compiled.

@mtrmac
Copy link
Contributor Author

mtrmac commented Aug 30, 2016

Maybe we should also include a vendor library for gpgme, so we don't need to link against the systems one.

I don’t think that would make the build issues any easier; instead of figuring out how to build the Go library against the OS libgpgme, now everyone would have to figure out how to build the Go library + the bundled libgpgme against the rest of the OS ecosystem.

We could just add a Makefile to this repo to detect a gpgme version and set Go build tags; and that would be much simpler than bundling libgpgme. But, as discussed above, that would still break go build and so far seems to be not worth it.

@ikrabbe
Copy link

ikrabbe commented Aug 30, 2016

Actually the gpgme has a quite stable and simple upstream.
What OS vendors make from that is completely different.
It is not just the version but also the way the vendor distributes include files and else in the system.

But as stated, fixing the includes allows to compile the tool against a gpgme-1.5.5 on my system.

What's the error on your side?

@proglottis
Copy link
Owner

Some constants and some new features don't exist on old gpgme versions.

See mtrmac@e883484 and mtrmac@808bb5b

Conditionally building those is practically impossible I think. I have wondered if it would be possible to write a C shim since it could use the preprocessor to version check.

@mtrmac
Copy link
Contributor Author

mtrmac commented Aug 31, 2016

A C shim with some #ifdefs might allow C code to build, but would not make the definitions of Golang constants conditional. That needs Golang tags, as discussed in #6 (comment) .

This is all fairly unrelated to @ikrabbe ’s issue that the #include path differs between distributions. I don’t know how to fix that other than giving up on go build and using either a plain shell script or make to call gpgme-config.

@proglottis
Copy link
Owner

@mtrmac is this still a problem for you since #17 (comment) ?

I now run this on travis-ci using libgpgme11-dev - I broke backwards compat to make this work (just constants) https://travis-ci.org/proglottis/gpgme

@mtrmac
Copy link
Contributor Author

mtrmac commented Oct 31, 2019

@proglottis Looking at current master, it removes the symbols added after 1.4.3 (old Fedoras), but not between 1.3.2 and 1.4.3 (relevant for CentOS 7). I’m afraid CentOS 7 still uses 1.3.2.

@mtrmac
Copy link
Contributor Author

mtrmac commented Jan 25, 2022

FWIW this is no longer a concern for us, RHEL 8 ships with GPGME 1.13 now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants