Library - krishnaramb/cplusplus GitHub Wiki

Why libraries are used

  • Libraries employ a software design also known as "shared components" or "archive libraries", which groups together multiple compiled object code files into a single file known as a library πŸ’–πŸ’—
  • Typically C functions/C++ classes and methods which can be shared by more than one application are broken out of the application's source code, compiled and bundled into a library.
  • The C standard libraries and C++ STL are examples of shared components which can be linked with your code
  • The benefit is that each and every object file need not be stated when linking because the developer can reference the library collective πŸ’žπŸŒΊπŸŒΉ
  • Benefits include: Component reuse: update one library, shared resource takes up less disk space.

Linux Library Types:

  • There are two Linux C/C++ library types which can be created:

    • Static libraries (.a): Library of object code which is linked with, and becomes part of the application.
    • Dynamically linked shared object libraries (.so): There is only one form of this library but it can be used in two ways.
      • Dynamically linked at run time. The libraries must be available during compile/link phase. The shared objects are not included into the executable component but are tied to the execution.
      • Dynamically loaded/unloaded and linked during execution (i.e. browser plug-in) using the dynamic linking loader system functions

Library naming conventions:

  • Libraries are typically named with the prefix "lib"πŸ’˜. This is true for all the C standard libraries.
  • When linking, the command line reference to the library will not contain the library prefix or suffixπŸŒΊπŸ’žπŸ’˜
  • Consider the following compile and link command:
    gcc src-file.c -lm -lpthread
    
  • The libraries referenced in this example for inclusion during linking are the math library ("m") and the thread library ("pthread"). They are found in /usr/lib/libm.a and /usr/lib/libpthread.a.
  • The GNU compiler now has the command line option -pthread while older versions of the compiler specify the pthread library explicitly with "-lpthread". Thus now you are more likely to see gcc src-file.c -lm -pthread

Static Libraries(.a): How to generate a static library (object code archive file):

  • Compile: cc -Wall -c ctest1.c ctest2.c
  • Compiler options:
    • -Wall: include warnings. See man page for warnings specified.
  • Create library "libctest.a":ar -cvq libctest.a ctest1.o ctest2.o
  • List files in library: ar -t libctest.a
  • Linking with the library:
    • cc -o executable-name prog.c libctest.a
    • cc -o executable-name prog.c -L/path/to/library-directory -lctest
  • Linking our Obj file with the library πŸŒΊπŸ€πŸŒΉπŸ’–πŸ’˜
    TARGETS=source
    OBJ = us_xfr_sv.o
    $(TARGETS): $(OBJ)
        $(CC_C)  -o $(TARGETS) $^ -L/home/krishna/security_git/security/tlpi-book -ltlpi
    

More about compiler and linker ref

  • The GNU C and C++ compiler are called gcc and g++, respectively.
  • gcc hello.c compiles and links source file hello.c into executable a.exe (Windows) or a (Unixes)
  • The default output executable is called "a.exe" (Windows) or "a.out" (Unixes and Mac OS X).
  • To specify the output filename, use -o option: eg. gcc -o hello hello.c 🌹
  • In Unixes, we typically omit the .exe file extension (meant for Windows only), and simply name the output executable as hello (via command "gcc -o hello hello.c".
  • More GCC Compiler Options
    • -o: specifies the output executable filename.
    • -Wall: prints "all" Warning messages.
    • -g: generates additional symbolic debuggging information for use with gdb debugger

Compile and Link Separately

  • The command gcc hello.c compiles the source file into object file and link with other object files and system libraries into executable in one step. You may separate compile and link in two steps as follows:
  • Compile-only with -c option: g++ -c -Wall -g Hello.cpp
  • Link object file(s) into an executable: g++ -g -o Hello Hello.o
  • -c: Compile into object file "Hello.o". By default, the object file has the same name as the source file with extension of ".o" (there is no need to specify -o option). No linking with other object files or libraries.
  • Linking is performed when the input file are object files ".o":palm_tree: (instead of source file ".cpp" or ".c"). GCC uses a separate linker program to perform the linking.

Compile and Link Multiple Source Files

  • Suppose that your program has two source files: file1.cpp, file2.cpp. You could compile all of them in a single command as
    g++ -o myprog.exe file1.cpp file2.cpp
    
  • However, we usually compile each of the source files separately into object file, and link them together in the later stage.🌸🌿 In this case, changes in one file does not require re-compilation of the other files.
    > g++ -c file1.cpp
    > g++ -c file2.cpp
    > g++ -o myprog file1.o file2.o
    

Searching for Header Files and Libraries (-I, -L and -l)

  • When compiling the program, the compiler needs the header files to compile the source codes ❀️
  • The linker needs the libraries to resolve external references from other object files or libraries
  • The compiler and linker will not find the headers/libraries unless you set the appropriate options, which is not obvious for first-time user
  • For each of the headers used in your source (via #include directives), the compiler searches the so-called include-paths for these headers
  • The include-paths are specified via -Idir option πŸŒΊπŸ’˜ (or environment variable CPATH).eg
    #here we are generting obj file for main program
    #For userdefined user file, we need to provide the include path of this headers using -I<dir> options
    TARGETS=source
    DEPS = us_xfr.h
    OBJ = us_xfr_sv.o
    CGFLAGS = -Wall -Werror -g -std=c99
    
    $(OBJ): us_xfr_sv.c $(DEPS)
        $(CC_C) $(CFLAGS) -c $< -I/home/krishna/security_git/security/tlpi-book/lib
    
  • Since the header's filename is known (e.g., iostream.h, stdio.h), the compiler only needs the directories πŸ’žπŸ”₯
  • The linker searches the so-called library-paths for libraries needed to link the program into an executable.
  • The library-path is specified via -Ldir option(uppercase 'L' followed by the directory path) (or environment variable LIBRARY_PATH) and in addition, you also have to specify the library nameπŸ‘ŠπŸ‘
  • In Unixes, the library libxxx.a is specified via -lxxx option (lowercase letter 'l', without the prefix "lib" and ".a" extension).πŸ”₯πŸ‘ŠπŸ’₯
  • The linker needs to know both the directories as well as the library names. Hence, two options need to be specified.πŸŒΊπŸ’ž
TARGETS=source
DEPS = us_xfr.h
OBJ = us_xfr_sv.o
CROSS_TOOL =
CC_CPP = $(CROSS_TOOL)g++
CC_C = $(CROSS_TOOL)gcc

CGFLAGS = -Wall -Werror -g -std=c99

#This is the linker where all the obj files and libraries are linked to create executable.
#static library (.a) or dynamic library (.so) files are the collections of obj files of the library
#The linker need to have directory -L<dir> and name of library -l<libraryname>.
# library-file has the name starting with lib and with .a or .so extension.
#In linker with -l option, we only give name of the file without lib and .a as in below where libtlpi.a is the library name
$(TARGETS): $(OBJ)
    $(CC_C)  -o $(TARGETS) $^ -L/home/krishna/security_git/security/tlpi-book -ltlpi

#here we are generting obj file for main program
#For userdefined user file, we need to provide the include path of this headers using -I<dir> options
$(OBJ): us_xfr_sv.c $(DEPS)
    $(CC_C) $(CFLAGS) -c $< -I/home/krishna/security_git/security/tlpi-book/lib


clean:
    rm -f $(TARGETS)
    rm -f *.o

extra notes(troubleshooting)

⚠️ **GitHub.com Fallback** ⚠️