Production of static library libxxx.a and dynamic library libxxx.so

1. Static connection and dynamic connection

There are two types of links: static links and dynamic links .

1) Static linking

Static linking: The linker adds the contents of the library to the executable program at link time.

advantage:

  • Less dependence on the operating environment and better compatibility

shortcoming:

  • The generated program is larger, requires more system resources, and consumes more time when loading into memory.
  • The library function has been updated and the application must be recompiled

2) Dynamic link

Dynamic linking: The connector only establishes the link relationship with the required library functions when linking, and transfers the required resources into the executable program when the program is running.

advantage:

  • The corresponding resource function will be called when needed.
  • Simplifies program upgrades; has smaller program size
  • Realize resource sharing between processes (avoid repeated copies)

shortcoming:

  • Depends on dynamic library and cannot run independently
  • Dynamic library dependency version problem is serious

3) Comparison of static and dynamic compilation

        The application program we wrote earlier uses a large number of standard library functions. The system uses dynamic linking by default to compile the program. If you want to use static compilation, add the -static parameter.

The following is a comparison of files when dynamic compilation and static compilation are used:

The test program (test.c) is as follows:

#include <stdio.h>
​
int main(void)
{
    printf("hello world\n");
​
    return 0;
}

Compile:

deng@itcast:~/test$ gcc test.c -o test_share

deng@itcast:~/test$ gcc -static test.c -o test_static

Comparative Results:

2. Introduction to static libraries and dynamic libraries

        The so-called "program library", simply put, is a file containing data and execution code. It cannot be executed alone and can be used as part of other execution programs to complete certain functions.

        The existence of libraries can modularize programs, speed up program recompilation, enable code reuse, and make programs easy to upgrade.

Program libraries can be divided into static libraries and shared libraries .

3. Production and use of static libraries

        A static library can be thought of as a collection of target codes that have been added to the executable code before the executable program is run and become part of the executable program.

According to custom, ".a" is generally used as the file suffix. The naming of static libraries is generally divided into three parts:

  • Prefix: lib
  • Library name: You can define it yourself
  • Suffix: .a

So the final static library name should be: libxxx.a

1) Static library production

Step 1: Generate the c source file into the corresponding .o file

deng@itcast:~/test/3static_lib$ gcc -c add.c -o add.o
deng@itcast:~/test/3static_lib​$ gcc -c sub.c -o sub.o

deng@itcast:~/test/3static_lib​$ gcc -c mul.c -o mul.o

deng@itcast:~/test/3static_lib​$ gcc -c div.c -o div.o

Step 2: Use the packaging tool ar to package the prepared .o file into an .a file libtest.a

deng@itcast:~/test/3static_lib

$ ar -rcs libtest.a add.o sub.o mul.o div.o

When using the ar tool, you need to add parameters: rcs

  • rUpdate
  • cCreate
  • s index

2) Static library usage

After the static library is produced, the .a file and header file need to be released to users together.

Assume that the test file is main.c, the static library file is libtest.a, and the header file is head.h.

Compile command:

deng@itcast:~/test/4static_test$ gcc test.c -L./ -I./ -ltest -o test

Parameter Description:

  • -L: Indicates the directory where the library to be connected is located
  • -I./: I (capital i) indicates that the directory of the specified header file is the current directory
  • -l (lowercase L): Specify the library required for linking, remove the prefix and suffix

13. Production and use of dynamic libraries

        Shared libraries are not linked into the target code when the program is compiled, but are loaded when the program is run. If different applications call the same library, they only need to have one instance of the shared library in the memory, avoiding the problem of wasted space.

        The dynamic library is loaded when the program is running, which also solves the problem that the static library will cause trouble to the update, deployment and release page of the program. Users only need to update the dynamic library, incremental update.

According to custom, ".so" is generally used as the file suffix. The naming of shared libraries is generally divided into three parts:

  • Prefix: lib
  • Library name: You can define it yourself
  • Suffix: .so

So the final dynamic library name should be: libxxx.so

 1) Dynamic library production

