I've just extracted a bunch of sources to several static libraries to make project more structured, and binary size of main executable increased by ~150kb. It confused me, so I've made small project with three files:
foo.c:
int foo1(void) { return 1; }
int foo2(void) { return 2; }
...
int foo100(void) { return 3; }
bar.c:
int bar1(void) { return 1; }
int bar2(void) { return 2; }
...
int bar100(void) { return 4; }
main.c:
int main(int argc, const char * argv[]) {
int acc = 0;
acc += foo1();
acc += bar1();
acc += foo2();
acc += bar2();
...
acc += foo100();
acc += bar100();
printf("%d\n", acc);
}
And after I made two executables and one static library:
libfoo.a:
foo.o
bar.o
test_no_lib:
main.o
foo.o
bar.o
test_with_lib:
main.o
libfoo.a
And their size differ by about 2kb (~31kb for test_no_lib and ~33kb for test_with_lib, compiled with clang 11 on macos, -Os optimisation, all symbols stripped).
Why is that? Isn't static library suppose to be just an archive off object files and linker takes those object files if it needs some? Why is it also increases size? It is not very much, but it surprises me nevertheless, why it is not free?
I've figured it out. Static library was compiled with different visibility settings (default), so linker had to keep relocation info, even though all symbol names were stripped.