git: aaa7af03ec - main - developers-handbook: update shared libraries policy section

Konstantin Belousov kib at FreeBSD.org
Tue Jul 27 19:49:01 UTC 2021


The branch main has been updated by kib (src committer):

URL: https://cgit.FreeBSD.org/doc/commit/?id=aaa7af03ec916877d59eb81f05d4cddbc01cefc5

commit aaa7af03ec916877d59eb81f05d4cddbc01cefc5
Author:     Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2021-07-18 13:48:59 +0000
Commit:     Konstantin Belousov <kib at FreeBSD.org>
CommitDate: 2021-07-27 19:48:40 +0000

    developers-handbook: update shared libraries policy section
    
    Current text was written with a.out shared libraries system in mind,
    which is not adequate for ELF system. In fact it can be considered
    as mis-information causing to spread false rumors about FreeBSD
    environment.
    
    Drop everything that comes from a.out world, and briefly describe common
    conventions related to ELF shared objects.
    
    Reviewed by:    emaste
    Sponsored by:   The FreeBSD Foundation
    Differential revision:  https://reviews.freebsd.org/D31213
---
 .../books/developers-handbook/policies/_index.adoc | 37 ++++++++++------------
 1 file changed, 16 insertions(+), 21 deletions(-)

diff --git a/documentation/content/en/books/developers-handbook/policies/_index.adoc b/documentation/content/en/books/developers-handbook/policies/_index.adoc
index b08ed72832..cfa074a542 100644
--- a/documentation/content/en/books/developers-handbook/policies/_index.adoc
+++ b/documentation/content/en/books/developers-handbook/policies/_index.adoc
@@ -287,30 +287,25 @@ The following policies apply to including encumbered files in the FreeBSD source
 If you are adding shared library support to a port or other piece of software that does not have one, the version numbers should follow these rules.
 Generally, the resulting numbers will have nothing to do with the release version of the software.
 
-The three principles of shared library building are:
+For ports:
 
-* Start from `1.0`
-* If there is a change that is backwards compatible, bump minor number (note that ELF systems ignore the minor number)
-* If there is an incompatible change, bump major number
+* Prefer using the number already selected by upstream
+* If upstream provides symbol versioning, ensure that we use their script
 
-For instance, added functions and bugfixes result in the minor version number being bumped, while deleted functions, changed function call syntax, etc. will force the major version number to change.
+For the base system:
 
-Stick to version numbers of the form major.minor (`_x_._y_`).
-Our a.out dynamic linker does not handle version numbers of the form `_x_._y_._z_` well.
-Any version number after the `_y_` (i.e., the third digit) is totally ignored when comparing shared lib version numbers to decide which library to link with.
-Given two shared libraries that differ only in the "micro" revision, `ld.so` will link with the higher one.
-That is, if you link with [.filename]#libfoo.so.3.3.3#, the linker only records `3.3` in the headers, and will link with anything starting with `_libfoo.so.3_._(anything >= 3)_._(highest available)_`.
+* Start library version from 1
+* It is strongly recommended to add symbol versioning to the new library
+* If there is an incompatible change, handle it with symbol versioning, maintaining backward ABI compatibility
+* If this is impossible, or the library does not use symbol versioning, bump the library version
+* Before even considering bumping library version for symbol-versioned library, consult with Release Engineering team, providing reasons why the change is so important that it should be allowed despite breaking the ABI
 
-[NOTE]
-====
-`ld.so` will always use the highest "minor" revision.
-For instance, it will use [.filename]#libc.so.2.2# in preference to [.filename]#libc.so.2.0#, even if the program was initially linked with [.filename]#libc.so.2.0#.
-====
+For instance, added functions and bugfixes not changing the interfaces are fine, while deleted functions, changed function call syntax, etc. should either provide backward-compat symbols, or will force the major version number to change.
 
-In addition, our ELF dynamic linker does not handle minor version numbers at all.
-However, one should still specify a major and minor version number as our [.filename]#Makefile#'s "do the right thing" based on the type of system.
+It is the duty of the committer making the change to handle library versioning.
 
-For non-port libraries, it is also our policy to change the shared library version number only once between releases.
-In addition, it is our policy to change the major shared library version number only once between major OS releases (i.e., from 6.0 to 7.0).
-When you make a change to a system library that requires the version number to be bumped, check the [.filename]#Makefile#'s commit logs.
-It is the responsibility of the committer to ensure that the first such change since the release will result in the shared library version number in the [.filename]#Makefile# to be updated, and any subsequent changes will not.
+The ELF dynamic linker matches library names literally.
+There is a popular convention where library version is written in the form `libexample.so.x.y`, where x is the major version, and y is minor.
+Common practice is to set the library' soname (`DT_SONAME` ELF tag) to `libexample.so.x`, and set up symlinks `libexample.so.x->libexample.so.x.y`, `libexample.so->libexample.so.x` on library installation for the latest minor version y.
+Then, since the static linker searches for `libexample.so` when the `-lexample` command line option is specified, objects linked with libexample get a dependency on the right library.
+Almost all popular build systems use this scheme automatically.


More information about the dev-commits-doc-all mailing list