1

demo_lib.h void fun();

demo_lib.cpp

#include<iostream>
void fun(){
    std::cout << "I am in demo_lib::fun()" << std::endl;
}

compiled a static library

g++ -c demo_lib.cpp -o demo_lib.o
ar rcs libdemo_lib.a demo_lib.a

main.c

#include "demo_lib.h"
int main(){
    fun();
    return 0;
}

compiled static

g++ -static main.cpp -L. -ldemo_lib
size of a.out is 1702697 => static linked by linker 

compiled without static

g++ main.cpp -L. -ldemo_lib
size of a.out is 9247  => is demo_lib linked dynamically  ??

why the difference in size here ??

i think the cpp library is linked static when we used -static compiler option

And when we don't cpp library is linked dynamically except the demo_lib.

In both case's demo_lib is linked static and only the cpp library diff

can we link static compiled library as dynamic ??

does this mean the default linkage of standard library is shared ??

Jagan Arikuti
  • 365
  • 1
  • 2
  • 11
  • Possible duplicate of [When to use dynamic vs. static libraries](http://stackoverflow.com/questions/140061/when-to-use-dynamic-vs-static-libraries) – SevenBits Feb 20 '16 at 18:06
  • I don't agree that is a good dupe, this question is about WHY the size of the executable is as it is with different library forms. – Mats Petersson Feb 20 '16 at 18:39

2 Answers2

4

The difference in size you see between --static and not is that the C and C++ standard library functions are and aren't linked in. So, the size difference isn't from YOUR library (which is presumably only a few hundred bytes, given that it's just a couple of calls to cout::operator<<(), and should only produce somewhere around a dozen instructions [assuming x86, but on ARM or MIPS it would be a no more than 20-25 instructions for all your code].

And no, you can't link a shared library as such statically, and you can't link a static library as shared - they are different files with different content. When you use --static, the compiler (or linker) will pick X.a in preference over X.so [assuming both exists].

Adding -Wl,--verbose will show you exactly [or at least a lot more detail than without] what the linker does when you link your program, and will show the difference quite clearly between with --static and without. With --static you'll get a whole heap of lines like:

(/usr/lib/gcc/x86_64-redhat-linux/4.9.2/../../../../lib64/libc.a)read.o

indicating, in this case, that the function read [which is the underlying basis of things like fread, scanf, cin::operator>> and so on].

You can of course also use objdump -d to see what code is linked into your application, for example.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
1

On top of excellent Mats Petersson answer, there is a good tool to check how many libraries are linked dynamically, just type

> ldd a.out

and output will contain all shared libraries your app is linked to

Severin Pappadeux
  • 18,636
  • 3
  • 38
  • 64