prefacio
contenido
1. ¿Por qué hay una biblioteca? 2.
Biblioteca estática 2.1 Generar un archivo .c
en un archivo .o con el mismo nombre
-
Biblioteca estática (.a): el programa copia el código binario de la biblioteca en el archivo ejecutable de mi programa cuando el programa se compila y vincula, y la biblioteca estática ya no es necesaria cuando se ejecuta el programa
-
Biblioteca dinámica (.so): el código de la biblioteca dinámica solo se vincula cuando el programa se está ejecutando y el código de la biblioteca es compartido por varios programas
Como la biblioteca de lenguaje c:
- Biblioteca dinámica libc.so
- biblioteca estática libc.a
La regla de nomenclatura de la biblioteca es: encabezado lib + nombre de la biblioteca + sufijo elimine el prefijo lib, elimine el sufijo ., y el resto es el nombre de la biblioteca
Hay dos formas de generar programas ejecutables: enlace dinámico y enlace estático
ldd filename # 查看链接方式
1. ¿Por qué hay una biblioteca?
Al desarrollar, a menudo usamos código escrito por otros, incluida la compilación del código fuente de otras personas, llamando a bibliotecas de terceros proporcionadas por otros, llamando a interfaces de funciones de red proporcionadas por otros...
¿Por qué deberíamos usar el código de otra persona?
- Mejorar la eficiencia del desarrollo
- Aumentar la solidez del programa
La llamada robustez se refiere a la robustez del programa, y el acoplamiento entre cada módulo es bajo. Para bibliotecas de terceros, creemos que no hay problema. Si hay un error en mi programa, entonces no hay necesidad de sospechar que hay un problema con la biblioteca llamada en sí, pero debe haber un problema con la lógica del código escrito por mí mismo, lo que reduce el alcance del error a ser comprobado. Por supuesto, la biblioteca aquí debe hacer referencia a algunas bibliotecas autorizadas, como bibliotecas estándar como STL.
Bueno, como usar el código de otras personas, es muy importante aprender a empaquetar y usar la biblioteca.
2. Biblioteca estática
Para este experimento, tenemos 5 archivos originales:
add.h
add.c
sub.h
sub.c
main.c
#pragma once
#include <stdio.h>
int add(int x, int y);
#include "add.h"
int add(int x, int y) {
return x+y;
}
#pragma once
#include <stdio.h>
int sub(int x, int y);
#include "sub.h"
int sub(int x, int y) {
return x-y;
}
#include <stdio.h>
#include "add.h"
#include "sub.h"
int main() {
printf("%d\n%d\n", add(20, 10), sub(20, 10));
return 0;
}
2.1 Genere el archivo .c en un archivo .o con el mismo nombre
Llamar a la biblioteca estática se refiere a vincular el código binario de la biblioteca estática en el archivo ejecutable cuando el programa está vinculado, de modo que no es necesario encontrar la biblioteca estática cuando se ejecuta.
Bueno, dado que la biblioteca estática está vinculada al archivo ejecutable en el paso de vinculación, entonces de acuerdo con
Preprocesamiento - Compilar - Ensamblar - Vincular
Necesitamos completar el paso de ensamblaje. El ensamblaje consiste en convertir el código de ensamblaje en código de máquina, y el archivo generado es un .o
archivo.
gcc -c add.c
gcc -c sub.c
2.2 Hacer una biblioteca estática
La esencia de hacer una biblioteca estática es empaquetar varios archivos .o
ar -ac libmymath.a add.o sub.o
Use ar -tv para ver los archivos incluidos en la biblioteca estática:
2.3 Uso de bibliotecas estáticas
Metemos los tres archivos add.o sub.o libmymath.a en la carpeta slib
1. Utilice -I
el directorio del archivo de encabezado para traerlo al compilar y vincular main.c
gcc main.c -o main -I ./slib/
parece que falta algo
2. Use -L
para traer el directorio donde se encuentra el archivo de la biblioteca
gcc main.c -o main -I ./slib/ -L ./slib/
parece que falta algo
3. Use -l
el nombre de la biblioteca (la parte entre lib y . sufijo)
gcc main.c -o main -I ./slib/ -L ./slib/ -lmymath
En este punto, el ejecutable se genera con éxito:
correr:
3. Biblioteca dinámica
-
Un archivo ejecutable vinculado con una biblioteca dinámica contiene solo una tabla de las direcciones de entrada de función que utiliza, no el código de máquina completo del archivo de objeto donde reside la función externa.
-
Antes de que el archivo ejecutable comience a ejecutarse, el sistema operativo copia el código de máquina de la función externa desde la biblioteca dinámica en el disco a la memoria, un proceso llamado vinculación dinámica.
-
Las bibliotecas dinámicas se pueden compartir entre varios programas, por lo que la vinculación dinámica hace que los archivos ejecutables sean más pequeños y ahorra espacio en disco. El sistema operativo utiliza un mecanismo de memoria virtual para permitir que todos los procesos que utilizan la biblioteca compartan una biblioteca dinámica en la memoria física, ahorrando memoria y espacio en disco.
3.1 Haciendo una biblioteca dinámica
1. Generar código independiente de la posición
Esta biblioteca dinámica en sí misma no se carga en ningún área de memoria asignada al área compartida, y cualquier ubicación afectará el cambio relativo de la dirección del código en la biblioteca, lo que dará como resultado que el código de biblioteca no ejecutable de la biblioteca se asigne a el área compartida, y cada proceso la usa. El mismo código, sin desperdicio de memoria
gcc -fPIC -c add.c sub.c
2. Generar archivos de biblioteca dinámicos
gcc -shared -o libmymath.so add.o sub.o
3.2 Generación de archivos ejecutables utilizando bibliotecas dinámicas
gcc main.c -o main -I dlib/ -L dlib/ -lmymath
3.3 Correr
La ejecución main
encontró un error, ¿qué pasó?
¿ No especificamos ya 编译
el directorio del archivo de encabezado, el directorio del archivo de la biblioteca, el nombre del archivo de la biblioteca cuando estuvimos allí?
Oh, se especificó al compilar, pero ahora está en la fase de ejecución. En la fase de ejecución, no se especifica dónde encontrar el archivo de la biblioteca. Por supuesto, no puedo encontrarlo.
3 soluciones:
- Copie nuestra
libmymath.so
copia en la ruta de la biblioteca compartida del sistema, generalmente/usr/lib64
o/usr/lib
- Agregue el directorio dlib a la variable de entorno LD_LIBRARY_PATH
Aquí hay una variable de entorno: LD_LIBRARY_PATH
, que almacena el directorio donde el sistema está predeterminado para encontrar archivos de biblioteca dinámica
Exportar variables de entorno:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/class101/linux/lesson18/dlib
- configuración de ldconfig
/etc/ld.so.conf.d
Cree un archivo .conf arbitrariamente en el directorio /etc/ld.so.conf.d y escriba el directorio de la biblioteca dinámica en el archivo .conf
echo "/root/class101/linux/lesson18/dlib" > /etc/ld.so.conf.d/test.conf
ldconfig
4. Algunos detalles
detalle uno
¿Por qué el lenguaje C nunca utiliza explícitamente opciones como -I -L -l al compilar?
1. Gcc encuentra los archivos de encabezado y de biblioteca en la ruta predeterminada 2. Cuando gcc
compila el código C, debe buscar libc de forma predeterminada
¿Y si tampoco queremos usar esas opciones?
Copie el archivo de la biblioteca del archivo de encabezado en la ruta predeterminada -> instalación de la biblioteca
detalle dos
enlace dinámico predeterminado de gcc, si no hay un enlace dinámico, vaya al enlace estático
Makefile
main: main.c
gcc -o $@ $^ -I ./dlib -L ./dlib -lmymath
.PHONY: clean
clean:
rm -f main