BDE 4.14.0 Production release
|
Macros | |
#define | BSLS_LINKCOERCION_FORCE_SYMBOL_DEPENDENCY(type, refName, referredSymbol) |
Provide a way to force a link-time dependency into an object.
This component provides a facility to force a link-time dependency on a symbol of the name supplied to the macro into the translation unit being compiled. This macro can be useful for generating link-time failures if a library version mismatch occurs.
This section provides a brief description of the macros defined in this component.
Notice that this macro is typically used to prevent to binary incompatible object files from being successfully linked together. This is achieved by calling this macro in a way that referredSymbol
will have a different symbol name for incompatible builds.
Link-time coersion is implemented by creating a static variable that references an external symbol defined by the library. The actual name of this external symbol should be different for different build flavors. When the executable is linked against the libraries with link-coercion symbols, the linker needs to resolve the symbol name and will fail the link step if the required symbol name is not present in the linked library (i.e. the library was built with a different set of flags that control the coercion symbol creation). For example, we can create different coercion symbols for code built with c++17 and c++20 flags, effectively preventing translation units compiled with different c++ standard flags from being linked into an working program.
Modern linkers may implement link-time garbage collection. In order to minimize the size of the final executable the linker can remove sections of object files that are not referenced anywhere from the code being linked. Unfortunately, the link coercion symbols are not referenced directly and may be garbage collected and, if removed, lead to a silent failure and successful linkage of a potentially binary incompatible executable. To avoid such a failure, coercion symbols are placed in the dedicated data section (if supported by the compiler) and this section is marked in-use to avoid it being garbage collected by the linker.
More information on details on linker garbage collection can be found here: https://maskray.me/blog/2021-02-28-linker-garbage-collection
In this section we show intended use of this component.
In this example we use a link coercion symbol to prevent linking a translation unit built against the header in debug mode, with a translation unit built against the header in optimized mode.
First we define a macro such that our symbol name will be different for debug and optimized builds of our library:
Now we use the BSLS_LINKCOERCION_FORCE_SYMBOL_DEPENDENCY
macro to require translation units to link against a library having a matching symbol name:
Note that the referred symbol will have a different name depending on whether NDEBUG
is defined or not.
Finally, in the corresponding .cpp
file we must define the appropriate symbol name for the library:
#define BSLS_LINKCOERCION_FORCE_SYMBOL_DEPENDENCY | ( | type, | |
refName, | |||
referredSymbol | |||
) |