Re: How to determine ports affected by ABI change

From: Matthew Seaman <matthew_at_FreeBSD.org>
Date: Sat, 13 May 2023 14:03:35 UTC
On 13/05/2023 13:43, Xavier Humbert wrote:
> I'm planning in a few days, as soon as it beeen branched, to upgrade 
> base from 13-STABLE to 14-STABLE
> 
> I'm trying to avoid to rebuild my > 1600 ports.
> 
> Is there a wayto determine ports affected by the ABI change, which must 
> be recompiled ? Obviously Pure Perl or Pure Pyhton don't need to.
> 

Since libc and other shared libraries in the FreeBSD base system use API 
versioning, almost all of your ports will continue to function on 
14-STABLE.  There will also be a misc/compat13x port to provide 
compatibility for any non-versioned system shared libraries, which you 
should install as part of upgrading your base system.

So, no need to rebuild everything immediately.  With the obvious 
exception of any loadable kernel modules which will definitely need to 
be updated to operate with the new 14-STABLE kernel.

However, as soon as you start updating ports on your new 14-STABLE 
system, this can change and simultaneous re-installation of several pkgs 
be required.  That's generally a consequence of something being linked 
against a different API version somewhere in a dependency chain, which 
may require the whole dependency chain involved to be updated at the 
same time.

Obviously, as you correctly observe, that only applies to software 
compiled down into machine code and linked by the system loader, ld.so 
-- statically linked binaries, interpreted languages (shell) or pure 
byte-compiled language modules (python, perl, lua, java) won't be 
affected.  Although the interpreters for any of those languages could 
well be, as would any modules built around loadable shared objects.

In terms of packages, the things to look for are:

  (1) architecture independence: `pkg query -a '%n-%v %q' | grep -F '*'`

Although the ABI string built into the package will say eg. 
`FreeBSD:13:*` indicating a specific major version of the OS, such 
packages probably _don't_ need to be recompiled for an OS major verson 
change.

  (2) Of the architecture dependent packages, check for those requiring 
or providing shared libraries: `pkg info -bB pkgname`

Typically this will not include any shared library dependencies on the 
base system (so not entirely foolproof) but any package only linking 
against the base system shlibs and not providing shlibs for anything 
else to link against is effectively a leaf package in this respect, and 
can be updated independent of anything else.

Look out for compiled dynamically loaded modules too -- things like 
apache or nginx modules, wrappers for shared libraries to make them 
available in other languages and so forth.  (eg. Python modules that are 
not architecture independent.)

Anything remaining after applying those filters is going to require more 
care to update smoothly.  It's going to be quite a laborious task to 
classify all of your 1600 ports and map out what depends on what and 
what groups of packages would need to be reinstalled in synchrony. 
Whether it's worth it compared to just throwing CPU-cycles at the 
problem and rebuilding everything straight off is not obvious to me.

Running a mixed set of packages from different major OS versions will 
run the risk of software packages arbitrarily crashing with consequent 
loss of functionality and potential system downtime.  Good luck.

Note that if you're using poudriere to build packages, updating a 
poudriere-jail to 14-STABLE will automatically trigger a full rebuild of 
all packages, precisely what you want to avoid.

	Cheers,

	Matthew