Step 1: Generate the target file. At this time, add the compilation option: -fPIC (fpic)

deng@itcast:~/test/5share_lib$ gcc -fPIC -c add.c
deng@itcast:~/test/5share_lib​$ gcc -fPIC -c sub.c deng@itcast:~/test/5share_lib$ gcc -fPIC -c mul.c deng@itcast:~/test/5share_lib​$ gcc -fPIC -c div.c

Parameters: -fPIC creates a position independent code (pic, position independent code) that can be shared among multiple applications.

Step 2: Generate a shared library. At this time, add the linker option: -shared (specify to generate a dynamic link library)

deng@itcast:~/test/5share_lib$ gcc -shared add.o sub.o mul.o div.o -o libtest.so

Step 3: View the corresponding function through nm command

deng@itcast:~/test/5share_lib$ nm libtest.so | grep add 00000000000006b0 T add deng@itcast:~/test/5share_lib​$ nm libtest.so | grep sub 00000000000006c4 T sub

ldd checks the dynamic libraries that an executable file depends on

deng@itcast:~/share/3rd/2share_test$ ldd test linux-vdso.so.1 => (0x00007ffcf89d4000) libtest.so => /lib/libtest.so (0x00007f81b5612000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f81b5248000) /lib64/ld-linux-x86-64.so.2 (0x00005562d0cff000)

2) Dynamic library testing

Reference the dynamic library and compile it into an executable file (the same as the static library)

deng@itcast:~/test/6share_test$ gcc test.c -L. -I. -ltest (-I. uppercase i -ltest lowercase L)

Then run: ./a.out and find that an error is reported! ! !

  • When the system loads executable code, it can know the names of the libraries it depends on, but it also needs to know the absolute path. At this time, the system dynamic loader (dynamic linker/loader) is needed.
  • For elf format executable programs, it is completed by ld-linux.so*, which successively searches the DT_RPATH section of the elf file - environment variable LD_LIBRARY_PATH - /etc/ld.so.cache file list - /lib/, /usr /lib directory finds the library file and loads it into memory.

3) How to let the system find the dynamic library

the first method:

        Copy the shared library you made to /lib or /usr/lib (not the /lib64 directory)

cp libxxx.so  /url/lib

The second method:

        Temporarily set LD_LIBRARY_PATH

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH: library path

Third method:

        For permanent settings, set export LD_LIBRARY_PATH=$LD_LIBRARY_PATH: library path to ~/.bashrc or /etc/profile file

deng@itcast:~/share/3rd/2share_test$ vim ~/.bashrc

Add the following to the last line:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/deng/share/3rd/2share_test

(Enable environment variables to take effect)

deng@itcast:~/share/3rd/2share_test$ source ~/.bashrc deng@itcast:~/share/3rd/2share_test​$ ./test
a + b = 20 a - b = 10

Fourth method:

        Add this to the /etc/ld.so.conf file

Edit the /etc/ld.so.conf file and add the path to the directory where the library file is located.

deng@itcast:~/share/3rd/2share_test$ sudo vim /etc/ld.so.conf

Add the dynamic library path (absolute path) at the end of the file

Run sudo ldconfig -v, which will rebuild the /etc/ld.so.cache file

deng@itcast:~/share/3rd/2share_test$ sudo ldconfig 

The fifth method:

        Use symbolic links, but be sure to use absolute paths

deng@itcast:~/test/6share_test$ sudo ln -s /home/deng/test/6share_test/libtest.so /lib/libtest.so

Summarize: 

        Static linking compiles all dependent library functions directly into the final executable file, providing high independence and execution efficiency, but may result in large disk and memory usage, and updating library functions requires recompiling. Dynamic linking dynamically loads library functions when the program is running, which effectively saves storage space and facilitates the updating and sharing of library functions. However, it needs to ensure that the correct version of the library is in the appropriate location during runtime, and may affect execution efficiency.

Guess you like

Origin blog.csdn.net/crr411422/article/details/131406842