What puzzles me is that there is a .so file for every library, even
those that should be static. Why is it there? What is it needed for?
You apparently are using someone else's make file. I wrote my own. My
build command does not create a ".so" (shared object library). It only
creates the ".a" (archive library). The linker knows how to use
See man ar. The utility ar builds archives.
See man ld. The utility ld can build shared objects.
You might look for these utility invocations in your build sequence, or
ask someone where they are and comment out the use of ld, as you most
likely do not need both (and building both will extend your build time
unnecessarily). Alternatively, you might temporarily rename the ld
command, and try your build. When it can not find the ld command, you
might get a useful hint as to where the ld is invoked.
In my make file, the commands look like the following. The comment char
is a # at beginning of line. (The string expansions $(AR) and $(LD) allow
the use of non-standard utilities.)
@echo R10: $(TARGET_ARCHIVE) :from: $(OBJ)
$(AR) crs $(TARGET_ARCHIVE) $(OBJ)
# $(TARGET_OLB) : $(OBJ)
# @echo R00: $(TARGET_OLB) :from: $(OBJ)
# $(LD) -o $(TARGET_OLB) -r $(OBJ)
The archive (.a), when used, is linked directly to and included in your
executable. When the executable is loaded, all the referenced symbols of
the .a are already in it. (un-referenced symbols and code are not linked
The shared object (.so) is not directly linked, but rather your
executable gets a handle (or perhaps a file name) to the .so. It is my
belief that when your executable is loaded, the .so is not immediately
loaded. The .so does not load until the first time your executable
references a symbol that is in the .so. At that loading, your app will
experience a delay, but probably this late loading is reasonable for most
It is also possible that the .so is already loaded in system memory
before you activated your process. In that case, when your executable
first references a symbol in the .so, some system code will 'map' the
existing in-memory .so to your application -- probably faster than loading
it, but I suppose the big benefit is that a .so that is used / referenced
by many processes need only be loaded once, saving memory space. The
loaded .so has all of its symbols, even if your app does not need all of
In either case, your executable will be smaller with .so's, bigger with
.a's, but the .so's have some small performance hit for each .so that needs
to be loaded or mapped in. With 4 GB in my desktop, the desktop has never
felt 'crowded'. It's swap has never been used (afaik). So I generally use
NOTE: When the linker has access to both an archive (.a) and a shared
object (.so) file, the linker will use the .so (and ignore the .a).
Probably you can override that preference, but I have not tried. I find it
easier to simply move the archive (.a) into a separate (from the .so's)
directory, and inform the linker via the -L build option.