问题
In the following example, the program should print "foo called":
// foo.c
#include <stdio.h>
__attribute__((constructor)) void foo()
{
printf("foo called\n");
}
// main.c
int main()
{
return 0;
}
If the program is compiled like this, it works:
gcc -o test main.c foo.c
However, if foo.c is compiled into a static library, the program prints nothing.
gcc -c main.c
gcc -c foo.c
as rcs foo.a foo.o
gcc -o test foo.a main.o
Why does this happen?
回答1:
The linker does not include the code in foo.a in the final program because nothing in main.o references it. If main.c
is rewritten as follows, the program will work:
//main.c
void foo();
int main()
{
void (*f)() = foo;
return 0;
}
Also, when compiling with a static library, the order of the arguments to gcc (or the linker) is significant: the library must come after the objects that reference it.
gcc -o test main.o foo.a
回答2:
As it was stated, unreferenced symbols from archive does not make it to the output binary, because linker discards them by default.
To override this behaviour when linking with static library, --whole-archive
/--no-whole-archive
options for the linker may be used, like this:
gcc -c main.c
gcc -c foo.c
ar rcs foo.a foo.o
gcc -o test -Wl,--whole-archive foo.a -Wl,--no-whole-archive main.o
This may lead to bloated binary, because all symbols from foo.a
will be included by the linker to the output, but sometimes it is justified.
来源:https://stackoverflow.com/questions/1202494/why-doesnt-attribute-constructor-work-in-a-static-library