Object-Oriented Programming

Libraries

Michael L. Collard, Ph.D.

Department of Computer Science, The University of Akron

Common Educational Experience

Student writes all the code for an executable program. The only other code used is in standard libraries, which is automatically taken care of for you.

  • On a large program, very rarely will one developer write all the code
  • Even if you write the core functionality, your program must adapt to the executable environment and must consider command-line options, multiple input formats, multiple output formats, etc.
  • Most programs use libraries besides that of the standard libraries
  • Most of the libraries used are not header-file only
  • For most libraries, you may not have access to the source, or if you do cannot change it
  • Must understand how libraries work

Compile

  • Compiles a single source file to object code
  • Default output filename
  • Optimization levels, -O1, -O2, -O3, where higher is faster code
  • Also have to compile incr.cpp

Link

  • Creates the executable program incr
  • All of our source code (in object form) is in the executable
  • If we want to use the increment.cpp code in another executable, it would be duplicated
  • Becomes complicated if there is more than one source-code file that our main program (incr) wants to use, e.g., suppose a decrement.cpp

Static Library

  • A static library contains the object code of (potentially) multiple source files
  • Existing object code is added to the library
  • Static libraries have the extension ".a"
  • The name of a static library is prefixed with lib
  • Use the ar command man ar to create and view static libraries

Link to Static Library

  • The object code for increment.cpp is now in the static library libincrement.a
  • The -L option tells the compiler where the static library files are. In this case, the current directory
  • The -l option tells the compiler to link in the object code from the static library, where the prefix lib of the library name libincrement.a is assumed

Executable with Static Library

  •  
  • At this point, we can run the program without the static library, as all of our code is in the executable
  • If we delete the library or change the increment.cpp and recompile, it does not affect our executable incr
  • Updates to functions used that come from a static library require the executable to be relinked

Shared Library

  • A shared library contains the object code of (potentially) multiple source files
  • Difference of a shared library with a static library is that the object code is not linked into the executable, but shared at run time
  • One difference between object code in a shared library is that it must contain PIC (Position Independent Code) achieved via the option -fPIC
  • The option -shared makes it a shared library
  • Shared libraries on Linux have a .so extension (short for shared object)
  • Shared libraries on macOS have a .dylib extension (short for dynamic library)

Link to Shared Library

  • The -L option tells the compiler where the shared library files are. In this case, the current directory
  • The -l option tells the compiler to link in the object code from the shared library, where the prefix lib of the library name libincrement.so is assumed
  • The object code is for increment() is not in the executable incr. However, the executable incr knows how to call the function

Executable with Shared Library

  • At this point, when we run the program, we get an error
  • The problem is that the executable, incr, cannot find the shared library and needs the object code for increment()

Viewing Shared Libraries

  • To view the use of shared libraries, use the ldd command on Linux and the otool -L command on macOS
  • May have to use sudo in front of the ldd command
  • Note that libincrement is "not found"

Temporary Fix for Executable with Shared Library

  • We need to tell the executable where to find the shared library
  • The path variable LD_LIBRARY_PATH is a temporary way of doing this
  • Here, we indicate to search in the current directory

Install Shared Library

  • To install, copy the shared library to a known library directory
  • Typically, this is something like /usr/local/lib
  • May have to use sudo for the cp command due to the destination location
  • Just copying the library is not enough, as the list of libraries is cached by the o.s.
  • The command ldconfig man ldconfig updates this cache
  • Note what the ldd command now shows
  • Install programs often do this as part of the installation process

Advantages of Shared Libraries

  • When we update a shared library and rerun the program, we get the new behavior
  • All executables share the same library, leading to smaller executable programs
  • Easier to update as we install a new shared library, restart the computer, and all executables are using the new library
  • Updating a shared library does not require the programs to be relinked

SONAMES

  • sonames are names embedded in a shared library that indicate a particular version
  • The name of the shared library is now libincrement.so.1.0.0
  • semantic versioning is in the form MAJOR.MINOR.PATCH
  • PATCH when you make backwards-compatible bug fixes
  • MINOR when you add functionality in a backwards-compatible manner
  • MAJOR when you make incompatible API changes
  • The option -Wl forwards options to the linker
  • The linker option -soname,libincrement.so.1 sets the soname field of the shared library to libincrement.so.1
  • ldconfig generates the appropriate symbolic link

Packaging

  • Three packages, libincrement1 the library, incr the application, and libincrement1-dev the development package
  • The libincrement1-dev adds the symbolic link for libincrement1.so to get the latest version during development
  • The libincrement1-dev also adds the static library
  • Both packages incr and libincrement1-dev depend on the package libincrement1