comando ar

Comando ar de Linux: úsalo para crear bibliotecas estáticas

El comando «ar» de Linux se usa para crear bibliotecas de funciones cuando desarrollas software. Este tutorial te mostrará cómo crear una biblioteca estática, modificarla y usarla en un programa, así como para completar con un código de muestra.

El comando ar es un verdadero veterano: existe desde 1971. El nombre hace rreferencia al uso original previsto para la herramienta, que era crear archivos de almacenamiento.

Un archivo de almacenamiento es un archivo único que actúa como contenedor de otros archivos. A veces para muchos otros archivos. Estos se pueden agregar, eliminar o extraer. Las personas que buscan ese tipo de funcionalidad ya no recurren al comando ar. Ese papel ha sido asumido por otras utilidades como el comando tar.

Sin embargo, el comando todavía se usa para algunos fines especializados. Se usa para crear bibliotecas estáticas. Estas bibliotecas se utilizan en el desarrollo de software. Y también se usa para crear archivos de paquetes como los archivos «.deb» usados ​​en la distribución Debian Linux y sus derivados como Ubuntu.

Vamos a seguir los pasos necesarios para crear y modificar una biblioteca estática, y demostrar cómo usar la biblioteca en un programa. Para hacer eso, necesitamos un requisito para que la biblioteca estática se cumpla. El propósito de esta biblioteca es codificar cadenas de texto y decodificar texto codificado.

Debes tener en cuenta que este es un truco rápido para fines de demostración. No uses este cifrado para nada que sea de valor. Es el cifrado de sustitución más simple del mundo, donde A se convierte en B, B se convierte en C, y así sucesivamente.

Las funciones cipher_encode () y cipher_decode ()

Vamos a trabajar en un directorio llamado «biblioteca», y luego crearemos un subdirectorio llamado «prueba».

Tenemos dos archivos en este directorio. En un archivo de texto llamado cipher_encode.c tenemos la función cipher_encode():

 void cipher_encode(char *text)
{
 for (int i=0; text[i] != 0x0; i++) {
   text[i]++;
 }

} // end of cipher_encode

La función cipher_decode() correspondiente está en un archivo de texto llamado cipher_decode.c:

void cipher_decode(char *text)
{
 for (int i=0; text[i] != 0x0; i++) {
   text[i]--;
 }

} // end of cipher_decode

Los archivos que contienen instrucciones de programación se denominan archivos de código fuente. Vamos a hacer un archivo de biblioteca llamado libcipher.a. Contendrá las versiones compiladas de estos dos archivos de código fuente.

También crearemos un archivo de texto corto llamado libcipher.h. Este es un archivo de encabezado que contiene las definiciones de las dos funciones en nuestra nueva biblioteca.

Cualquier persona con la biblioteca y el archivo de encabezado podrá usar las dos funciones en sus propios programas. No necesitas reinventar la rueda y reescribir las funciones; simplemente haces uso de las copias en nuestra biblioteca.

Compilación de los archivos cipher_encode.c y cipher_decode.c

Para compilar los archivos de código fuente, usaremos «gcc», el compilador estándar de GNU. La opción -c (compilar, sin enlace) le dice a gcc que compile los archivos y luego se detenga. Así que produce un archivo intermediario de cada archivo del código fuente, llamado archivo de objeto.

El vinculador gcc generalmente toma todos los archivos de objetos y los vincula para crear un programa ejecutable. Estamos omitiendo ese paso usando la opción -c. Por lo que necesitamos los archivos de objetos.

Verifiquemos que tenemos los archivos que creemos que tenemos.

ls -l

Los dos archivos de código fuente están presentes en este directorio. Usemos gcc para compilarlos en archivos de objetos.

gcc -c cipher_encode.c
gcc -c cipher_decode.c

No debería haber salida del gcc si todo va bien.

comando ar

Esto genera dos archivos de objeto con el mismo nombre que los archivos de código fuente, pero con extensiones «.o». Estos son los archivos que necesitamos agregar al archivo de la biblioteca.

ls -l

Creando la biblioteca libcipher.a

Para crear el archivo de la biblioteca, que en realidad es un archivo de almacenamiento, usaremos ar.

Estamos utilizando la opción -c (crear) para crear el archivo de la biblioteca, la opción -r (agregar con reemplazar) para agregar los mismos al archivo de la biblioteca. Y la opción -s (indexar) para crear un índice de los archivos dentro de la biblioteca.

Vamos a llamar al archivo de biblioteca libcipher.a. Proporcionamos ese nombre en la línea de comando, junto con los nombres de los archivos de objetos que vamos a agregarle.

ar -crs libcipher.a cipher_encode.o cipher_decode.o

Si enumeramos los archivos en el directorio, veremos que ahora tenemos un archivo libcipher.a.

ls -l

comando ar

