El archivador , también conocido simplemente como ar , es una utilidad de Unix que mantiene grupos de archivos como un único archivo de almacenamiento . En la actualidad, ar
se utiliza generalmente solo para crear y actualizar archivos de bibliotecas estáticas que utiliza el editor de enlaces o enlazador y para generar paquetes .deb para la familia Debian ; se puede utilizar para crear archivos para cualquier propósito, pero ha sido reemplazado en gran medida por tar
para otros fines que no sean bibliotecas estáticas. [3] Se incluye una implementación de ar
como una de las GNU Binutils . [2]
En la base estándar de Linux (LSB), ar
se ha dejado de usar y se espera que desaparezca en una versión futura de ese estándar. La justificación proporcionada fue que "LSB no incluye utilidades de desarrollo de software ni especifica los formatos de archivo .o y .a". [4]
El formato ar nunca ha sido estandarizado; los archivos modernos se basan en un formato común con dos variantes principales, BSD y System V (inicialmente conocido como COFF y utilizado también por GNU , ELF y Windows ).
Históricamente ha habido otras variantes [5], incluidas V6 , V7 , AIX (pequeña y grande) y Coherent, que varían significativamente del formato común. [6]
Los archivos ". deb " de Debian utilizan el formato común.
Un archivo ar comienza con un encabezado global , seguido de un encabezado y una sección de datos para cada archivo almacenado dentro del archivo ar.
Cada sección de datos está alineada con 2 bytes. Si termina en un desplazamiento impar, se utiliza una nueva línea ('\n', 0x0A) como relleno.
La firma del archivo es un campo único que contiene la cadena ASCII mágica "!<arch>"
seguida de un único carácter de control LF (0x0A).
Cada archivo almacenado en un archivo ar incluye un encabezado de archivo para almacenar información sobre el archivo. El formato común es el siguiente. Los valores numéricos se codifican en ASCII y todos los valores se rellenan a la derecha con espacios ASCII (0x20).
Como los encabezados solo incluyen caracteres ASCII imprimibles y saltos de línea, un archivo que contiene solo archivos de texto todavía parece ser un archivo de texto.
Los miembros están alineados con límites de bytes pares. "Cada miembro del archivo comienza en un límite de bytes pares; se inserta una nueva línea entre los archivos si es necesario. Sin embargo, el tamaño indicado refleja el tamaño real del archivo sin incluir el relleno". [7]
Debido a las limitaciones de la longitud y el formato de los nombres de archivo, tanto las variantes GNU como BSD idearon métodos diferentes para almacenar nombres de archivo largos. Aunque el formato común no sufre el problema del año 2038 , muchas implementaciones de la utilidad ar sí lo sufren y es posible que deban modificarse en el futuro para manejar correctamente las marcas de tiempo superiores a 2147483647. En libbfd se encuentra una descripción de estas extensiones. [8]
Dependiendo del formato, muchas implementaciones de ar incluyen una tabla de símbolos global (también conocida como armap, directorio o índice) para realizar enlaces rápidos sin necesidad de escanear todo el archivo en busca de un símbolo. POSIX reconoce esta característica y requiere que las implementaciones de ar tengan una -s
opción para actualizarla. La mayoría de las implementaciones la colocan en la primera entrada del archivo. [9]
BSD ar almacena los nombres de archivo rellenados con espacios ASCII a la derecha. Esto causa problemas con los espacios dentro de los nombres de archivo. 4.4BSD ar almacena los nombres de archivo extendidos colocando la cadena "#1/" seguida de la longitud del nombre de archivo en el campo de nombre de archivo y almacenando el nombre de archivo real delante de la sección de datos. [6]
La utilidad BSD ar tradicionalmente no maneja la construcción de una tabla de búsqueda de símbolos global y delega esta tarea a una utilidad separada llamada ranlib , [10] que inserta un archivo específico de la arquitectura llamado __.SYMDEF
como primer miembro del archivo. [11] Algunos descendientes ponen un espacio y "SORTED" después del nombre para indicar una versión ordenada. [12] Existe una variante de 64 bits llamada __.SYMDEF_64
en Darwin .
Sin embargo, desde que POSIX agregó el requisito de la -s
opción como reemplazo de ranlib, las implementaciones de ar de BSD más nuevas se han reescrito para tener esta característica. FreeBSD en particular abandonó el formato de tabla SYMDEF y adoptó el estilo de tabla de System V. [13]
System V ar utiliza un carácter '/' (0x2F) para marcar el final del nombre de archivo; esto permite el uso de espacios sin el uso de un nombre de archivo extendido. Luego almacena múltiples nombres de archivo extendidos en la sección de datos de un archivo con el nombre "//", este registro es mencionado por encabezados futuros. Un encabezado hace referencia a un nombre de archivo extendido almacenando un "/" seguido por un desplazamiento decimal al comienzo del nombre de archivo en la sección de datos del nombre de archivo extendido. El formato de este archivo "//" en sí es simplemente una lista de los nombres de archivo largos, cada uno separado por uno o más caracteres LF. Tenga en cuenta que los desplazamientos decimales son el número de caracteres, no el número de línea o cadena dentro del archivo "//". Esta suele ser la segunda entrada del archivo, después de la tabla de símbolos que siempre es la primera.
El sistema V ar utiliza el nombre de archivo especial "/" para indicar que la siguiente entrada de datos contiene una tabla de búsqueda de símbolos, que se utiliza en las bibliotecas ar para acelerar el acceso. Esta tabla de símbolos se construye en tres partes que se registran juntas como datos contiguos.
Algunos sistemas System V no utilizan el formato descrito anteriormente para la tabla de búsqueda de símbolos. En el caso de sistemas operativos como HP-UX 11.0, esta información se almacena en una estructura de datos basada en el formato de archivo SOM .
El archivo especial "/" no termina con una secuencia específica; el final se asume una vez que se ha leído el último nombre del símbolo.
Para superar el límite de tamaño de archivo de 4 GiB, algunos sistemas operativos como Solaris 11.2 y GNU utilizan una tabla de búsqueda de variantes. En lugar de números enteros de 32 bits, se utilizan números enteros de 64 bits en las tablas de búsqueda de símbolos. La cadena "/SYM64/" en lugar de "/" se utiliza como identificador para esta tabla [14]
La variante de Windows (PE/COFF) se basa en la variante SysV/GNU. La primera entrada "/" tiene el mismo diseño que la tabla de símbolos SysV/GNU. La segunda entrada es otra "/", una extensión de Microsoft que almacena una tabla de referencia cruzada de símbolos extendida. Esta está ordenada y utiliza números enteros little-endian. [5] [15] La tercera entrada es el dato de nombre largo opcional "//" como en SysV/GNU. [16]
La versión de ar
GNU binutils y Elfutils tiene un formato adicional de "archivo delgado" con el número mágico !<thin> . Un archivo delgado solo contiene una tabla de símbolos y referencias al archivo. El formato de archivo es esencialmente un archivo de formato System V donde cada archivo se almacena sin las secciones de datos. Cada nombre de archivo se almacena como un nombre de archivo "largo" y se deben resolver como si fueran enlaces simbólicos . [17]
Para crear un archivo a partir de los archivos class1.o , class2.o , class3.o , se utilizaría el siguiente comando:
ar rcs libclass.a clase1.o clase2.o clase3.o
Los enlazadores de Unix, generalmente invocados a través del compilador de Ccc
, pueden leer ar
archivos y extraer archivos de objetos de ellos, por lo que si libclass.a
es un archivo que contiene class1.o
, class2.o
y class3.o
, entonces
cc principal.c libclass.a
o (si libclass.a se ubica en la ruta de la biblioteca estándar, como /usr/local/lib )
cc main.c -lclass
o (durante la vinculación)
ld... main.o -lclass ...
es lo mismo que:
cc main.c clase1.o clase2.o clase3.o