Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Let's say you have the following C source file, call it <code>name.c</code></p> <pre><code>#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; void print_name(const char * name) { printf("My name is %s\n", name); } </code></pre> <p>When you compile it, with <code>cc name.c</code> you generate <code>name.o</code>. The .o contains the compiled code and data for all functions and variables defined in name.c, as well as index associated their names with the actual code. If you look at that index, say with the <code>nm</code> tool (available on Linux and many other Unixes) you'll notice two entries:</p> <pre><code>00000000 T print_name U printf </code></pre> <p>What this means: there are two symbols (names of functions or variables, but not names of classes, structs, or any types) stored in the .o. The first, marked with <code>T</code> actually contains its <em>definition</em> in <code>name.o</code>. The other, marked with <code>U</code> is merely a <em>reference</em>. The code for <code>print_name</code> can be found here, but the code for <code>printf</code> cannot. When your actual program runs it will need to find all the symbols that are references and look up their definitions in <em>other</em> object files in order to be linked together into a complete program or complete library. An object file is therefore the definitions found in the source file, converted to binary form, and available for placing into a full program.</p> <p>You can link together .o files one by one, but you don't: there are generally a lot of them, and they are an implementation detail. You'd really prefer to have them all collected into bundles of related objects, with well recognized names. These bundles are called <em>libraries</em> and they come in two forms: static and dynamic.</p> <p>A <em>static library</em> (in Unix) is almost always suffixed with <code>.a</code> (examples include <code>libc.a</code> which is the C core library, <code>libm.a</code> which is the C math library) and so on. Continuing the example you'd build your static library with <code>ar rc libname.a name.o</code>. If you run <code>nm</code> on <code>libname.a</code> you'll see this:</p> <pre><code>name.o: 00000000 T print_name U printf </code></pre> <p>As you can see it is primarily a big table of object files with an index finding <em>all</em> the names in it. Just like object files it contains both the symbols defined in every <code>.o</code> and the symbols referred to by them. If you were to link in <em>another</em> .o (e.g. <code>date.o</code> to <code>print_date</code>), you'd see another entry like the one above.</p> <p>If you link in a static library into an executable it embeds the entire library into the executable. This is just like linking in all the individual <code>.o</code> files. As you can imagine this can make your program very large, especially if you are using (as most modern applications are) a lot of libraries.</p> <p>A <em>dynamic</em> or <em>shared library</em> is suffixed with <code>.so</code>. It, like its static analogue, is a large table of object files, referring to all the code compiled. You'd build it with <code>cc -shared libname.so name.o</code>. Looking at with <code>nm</code> is quite a bit different than the static library though. On my system it contains about two dozen symbols only two of which are <code>print_name</code> and <code>printf</code>:</p> <pre><code>00001498 a _DYNAMIC 00001574 a _GLOBAL_OFFSET_TABLE_ w _Jv_RegisterClasses 00001488 d __CTOR_END__ 00001484 d __CTOR_LIST__ 00001490 d __DTOR_END__ 0000148c d __DTOR_LIST__ 00000480 r __FRAME_END__ 00001494 d __JCR_END__ 00001494 d __JCR_LIST__ 00001590 A __bss_start w __cxa_finalize@@GLIBC_2.1.3 00000420 t __do_global_ctors_aux 00000360 t __do_global_dtors_aux 00001588 d __dso_handle w __gmon_start__ 000003f7 t __i686.get_pc_thunk.bx 00001590 A _edata 00001594 A _end 00000454 T _fini 000002f8 T _init 00001590 b completed.5843 000003c0 t frame_dummy 0000158c d p.5841 000003fc T print_name U printf@@GLIBC_2.0 </code></pre> <p>A shared library differs from a static library in one very important way: it does not embed itself in your final executable. Instead the executable contains a reference to that shared library that is resolved, not at link time, but at run-time. This has a number of advantages:</p> <ul> <li>Your executable is much smaller. It only contains the code you explicitly linked via the object files. The external libraries are references and their code does not go into the binary.</li> <li>You can share (hence the name) one library's bits among multiple executables.</li> <li>You can, if you are careful about binary compatibility, update the code in the library between runs of the program, and the program will pick up the new library without you needing to change it.</li> </ul> <p>There are some disadvantages:</p> <ul> <li>It takes time to link a program together. With shared libraries some of this time is deferred to every time the executable runs.</li> <li>The process is more complex. All the additional symbols in the shared library are part of the infrastructure needed to make the library link up at run-time.</li> <li>You run the risk of subtle incompatibilities between differing versions of the library. On Windows this is called "DLL hell".</li> </ul> <p>(If you think about it many of these are the reasons programs use or do not use references and pointers instead of directly embedding objects of a class into other objects. The analogy is pretty direct.)</p> <p>Ok, that's a lot of detail, and I've skipped a lot, such as how the linking process actually works. I hope you can follow it. If not ask for clarification.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload