Static linking
Example
Let's say you want a library that defines a function help() that outputs "hello world". First create help.cpp
cat >help.cpp #include <iostream> extern "C" void help() { std::cout << "hello world" << '\n'; }
Then create main.cpp which will be the program calling the function help():
cat >main.cpp #include <iostream> #include <dlfcn.h> extern "C" void help(); int main() { help(); return 0; }
Now compile help.cpp, but do not make it an executable. An attempt to make it an executable will fail because it does not contain a main routine.
# gcc -c help.cpp
Verify your library help.o has been created:
# ls -ltr total 12 -rw-r--r-- 1 root root 87 Dec 31 11:32 help.cpp -rw-r--r-- 1 root root 105 Dec 31 11:57 main.cpp -rw-r--r-- 1 root root 2712 Dec 31 11:57 help.o
Create an archive out of help.o. In a real case you would use more than one .o file:
# ar -r help.a help.o # ls -ltr total 16 -rw-r--r-- 1 root root 87 Dec 31 11:32 help.cpp -rw-r--r-- 1 root root 105 Dec 31 11:57 main.cpp -rw-r--r-- 1 root root 2712 Dec 31 11:57 help.o -rw-r--r-- 1 root root 2854 Dec 31 12:00 help.a
Verify main.cpp has an unresolved dependency to a function help:
# g++ main.cpp /tmp/ccvIeJnW.o: In function `main': main.cpp:(.text+0x5): undefined reference to `help' collect2: ld returned 1 exit status
Put the archive in a place so gcc can find it:
# cp help.a /usr/lib/libhelp.a
Compile and link your program:
# g++ -o myprogram main.cpp -lhelp
Test it:
# ./myprogram hello world
Verify it does NOT have a dependency on help.so or help.o:
# ldd myprogram linux-vdso.so.1 => (0x00007fff34dff000) libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f784ce16000) libm.so.6 => /lib64/libm.so.6 (0x00007f784cbbf000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f784c9a9000) libc.so.6 => /lib64/libc.so.6 (0x00007f784c649000) /lib64/ld-linux-x86-64.so.2 (0x00007f784d120000) #
Verify it really contains code to output hello world in the executable file:
# strings myprogram /lib64/ld-linux-x86-64.so.2 SuSESuSE libstdc++.so.6 __gmon_start__ _Jv_RegisterClasses _ZNSt8ios_base4InitD1Ev _ZSt4cout _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_c _ZNSt8ios_base4InitC1Ev libm.so.6 libgcc_s.so.1 libc.so.6 __cxa_atexit __libc_start_main GLIBC_2.2.5 GLIBCXX_3.4 %z %r %j %b %Z fff. l$ L t$(L |$0H hello world
Look at its size so you can compare it with the same example that has been linked dynamically:
# ll myprogram -rwxr-xr-x 1 root root 12541 Dec 31 12:03 myprogram
You see it has a size of 12 541 bytes while the executable file that has been linked dynamically has a size of 12 173 bytes.