Generating an Executable Output File

When generating an executable output file,
the link-editor's default behavior is to terminate with an appropriate error message should any symbols remain undefined. A symbol remains undefined when a symbol reference in a relocatable object
is never matched to a symbol definition.

To allow undefined symbols, as in the previous example, use the link-editor's -z nodefs option to suppress the default error condition.

Note –

Take care when using the -z nodefs option. If an unavailable symbol reference is required during the execution of a process, a fatal runtime relocation error occurs.
This error might be detected during the initial execution and testing of an application. However, more complex execution paths can result in this error condition taking much longer to detect, which
can be time consuming and costly.

Symbols can also remain undefined when a symbol reference in a relocatable object is bound
to a symbol definition in an implicitly defined shared object. For example, continuing with the files main.c and foo.c used in the previous example.

prog is built with an explicit reference to libbar.so. libbar.so has
a dependency on libfoo.so. Therefore, an implicit reference to libfoo.so from prog is established.

Because main.c made a specific reference to the interface provided by libfoo.so, prog really has a dependency on libfoo.so. However, only explicit shared object dependencies are recorded in the output file being generated. Thus, prog fails to run if a new version of libbar.so is
developed that no longer has a dependency on libfoo.so.

For this reason, bindings of this type are deemed fatal. The implicit reference must be made explicit by referencing the library directly during the link-edit of prog.
The required reference is hinted at in the fatal error message that is shown in the preceding example.