Static libraries and shared libraries in Linux

One, the concept of the library

The library is a binary file that contains code that can be called by the program. For example, standard C library, math library, thread library, etc. The library has source code, which can be downloaded and compiled, or the binary package can be installed directly.
A library is a pre-compiled code that can be reused. Basically, all programs running on the OS use the library. Using libraries can improve development efficiency.
The format of library files under Windows and Linux is not compatible.
Linux contains static libraries and shared libraries.

Two, static library

2.1 Features of static libraries
  • Copy the relevant code in the static library to the executable file when compiling (linking)
  • The program contains code, no static library is needed at runtime
  • No need to load the library when the program is running, running faster
  • Take up more disk and space
  • After the static library is upgraded, the program needs to be recompiled and linked
2.2 Creation and linking of static libraries

Step 1: Determine the function and interface of the function in the library

Step 2: Write library source code

/****hello.c****/
#include <stdio.h>
#include "hello.h"

void hello(void){
    
    
	printf("hello Andyxi\n");
}
/****hello.h****/
#ifndef _HELLO_H_
#define _HELLO_H_

void hello(void);

#endif

Step 3: Compile and generate object files

linux@linux:~/andy/lib$ ls
hello.c  hello.h
linux@linux:~/andy/lib$ gcc -c hello.c -Wall
linux@linux:~/andy/lib$ ls
hello.c  hello.h  hello.o

Step 4: Create a static library

linux@linux:~/andy/lib$ ls
hello.c  hello.h  hello.o
linux@linux:~/andy/lib$ ar crs libhello.a hello.o  //使用 ar crs 命令创建静态库
linux@linux:~/andy/lib$ ls
hello.c  hello.h  hello.o  libhello.a	//注意libhello.a是库文件名,hello是库名
linux@linux:~/andy/lib$ nm libhello.a	//使用 nm 命令可查看库中符号信息

hello.o:
00000000 T hello
         U puts

Step 5: Write the application

/****test.c****/
#include <stdio.h>
#include "hello.h"

int main(int argc, const char *argv[]){
    
    
	hello();
	return 0;
}

Step 6: Compile the application and link the static library

linux@linux:~/andy/lib$ ls
hello.c  hello.h  hello.o  libhello.a  test.c
linux@linux:~/andy/lib$ gcc -o test test.c -L. -lhello //使用-L. -l+库名 链接静态库
linux@linux:~/andy/lib$ ls
hello.c  hello.h  hello.o  libhello.a  test  test.c
linux@linux:~/andy/lib$ ./test
hello Andyxi

Because it is a static library, the relevant code has been copied to the executable file after compilation. Delete static library without affecting program execution

linux@linux:~/andy/lib$ ls
hello.c  hello.h  hello.o  libhello.a  test  test.c
linux@linux:~/andy/lib$ rm libhello.a 
linux@linux:~/andy/lib$ ls
hello.c  hello.h  hello.o  test  test.c
linux@linux:~/andy/lib$ ./test 
hello Andyxi

Three, shared library

3.1 Features of shared libraries
  • Only record which symbol in which shared library is used when compiling (linking), and does not copy related code in shared library
  • The program does not contain the code in the library, and the size is small
  • Multiple programs can share a library
  • The library needs to be loaded when the program is running
  • Easy library upgrade, no need to recompile the program
  • More widely used
3.2 Creation and linking of shared libraries

Step 1: Determine the function and interface of the function in the library

Step 2: Write library source code

/****hello.c****/
#include <stdio.h>

void hello(void){
    
    
	printf("hello world\n");
	return ;
}
/****bye.c****/
#include <stdio.h>

void bye(void){
    
    
	printf("bye!\n");
	return ;
}
/****共享库头文件common.h****/
#ifndef __COMMON_H__
#define __COMMON_H__

void hello(void);
void bye(void);

#endif

Step 3: Compile and generate object files

linux@linux:~/andy/lib/share$ ls
bye.c  common.h  hello.c
linux@linux:~/andy/lib/share$ gcc -c -fPIC *.c -Wall
linux@linux:~/andy/lib/share$ ls
bye.c  bye.o  common.h  hello.c  hello.o
  • fPIC option: tell the compiler to generate position-independent code
  • Position-independent code: The code in the generated ".o file" file can be loaded to any address for execution. Relative addressing is used instead of absolute addressing when compiling

Step 4: Create a shared library common

linux@linux:~/andy/lib/share$ gcc -shared -o libcommon.so.1 hello.o bye.o
linux@linux:~/andy/lib/share$ ls
bye.c  bye.o  common.h  hello.c  hello.o  libcommon.so.1
  • shared option: tell the compiler to generate a shared library
  • The file name of the generated shared library is "libcommon.so.1", where ".so" indicates that this is a shared library, and ".1" indicates that the version of the library is 1.
  • Symbolic link file naming rules: lib<library name>.so

Step 5: Write the application

/****test.c****/
#include <stdio.h>
#include "common.h"

int main(int argc, const char *argv[]){
    
    
	hello();
	bye();

	return 0;
}

Step 6: Compile the application and link the shared library

/****为共享库文件创建链接文件****/
linux@linux:~/andy/lib/share$ ls
bye.c  bye.o  common.h  hello.c  hello.o  libcommon.so.1  test.c
linux@linux:~/andy/lib/share$ ln -s libcommon.so.1 libcommon.so	//ln -s创建符号链接
linux@linux:~/andy/lib/share$ ls
bye.c  bye.o  common.h  hello.c  hello.o  libcommon.so  libcommon.so.1  test.c
/****编译应用程序并链接共享库****/
linux@linux:~/andy/lib/share$ gcc -o test test.c -L. -lcommon
linux@linux-:~/andy/lib/share$ ls
bye.c  bye.o  common.h  hello.c  hello.o  libcommon.so  libcommon.so.1  test  test.c
  • gcc -o test test.c -L. -lcommon: It can be found that the shared library and static library are used in the same way; GCC first looks for the shared library when linking, if the shared library does not exist, link the static library, if the static library is also found If not, an error will be reported; after adding the "-static" option, the compiler will directly find the static library.
3.3 Loading of shared libraries

When the program is executed at this time, an error will be reported

linux@linux:~/andy/lib/share$ ./test
./test: error while loading shared libraries: libcommon.so: cannot open shared object file: No such file or directory
  • The reason for the error during execution: Because the program is linked to a shared library, and the code in the shared library is not copied, the program will also load the shared library when it is executed, and go back to the default path (such as "/lib" ","/usr/lib") Go down to find the shared library, but the library we created is in the current directory, not in the search path of the system library, so an error will be reported if the shared library is not found during execution;
  • Therefore, after creating the shared library, you need to add the shared library load path

Step 7: Load the shared library and execute the program

linux@linux:~/andy/lib/share$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
linux@linux:~/andy/lib/share$ ./test
hello world
bye!
  • export: Export the original environment variables
  • ":"Before"$LD_LIBRARY_PATH" refers to the original value; ":"behind"." is to append the current directory; you can also append the paths of other shared libraries, separated by ":"
  • This method is temporary and only valid for the current terminal. When reopening a terminal and executing the modified program again, an error will be reported
3.4 How to find shared libraries

In order for the system to find the shared library to be loaded, there are usually three methods:

  • Copy the library to the /usr/lib and /lib directories
  • Add the path of the library in the LD_LIBRARY_PATH environment variable
  • Add /etc/ld.so.conf.d/*.conf file, execute ldconfig refresh

Guess you like

Origin blog.csdn.net/Chuangke_Andy/article/details/108264126