gcc -u symbol compiler option

When do we use the gcc -u compiler option? Can you please provide an example too?

https://gcc.gnu.org/onlinedocs/gcc-2.95.2/gcc_2.html Says the following:

Pretend the symbol symbol is undefined, to force linking of library modules to define it. You can use `-u' multiple times with different symbols to force loading of additional library modules.


Solution 1:

Normally during linking of an object, the supplied modules (that is, from compiled archives and other object files) are searched for undefined symbols, and only the symbols required by to minimally satisfy the whole set of undefined symbols are drawn from the supplied modules.

What this means in practice is that if you have e.g. a function foo() in an object file, unless foo() is used somewhere else in the final linked product, it will not be included. This is normally the desired behaviour.

What about the case where you have a module contributing some functions which are not referenced anywhere else from the final linked product, but which you nonetheless want included? (For example, perhaps these functions are designed to be invoked directly from a debugger). This is where the -u option comes in handy. It effectively tells the linker that there is an unsatisfied reference to foo(), thus triggering its inclusion into the final linked product in spite of the symbol not being referenced in code.

Example:

Let's define two functions, foo and bar, and place each in a separate module, and then a short program which references just foo. Even though we link both libfoo.a and libbar.a into the program, an examination of the program (a.out)'s symbols shows bar was not included.

foo.h:

void foo(void);

foo.c:

void foo(void) { }

bar.h:

void bar(void);

bar.c:

void bar(void) { }

main.c:

#include "foo.h"
#include "bar.h"
int main(int argc, char** argv) {
    foo();
    return 0;
}

build:

gcc -c foo.c bar.c main.c
ar -r libfoo.a foo.o
ar -r libbar.a bar.o
# For macOS, replace -shared with -dylib
ld -shared main.o -L . -lfoo -lbar
nm -g --defined-only a.out

> T _main
> T _foo

Now if we modify just the linker phase, and tell it to add an undefined reference to bar (using its linked name, which will be prefixed with an underscore), this time we'll find bar in the final product, even though it's not referenced in the program:

# For macOS, replace -shared with -dylib
ld -shared -u _bar main.o -L . -lfoo -lbar
nm -g --defined-only a.out

> T _main
> T _foo
> T _bar