port:libressl vs port:openssl, path-style variants and prebuilt binaries

René J.V. Bertin rjvbertin at gmail.com
Tue Nov 22 12:16:34 CET 2016


On Tuesday November 22 2016 10:54:22 Mojca Miklavec wrote:

>According to my understanding, ports that depend on either of multiple
>ABI-incompatible libraries should use variants to pick one or the
>other, path-style is just the wrong workaround/shortcut (I don't know
>if  openssl/libressl are ABI-incompatible, I'm just taking your word
>for it, but if they are, the same holds for those two).

I'm not 100% sure how the situation is now, but I tried migrating to libressl about a year ago, realised that this obliged me to rebuild all ssl dependents (also because the libressl libs have a different version in their name, IIRC), and retain from the ensuing discussion when I asked about this that I was trying to do something impossible.

The situation with -devel ports is a bit more ambiguous: whether or not the -devel version indeed introduces an ABI incompatibility in continuous flux if it evolves regularly. For instance, a Qt5-devel port that provides a development 5.6.x version *may* just provide a richer private API/ABI which shouldn't affect most dependents. Once it provides 5.7 or newer, however, it will still be a drop-in replacement for Qt 5.6.x, but going back to Qt 5.6 will require rebuilding all dependents that were built against the -devel port.

But yes, the building blocks I mentioned include the variant mechanism and labelling installed port with a variant indicating which alternative dependency was active when the port was installed.
What I could imagine for an alternative port that can be preferred by the user and that introduces an asymmetric ABI dependency as described above is something like this, in the associated PortGroup (which already sets up dependencies and similar things):
- declare a variant (or as many variants as there are alternatives if you always want to apply an explicit label)
- determine which of the alternative dependencies is installed
- make the corresponding variant default (using default_variants)
This is probably a bit novel (in the sense that it's a variant that users aren't support to manipulate themselves). I think it shouldn't violate anything though, not even the reproducible build principle as long as installing a dependent port from scratch on a user system and on the build bot leads to the use of the same intended port (typically the standard port).

You can even extend this with a way for ports to indicate a preference before the PortGroup is included, so that an installation from scratch pulls in the preferred alternative dependency. This is an approach I'm currently following with my KF5 ports: if you request the installation of, say, kf5-kate on a system that doesn't have Qt5 installed you will get qt5-kde, but if you already have port:qt5 installed that one will be used (an unsupported configuration, but that's a different topic). Once you install port:qt5-kde, all Qt5 dependent ports will be installed with a +qt5kde variant. This is a bit overkill, but ensures there will never be incompatibility issues when installing prebuilt packages.

Just to be certain: there is no way for a port to unset a variant once the user has set it, correct? If it *is* possible the above variant mechanism can also be used as a way for ports AND user to express a preference (rather than a hard dependency).

>doesn't offer any easy way to do the switch. Ideally (in my opinion)
>there should be a mechanism to do the switch with a single command
>(and replace/reinstall all ports "foo +openssl" with "foo +libressl").

If you have 2 alternative variants one of which is always selected it should be possible to write a script that deactivates all active ports with one variant and (re)activate ports with the other variant. It must be possible to do the same when there's only a single variant which indicates if the port uses an alternative dependency. 
General probem here is that activation can require figuring out which of a series of installed versions to activate.

>    # alternatives: wxWidgets-2.8 wxGTK-2.8 wxPython-3.0 ...
>    wxWidgets.use wxWidgets-3.0
>    depends_lib-append port:${wxWidgets.port}
>
>but I made wxWidgets co-installable, so it didn't hurt anyone if some

That makes sense for major releases of a middleware; this has finally be done for Qt4 and Qt5 too, albeit in a different way.

>ports remained linked against wxWidgets 2.8. In case of libressl this
>would be slightly more painful.

One could also imagine an approach with a split into binaries and the development stuff (the equivalent of -dev packages under Debian and Ubuntu).
I don't know if that would make things less painful or even worse, though.

>If you asked this question in the spirit of what should be done with
>Qt, you could easily pick a similar approach as I did with wxWidgets
>instead of using path-style dependency.

I don't want to go down the road of installing 2 subtly different Qt5 versions in parallel in the same prefix and risk having to deal with build system AND runtime confusion down the road. I've considered it, but Qt is too large and complex and KF5 intends to be an extension to Qt5 rather than just self-contained family of applications that happen to use Qt5.

>There is some unfinished code (from summer of code) in master that
>should be better at resolving dependencies of ports with variants.

It would of course be much preferable not to have to wait for changes in base in some future release (for introducing qt5-kde and the KF5 ports).

R.


More information about the macports-dev mailing list