2

I am wondering if it could happen that, in a programm written in C, the code for a function from a static library is contained twice in an executable.

For example, assume that you create a static library lib_a which uses functions from another static library lib_b. Then you create a programm that uses both lib_a and lib_b. Would the executable for this programm contain the code for the functions from lib_b twice? If not, how is this avoided?

My understanding of the linker and of the format of an executable is very rough; sorry if this question is quite basic. Maybe somebody knows a good reference for this topic? I have searched several books on C, but I can't find the answer.

lee77
  • 1,493
  • 3
  • 10
  • 14
  • It will be contained twice, if you don't want it you should create a lib_c with the merge of lib_b and lib_a and replace in the source file lib_b and lib_a by lib_c. some more explanations [here](http://en.wikipedia.org/wiki/Static_library) and [here](http://www.cs.swarthmore.edu/~newhall/unixhelp/howto_C_libraries.html) – Yann Jun 24 '14 at 13:13
  • @Yann Are you sure? With global variables one could not have multiple definitions linked together. With global functions one can? – Peter - Reinstate Monica Jun 24 '14 at 14:38
  • See here: http://stackoverflow.com/questions/6940384/how-to-deal-with-symbol-collisions-between-statically-linked-libraries – Archie Jun 24 '14 at 14:53
  • I'm still waiting for the expert programmer but meanwhile let me check my understanding. Creating a static library lib_b which uses functions from lib_a doesn't mean to include code from lib_a in lib_b. lib_b will have "unresolved references" to functions in lib_a (lib_a doesn't even have to be present when lib_b is created). In fact, in the typical unix environment it's at least unusual and difficult to produce a library which has all its dependencies resolved, because that step is usually done when linking the executable. – Peter - Reinstate Monica Jun 24 '14 at 15:15

2 Answers2

0

You can also convert lib_b to a shared library on top of what @Yann suggests

Peter Petrik
  • 9,701
  • 5
  • 41
  • 65
0

Suppose library lib_a.a (a Unix-style static library) contains a function a1_function(), and a1_function() calls another function b1_function() that is found in lib_b.a.

Suppose your program calls a1_function() directly, and also calls another function, b2_function(), from lib_b.a directly.

Your linker command might look like:

c99 -o program program.c -l_a -l_b

You cannot link your program without mentioning both lib_a.a (as -l_a or by pathname) and lib_b.a. Even if you later revise your program so it no longer calls b2_function(), you will still need both libraries, because lib_a.a only contains its own code, not the code that is in lib_b.a.

With shared libraries, it might be possible for to link the revised program (with no direct call to b2_function()) with just -l_a and rely on the metadata in lib_a.so to tell the linker to link with lib_b.so too.

If you revise lib_a.a so it contains not only a1_function() but also the code for b1_function() and any supporting code necessary to support it (which will exclude b2_function() for the purposes of this discussion). Then the program that calls just a1_function() would not need lib_b.a at all. However, if the program calls b2_function(), then you will need to link with both libraries. The material from lib_a.a that satisfied b1_function() and its dependencies will come from lib_a.a; the function b2_function() and any supporting material it needs that was not provided by lib_a.a will also be linked in.

If the code from lib_b included in lib_a.a is different from the 'same' code in lib_b.a, then you have potential for aberrant behaviour. An extreme case of this might be an object file, b_file1.c, which contains a number of functions including b1_function() and b2_function(). When compiled for inclusion in lib_a.a, the b2_function() is not included; when compiled for inclusion in lib_b.a, the b2_function() is included (and b1_function() is always included). Then you will fail to link the program when it calls b2_function() because the program will link b_file1.o from lib_a.a to satisfy the b1_function() reference, but the linker will also try to link b_file1.o from lib_b.a to satisfy the b2_function() reference. This leads to two definitions of function b1_function(), and that isn't allowed (under static library linking rules). With shared libraries, it isn't entirely clear what would happen, but there are a number of ways that things could go wrong (but errors for doubly-defined symbols wouldn't be one of those ways).

Note that you should studiously avoid circumstances where a function in lib_a.a calls a function in lib_b.a and a function in lib_b.a calls a function in lib_a.a. This leads to circular dependency problems, and can mean you need to list libraries multiple times on a command line. It would be far better to create a single library, lib_c.a containing the material from both lib_a.a and lib_b.a and link with that, once.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278