Update shared library advice now that a.out no longer is a consideration

Remove old a.out information. Update the policy to match our current practice of
rarely, if ever, bumping the major version of libraries, but instead relying on
symbol versioning to maintain a stable ABI. Move from paragraph form to bullet
points. Also, tweak the 'once per major release' policy to 'as needed' because
the conditions that existed for the former no longer apply.

Discussed with: jhb@
Reviewed by: kib@, debdrub@
Differential Revision: https://reviews.freebsd.org/D28486
main
Warner Losh 3 years ago
parent dff8699750
commit ea2dde38df

@ -323,21 +323,34 @@ It might occasionally be necessary to include an encumbered file in the FreeBSD
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:
* 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
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.
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)_`.
[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#.
====
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.
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.
FreeBSD tries to maintain ABI stability. Most libraries in the system use symbol versioning to remain compatible with old versions of the library. When updating libraries with versioned symbols:
. Create new symbols in the symbol map for otherwise incompatible changes.
. When deleting old functions, only remove visibility of symbols from newer versions (that is, do not delete functions).
. Avoid gratuitous rearrangement of structures. This will keep compatibility symbols to a minimum.
. If changes require a version bump, re-evaluate whether they are needed at all.
For project-maintained libraries, please try to follow the following guidelines for major version numbers:
. New libraries
.. Should start with major version 1, though third-party libraries may start at a different number if warranted
.. All new libraries should either be symvers or private unless there's some compelling reason to deviate.
. For non-symvers libraries, avoid changes that would require a version bump.
.. When making a change that requires one, seriously consider adopting symbol versions at the same time
. For symvers libraries, generally, avoid version bumps
. Changes to structures can be worked around by providing the old structure and old functions to access it (if the layout of the structure is embedded in its clients).
. Changes to function signatures can be implemented by creating compatibility versions of the function (often calling the new version of the function in a specific way).
. If the benefits of a version bump outweight the costs to do it, follow up to ensure compat packages are built, etc
. Carefully consider the impact of a major version bump. When a major version change cannot be avoided, add a version map to avoid future bumps.
. For libraries where the ABI cannot be guaranteed, make them FreeBSD private where possible. Third party libraries that have poor ABI guarantees are generally made private, though there are a few exceptions for historical reasons.
. It is strong policy not to change the ABI of dynamicly linked libararies in an non-backwards compatible way
. Every reasonable effort should be made to make the changes in a binary compatible manner using tools like symbol versioning
. When major version changes cannot be avoided, the policy is to change only between major releases.
.. Minimize the number of major version bumps where possible
.. Multiple bumps are allowed between releases where necessary
.. Where possible, batch multiple changes that each would require a major bump together
.. Ensure that the compatibility ports / packages are updated as appropriate
.. Request an exp-run of ports to understand the full impact of the change to the base system
. Any changes to major libraries must still allow build from source upgrades to succeed
Changing the ABI is allowed, otherwise FreeBSD cannot evolve. However, the project has generally chosen to pay the added cost of retaining ABI backward-compatibility.

Loading…
Cancel
Save