Si usamos la opción -t (tabla) con el comando ar, podemos ver los módulos dentro del archivo de la biblioteca.

ar -t libcipher.a

Crear el archivo de encabezado libcipher.h

El archivo libcipher.h se incluirá en cualquier programa que use la biblioteca libcipher.a. El archivo libcipher.h debe contener la definición de las funciones que están en la biblioteca.

Para crear el archivo de encabezado, debemos escribir las definiciones de funciones en un editor de texto como gedit. Nombra el archivo como «libcipher.h» y guárdalo en el mismo directorio que el archivo libcipher.a.

void cipher_encode(char *text);
void cipher_decode(char *text);

Usando la biblioteca libcipher

La única forma segura de probar nuestra nueva biblioteca es escribir un pequeño programa para usarla. Primero, haremos un directorio llamado «test».

mkdir test

Copiaremos la biblioteca y los archivos de encabezado en el nuevo directorio.

cp libcipher.* ./test

Cambiaremos al nuevo directorio.

cd test

Vamos a ver si nuestros dos archivos están aquí.

ls -l

Necesitamos crear un pequeño programa que pueda usar la biblioteca y demostrar que funciona como se esperaba. Escribe las siguientes líneas de texto en un editor. Ahora, guarda el contenido del editor en un archivo llamado «test.c» en el directorio «test».

#include <stdio.h>
#include <stdlib.h>

#include "libcipher.h"

int main(int argc, char *argv[])
{
 char text[]="Amamos Linux";

 puts(text);

 cipher_encode(text);
 puts(text);

 cipher_decode(text);
 puts(text);

 exit (0);

} // end of main

El flujo del programa es muy simple:

  • Incluye el archivo libcipher.h para que pueda ver las definiciones de funciones de la biblioteca.
  • Crea una cadena llamada «texto» y almacena las palabras «Amamos Linux» en la misma.
  • Imprime esa cadena en la pantalla.
  • Llama a la función cipher_encode() para codificar la cadena e imprime la cadena codificada en la pantalla.
  • Llama cipher_decode() a decodificar la cadena e imprime la cadena decodificada en la pantalla.

Para generar el programa llamado test, necesitamos compilar el programa test.c y vincularlo en la biblioteca. La opción -o (salida) indica al gcc cómo llamar al programa ejecutable que genera.

gcc test.c libcipher.a -o test

Si gcc silenciosamente te devuelve al símbolo del sistema, todo está bien. Ahora probemos nuestro programa. Es el momento de la verdad:

./test

Y vemos la salida esperada. El programa test imprime el texto plano. También imprime el texto cifrado y luego imprime el texto descifrado. Y está utilizando las funciones dentro de nuestra nueva biblioteca. Así que nuestra biblioteca está funcionando.

comando ar

Tuvimos éxito. ¿Pero por qué parar allí?

Comando ar: Agregar otro módulo a la biblioteca

Agreguemos otra función a la biblioteca. Una función que el programador pueda usar para mostrar la versión de la biblioteca que está utilizando. Tendremos que crear la nueva función, compilarla y agregar el nuevo archivo de objeto al archivo de biblioteca existente.

Escribe las siguientes líneas en un editor. Guarda el contenido en un archivo llamado cipher_version.c, en el directorio de la biblioteca.

#include <stdio.h>

void cipher_version(void)
{
 puts("Este archivo es :: MUY INSEGURO Cipher Library");
 puts("Version 0.0.1 Alpha\n");

} // end of cipher_version

Necesitamos agregar la definición de la nueva función al archivo de encabezado libcipher.h. Agrega una nueva línea al final de ese archivo, para que se vea así:

void cipher_encode(char *text);
void cipher_decode(char *text);
void cipher_version(void);

Guarda el archivo modificado como «libcipher.h.»

Necesitamos compilar el archivo cipher_version.c para que tengamos un archivo de objeto cipher_version.o.

gcc -c cipher_version.c

Esto crea un archivo cipher_version.o. Podemos agregar el nuevo archivo de objeto a la biblioteca libcipher.a con el siguiente comando. La opción -v (detallada) hace que generalmente ar nos diga lo que ha hecho.

ar -rsv libcipher.a cipher_version.o

El nuevo archivo de objeto se agrega al archivo de biblioteca. el comando ar imprime la confirmación. La «a» significa «agregado».

Podemos usar la opción -t (tabla) para ver qué módulos están dentro del archivo de la biblioteca.

ar -t libcipher.a

Ahora hay tres módulos dentro de nuestro archivo de biblioteca. Hagamos uso de la nueva función que acabamos de hacer.

Usando la función cipher_version ()

Eliminemos la biblioteca y los archivos de encabezado antiguos del directorio «test», copiemos los archivos nuevos y luego volvamos al directorio test.

Eliminaremos las versiones anteriores de los archivos.

rm ./test/libcipher.*

