0
votes

So let's say we have static library mylib.a, which contains compiled cpp files.

file1.cpp:

int do_stuff();

int func_unres()
{
  int a = do_stuff();
  return a;
}

file2.cpp:

int do_other_stuff();

int func_res()
{
  int a = do_other_stuff();
  return a;
}

file3.cpp:

int do_other_stuff()
{
  return 42;
}

So, as we can see here, no file contains definition of do_stuff function. Library created this way:

g++ -c file1.cpp -o file1.o

g++ -c file2.cpp -o file2.o

g++ -c file3.cpp -o file3.o

ar r mylib.a file1.o file2.o file3.o

Now we try to make some binary with this library. Simple example main file:

#include <iostream>

int func_res();

int main()
{
  std::cout << func_res() << std::endl;
}

Compiling:

g++ main.cpp mylib.a -o my_bin

Everything works just fine. Now consider case of main file like this:

#include <iostream>

int func_unres();

int main()
{
  std::cout << func_unres() << std::endl;
}

In this case binary won't link, cause func_unres requires function do_stuff to be defined.

Is there a way to find out that static library requires symbol which no object file in the library contains before linking it with executable, which uses such symbol?

EDIT: The question is not how to simple list such symbols, but to get an output with linker like error. Like if i linked this library with executable using all of symbols it should contain.

1
Is there a way to find out that static library requires symbol which no object file in the library contains before linking it with executable, which uses such symbol? How would you know which symbols are used in the executable? Or are you interested in all symbols that are not defined but used in a static library? - KamilCuk
@KamilCuk yes, i want to make sure that all symbols that library uses are defined in it's object files - toozyfuzzy
it's too much of work No, it's not, it's like nm mylib.a | awk '$2 == "u" { print "void "$3"(void); "$3"();" }' > file.c; gcc file.c mylib.a. And i want something so implement that, stackoverflow is not a free writing service. It seems that even gcc -Wl,--whole-archive mylib.a -Wl,--no-whole-archive is enough to list all undefined symbols (and main). - KamilCuk
I don't get it. Why is an error emitted by this hypothetical pre-link tool better than having it come from the linker? - 500 - Internal Server Error
@500-InternalServerError: “Why is an error emitted by this hypothetical pre-link tool better than having it come from the linker?” Because the tool would tell you if any symbol used by the library is not defined, whereas linking would only tell you if a symbol used as a result of library object modules included by that executable is undefined. The latter might not occur with a particular executable, so it is insufficient to test that a library is complete before releasing it, unless the executable is known to contain a reference to at least one symbol in each object module of the library. - Eric Postpischil

1 Answers

1
votes

It seems that as pointed in comments and in How to force gcc to link an unused static library, linker option --whole-archive is enough to force resolve all symbols and output linker error for all unresolved symbols in static library. So referring the question examples, compiling and linking this way first main file, which doesn't refer undefined symbol, will output linker error anyway:

g++ main.cpp -Wl,--whole-archive mylib.a -Wl,--no-whole-archive

Linking fails despite main doesn't use func_unres:

mylib.a(file1.o): In function func_unres(): file1.cpp:(.text+0x9): undefined reference to do_stuff()

Second option --no-whole-archive is used so the rest of required libraries' symbols will not be force resolved like this.