200 likes | 422 Views
Bibliotecas. Nacen a partir de la necesidad de la compilación por módulos. Lo cual consiste en separar el programa principal de aquellas funciones que se utilizan frecuentemente en distintos programas.
E N D
Bibliotecas Nacen a partir de la necesidad de la compilación por módulos. Lo cual consiste en separar el programa principal de aquellas funciones que se utilizan frecuentemente en distintos programas. Con ello es posible desarrollar programas que utilizan aquellas funciones sin el esfuerzo adicional que provoca el incluir su código fuente una y otra vez. Una biblioteca es un archivo que contiene las funciones que un programa necesita. El formato de una biblioteca es comprendido por el linker. El linker selecciona sólo aquellas funciones que el programa necesita y excluye todas las demás.
Bibliotecas • La ejecución de un programa es desarrollada por una pieza de software que es esencial para el sistema operativo, en el caso de Linux es la llamada exec( ). • exec( ) tiene como tareas: • encontrar el archivo. • asignar memoria al proceso. • cargar partes del archivo relacionadas con el código y valores iniciales de las variables. • transferir el control a la CPU hacia un punto en el código del proceso que es indicado en el ejecutable.
Bibliotecas Tipos de bibliotecas existen las bibliotecas estáticas y compartidas Generalmente se ubican en /usr/lib, si no es necesario modificar la variable de entorno LD_LIBRARY_PATH Estáticas corresponde a una colección de código objeto almacenada en un archivo cuyo nombre termina en .a En el proceso de linkeo se buscan los módulos que el programa necesita y se incluyen en la generación del programa ejecutable. En el caso de Linux el linker es ld, no es invocado directamente por los usuarios sino que mediante gcc.
Bibliotecas Para crear una biblioteca estática: Se compilan y genera el código objeto para todos los archivos que se desean incluir. gcc -c util.c util1.c util2.c Luego se genera la biblioteca con el comando ar ar rc libutil.a util.o util1.o util2.o Finalmente se “indexa” la biblioteca ranlib libutil.a Si un programa utiliza algunas funciones de la biblioteca, las incluye en su programa fuente y luego en el proceso de compilación se debe hacer una referencia explicita a la biblioteca que las contiene: gcc programa.c –o programa –L. -lutil
Bibliotecas Compartidas una biblioteca compartida es linkeada en un programa en 2 pasos. Primero, durante la fase de compilación el linker verifica que todos los símbolos requeridos por el programa (funciones, variables, etc) se encuentran en él o bien en una biblioteca compartida. Sin embargo el código objeto (de la biblioteca) no se incluye en la generación del programa ejecutable. Posteriormente, durante la ejecución del programa se realiza el linkeo mediante un programa especial (/lib/ld-linux.so ó /lib/ld.so) Una biblioteca compartida se carga completamente en memoria. Si se ejecuta un segundo programa linkeado a la misma biblioteca, se utiliza la ya existente en memoria. Con esto los programas ejecutables son mas pequeños y además se reduce la utilización de memoria durante su ejecución.
Bibliotecas Para crear una biblioteca compartida: gcc –c util.c –fPIC La opcion fPIC se utiliza para indicar que la dirección de memoria en donde se carga la biblioteca es independiente del programa que la carga. gcc –shared –olibutil.so util.o con esto se crea la biblioteca util como compartida. Luego, cuando un programa necesita de las funciones presentes en la biblioteca se debe compilar de la sgte manera: gcc programa.c –L. –lutil Se utiliza –L. para indicar que la biblioteca se encuentra en el directorio actual, ya que por defecto se ubican en /usr/lib/
Bibliotecas Para localizar una biblioteca fuera de /usr/lib/ se debe modificar la variable de entorno LD_LIBRARY_PATH. $ LD_LIBRARY_PATH=$HOME/sources/lib/ $ export LD_LIBRARY_PATH Para verificar que un programa no tendra problemas en la carga de la biblioteca compartida se puede usar $ lddnombre_programa
Bibliotecas En algunos casos se utiliza de manera idéntica los términos compartida y dinámica. En este caso el dinamismo se refiere al proceso de linkeo que se realiza en tiempo de ejecución. Otra cosa muy distinta es utilizar una biblioteca compartida en forma dinámica. En este caso se carga la biblioteca, se utilizan algunas funciones y cuando ya no se necesitan se “borra” de la memoria. Un caso en el cual se justifica puede ser el siguiente: Supongamos el caso en el cual un programa debe estar preparado para leer archivos creados en diferentes formatos. Por ejemplo xv, no es muy frecuente visualizar decenas de imágenes de distintos formatos al mismo tiempo. Lo mejor sería escribir una biblioteca para cada formato de imagen y cargarla cuando sea necesario. Luego que una imagen ya no desea ser visualizada la biblioteca se “borra” de la memoria.
Bibliotecas #include <stdio.h> #include <dlfcn.h> int main(int argc, char **argv) { void *handle; double (*cosine)(double); char *error; handle = dlopen ("libm.so", RTLD_LAZY); if (!handle) { fprintf (stderr, "%s\n", dlerror()); exit(1); } cosine = dlsym(handle, "cos"); if ((error = dlerror()) != NULL) { fprintf (stderr, "%s\n", error); exit(1); } printf ("%f\n", (*cosine)(2.0)); dlclose(handle); return 0; }
make Es un programa que diseñado para determinar automáticamente cuales piezas de un software necesitan ser recompiladas. Generalmente un archivo llamado makefile contiene las dependencias entre las piezas del software y los comandos para la actualización. Es posible usar make con cualquier lenguaje de programación cuyo compilador pueda ser ejecutado desde un shell. Una version popular corresponde a GNU make.
make En el proceso de compilación existen 3 etapas: Luego de tomar el codigo fuente y llevarlo a un lenguaje de bajo nivel (.s) se genera un código objeto (.o), el cual es posteriormente enlazado con algunas bibliotecas que contienen funciones (por ej: printf) www.eng.hawaii.edu/Tutor/Make/
make Tambien existe la posibilidad de generar un programa ejecutable a partir de varios archivos fuente.
make En el caso anterior la compilación no es separada, en este caso la creación del programa ejecutable se realiza mediante compilación independiente. Ahora las piezas resultantes (.o) se fusionan mediante el linkeo.
make Un concepto clave en make es la dependencia. Por ejemplo, para crear main.o se depende de data.h, main.c e io.h
make La habilidad de make está en evitar un proceso completo de compilación cuando solo una pieza del software ha cambiado. En este caso para una modificación en io.c resulta razonable $ cc –c io.c $ cc –oproject1 data.o main.o io.o
make El grafo de dependencias existente para la creación de un programa se especifica en un archivo llamado makefile En un makefile se incluyen los comandos necesarios para la compilación y el linkeo.
make La estructura de un makefile se compone básicamente de: target: archivo(s) fuente comando para la compilación La línea asociada al comando debe ir precedida de un tab.
make También es posible definir macros: OBJECTS = data.o main.o io.o Luego, para hacer referencia al contenido de la macro se utiliza $(OBJECTS) Una macro es útil los flags de compilación. FLAGS= -g -DDEBUG Es importante destacar que make puede ejecutar cualquier comando que se ejecute desde un shell. Asi es posible tener algo como: clean: rm *.o