5

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.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
Chetan Dugar
  • 63
  • 1
  • 5
  • 5
    We don't use it — almost never use it. (I've not needed to use it during the last 30 years, AFAICR.) When you have a need for it, you will know what to do. Until then, don't worry about it. There are a lot of other options to GCC that are similar — they're invaluable if you need to do something arcane, but 99.99% of the time are not relevant. – Jonathan Leffler Aug 18 '16 at 13:37
  • @JonathanLeffler, I currently do have a need for it and I cannot for the life of me figure out how to get it to work. I am trying to build a dynamic library that has a function in a header file that requires a single symbol from a static library, however since its in a header file it doesn't automatically link the static library for me because technically when I compile my library the symbol is not being used yet. This means clients of my library must know to link the static lib... Do you know how to make the "-u" option work? Or even better do you have any better solution for my problem? – tjwrona1992 Jan 25 '19 at 19:43
  • @tjwrona1992: I think I'd probably create a file `libname.c` that contains `#include "header.h"` and then use the usual rules to build a shared library on your platform, possibly with the static library listed on the command line that creates the shared library. I'm not confident that this would work; having a shared library call a symbol from a static library probably means that the static library has to be linked into the executable for the shared library to be able to find the symbol. That's the difference between a shared and a static library; you can't just load the static one on demand. – Jonathan Leffler Jan 25 '19 at 19:47
  • You might need to use: `gcc -u staticlibsymbol -o prog obj1.o … -ldynamic -lstatic …` (where `libdynamic.so` or whatever is for the shared object, and `libstatic.a` is the static library), and this might cause the symbol `staticlibsymbol` from the static library to be linked into the executable so it's available to the dynamic library at run time. If you've tried that, then you probably need to ask a new question on SO, with an MCVE ([MCVE]). It can legitimately cross-reference this question — I almost said Q&A but there's no formal A here. – Jonathan Leffler Jan 25 '19 at 19:53
  • The link in the question is to an archaic version of the compiler. However, you get much the same information from the GCC 8.2.0 Manual on [Linker Options](https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/Link-Options.html#Link-Options). – Jonathan Leffler Jan 25 '19 at 19:59
  • @JonathanLeffler, I did try your first recommendation, but since the dynamic library only includes the header but doesn't actually attempt to use the symbol itself it doesn't get linked in. (It only gets used when a client calls a function that is contained within a header file in my library - this function must be header only because it is a template function. If it was not header only I imagine this would work.) I will try a few more things and possibly open a new question if I can't get it to work correctly. – tjwrona1992 Jan 28 '19 at 14:52
  • You may need to manufacture something that causes the function in the header to be created (instantiated), I think. However, I’m hypothesizing without a sufficiently good understanding of the situation. If you have no success with what you’re already planning to try, create a good MCVE ([MCVE]) and ask your question. By all means leave a comment here to point me to it. (No guarantees about my response time, of course, but other people can also help.) – Jonathan Leffler Jan 28 '19 at 15:01

1 Answers1

5

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
bleater
  • 5,098
  • 50
  • 48