Project:Quality Assurance/-Wl,-z,defs and -Wl,--no-allow-shlib-undefined

From Gentoo Wiki
Jump to:navigation Jump to:search

-Wl,-z,defs (aka -Wl,--no-undefined) and -Wl,--no-allow-shlib-undefined are two LDFLAGS that could be used to prevent undefined references in libraries.

Default state

By default, the GNU linker disallows undefined symbol references when linking final executables but allows them for shared libraries. The latter behavior is necessary since many projects depend on missing shared library symbols being provided by executables they are linked or loaded to. This is commonly the case with plugins, which call the plugin API provided by the executable that loads them.

However, this behavior also means that if a shared library misses linking to a dependency, it will build fine and the error won't be visible until the first executable linking to the library (directly or indirectly) is built. For example, if app-accessibility/flite has missing symbols, and media-video/ffmpeg links to it, neither of those two packages will fail to build. However, a package using ffmpeg, e.g. media-video/mpv will fail to build due to undefined symbols in flite.

What do the options change?

-Wl,-z,defs makes the linker treat any undefined symbols in linked object files (including static libraries) as errors. With this option, all symbols referenced in the code included in the shared library must be resolved using additional libraries linked in. In other words, this option prevents linker from creating shared libraries that are missing direct dependencies.

-Wl,--no-allow-shlib-undefined makes the linker treat any undefined symbols in shared libraries linked in as errors. In other words, this option prevents linker from creating shared libraries that are missing indirect dependencies.

For example, let's assume that app-accessibility/flite has missing symbols in the library. -Wl,-z,defs on this package would cause it to fail to build due to unresolved symbols. If the library is built already, media-video/ffmpeg will build successfully since the unresolved symbols are in an existing shared library. If -Wl,--no-allow-shlib-undefined was used, ffmpeg would fail to build.

How to use them?

Warning
Use of -Wl,--no-allow-shlib-undefined has not been tested thoroughly and may break weird systems, so it's preferable to focus on -Wl,-z,defs only.

The preferable way of introducing -Wl,-z,defs is to request upstream add the flag in the build system. This makes it possible to apply it only to the libraries that actually do not rely on undefined symbols, and also increases the testing coverage since all users of the package will be affected.

It is also acceptable to append the flag in ebuilds. In this case, the additional flag should be appended to the LDFLAGS variable. Please note that it will apply to all shared libraries built, so this may not work if the package builds any modules (plugins).

The flags should not be put in global LDFLAGS as they will result most module builds to fail.