Copiaremos las nuevas versiones en el directorio de prueba.

cp libcipher.* ./test

Ahora cambiaremos al directorio de prueba.

cd test

Y ahora podemos modificar el programa test.c para que use la nueva función de biblioteca.

Necesitamos agregar una nueva línea al programa test.c que llama a la función cipher_version(). Colocaremos esto antes de la primera línea puts(text);

#include <stdio.h>
#include <stdlib.h> 

#include "libcipher.h" 

int main(int argc, char *argv[]) 
{
 char text[]="How-To Geek loves Linux"; 

 // new line added here
 cipher_version(); 

 puts(text); 
 
 cipher_encode(text); 
 puts(text); 
 
 cipher_decode(text); 
 puts(text); 

 exit (0); 

} // end of main

Guarda este código como test.c. Ahora podemos compilarlo y probar que la nueva función está operativa.

gcc test.c libcipher.a -o test

Ahora, ejecutemos la nueva versión de test:

La nueva función está trabajando, así que podemos ver la versión de la biblioteca al comienzo de la salida de test. Pero puede haber un problema.

Comando ar: Sustitución de un módulo en la biblioteca

Esta no es la primera versión de la biblioteca; Es la segunda. Nuestro número de versión es incorrecto, debido a que la primera versión no tenía ninguna función cipher_version(). Este sí. Entonces esta debería ser la versión «0.0.2». Por lo que necesitamos reemplazar la función cipher_version() en la biblioteca haciendo correcciones.

Afortunadamente, el comando ar lo hace muy fácil.

Primero, editemos el archivo cipher_version.c en el directorio de la biblioteca. Cambia el texto «Versión 0.0.1 Alfa» a «Versión 0.0.2 Alfa». Debe tener un aspecto como este:

#include <stdio.h>

void cipher_version(void)
{
 puts("How-To Geek :: VERY INSECURE Cipher Library");  
 puts("Version 0.0.2 Alpha\n"); 

} // end of cipher_version

Guarda este archivo. Necesitamos compilarlo nuevamente para crear un nuevo archivo de objeto cipher_version.o.

gcc -c cipher_version.c

Ahora reemplazaremos el objeto cipher_version.o existente en la biblioteca con nuestra versión recién compilada.

Hemos usado la  opción -r (agregar con reemplazar) antes, para agregar nuevos módulos a la biblioteca. Cuando lo usamos con un módulo que ya existe, ar reemplaza la versión anterior por la nueva. La opción -s (índice) actualizará el índice de la biblioteca y la opción -v(detallada) hará que  ar nos diga qué ha hecho.

ar -rsv libcipher.a cipher_version.o

Esta vez ar informa que ha reemplazado el módulo cipher_version.o. La «r» significa «reemplazado».

Uso de la función actualizada cipher_version ()

Deberíamos usar nuestra biblioteca modificada y verificar que funciona. Así que copiaremos los archivos de la biblioteca al directorio de prueba.

cp libcipher.* ./test

Cambiaremos al directorio «test».

cd ./test

Necesitamos compilar nuestro programa «test» nuevamente con nuestra nueva biblioteca.

gcc test.c libcipher.a -o test

Y ahora podemos probar nuestro programa.

./test
comando ar

El resultado del programa test es lo que esperábamos. El número de versión correcto se muestra en la cadena de la versión y las rutinas de cifrado y descifrado están funcionando.

Comando ar: eliminar módulos de una biblioteca

Para hacer esto, usaremos la opción -d (eliminar). También usaremos la opción -v (detallada), para que ar nos diga lo que ha hecho. También incluiremos la opción -s (índice) para actualizar el índice en el archivo de la biblioteca.

ar -dsv libcipher.a cipher_version.o

El comando ar informa que ha eliminado el módulo. La «d» significa «eliminado». Si solicitamos a «ar» enumerar los módulos dentro del archivo de la biblioteca, veremos que hemos vuelto a los dos módulos.

ar -t libcipher.a

Si vas a eliminar módulos de tu biblioteca, recuerda eliminar tu definición del archivo de encabezado de la biblioteca.

¡Comparte tu código con el comando ar!

Las bibliotecas hacen que el código se pueda compartir de una manera práctica pero privada. Cualquiera a quien le des el archivo en cuestión y el archivo de encabezado, puede usar tu biblioteca, pero tu código fuente real permanece privado.


¿Tienes alguna pregunta o problema relacionado con el tema del artículo? Queremos ayudarte.

Deja un comentario con tu problema o pregunta. Leemos y respondemos todos los comentarios, aunque a veces podamos tardar un poco debido al volumen que recibimos. Además, si tu consulta inspira la escritura de un artículo, te notificaremos por email cuando lo publiquemos.
*Moderamos los comentarios para evitar spam.

¡Gracias por enriquecer nuestra comunidad con tu participación!

Deja un comentario