Como usar o comando ar do Linux para criar bibliotecas estáticas

Prompt do shell em um laptop Linux
Fatmawati Achmad Zaenuri / Shutterstock.com

Use o ar comando do Linux  para criar bibliotecas de funções ao desenvolver software. Este tutorial mostrará como criar uma biblioteca estática, modificá-la e usá-la em um programa, completo com código de amostra.

O arcomando é um verdadeiro veterano – existe desde 1971. O nome faz arreferência ao uso original pretendido para a ferramenta, que era criar arquivos compactados . Um arquivo morto é um único arquivo que atua como um contêiner para outros arquivos. Às vezes, para muitos outros arquivos. Os arquivos podem ser adicionados, removidos ou extraídos do arquivo. Pessoas que procuram esse tipo de funcionalidade não recorrem mais ar. Essa função foi assumida por outros utilitários, como tar.

O arcomando ainda é usado para alguns propósitos especializados, no entanto. aré usado para criar bibliotecas estáticas. Eles são usados ​​no desenvolvimento de software. E artambém pode ser usado para criar arquivos de pacote, como os arquivos “.deb” usados ​​na distribuição Debian Linux e seus derivados, como o Ubuntu.

Vamos percorrer as etapas necessárias para criar e modificar uma biblioteca estática e demonstrar como usar a biblioteca em um programa. Para fazer isso, precisamos de um requisito a ser cumprido pela biblioteca estática. O objetivo desta biblioteca é codificar strings de texto e decodificar texto codificado.

Observe que este é um hack rápido e sujo para fins de demonstração. Não use essa criptografia para nada de valor. É a cifra de substituição mais simples do mundo , em que A se torna B, B se torna C e assim por diante.

As funções cipher_encode () e cipher_decode ()

Estaremos trabalhando em um diretório chamado “biblioteca” e, posteriormente, criaremos um subdiretório chamado “teste”.

Temos dois arquivos neste diretório. Em um arquivo de texto chamado cipher_encode.c, temos a cipher_encode()função:

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

} // fim de cipher_encode

A cipher_decode()função correspondente está em um arquivo de texto chamado cipher_decode.c:

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

} // fim de cipher_decode

Os arquivos que contêm instruções de programação são chamados de arquivos de código-fonte. Vamos fazer um arquivo de biblioteca chamado libcipher.a. Ele conterá as versões compiladas desses dois arquivos de código-fonte. Também criaremos um arquivo de texto curto chamado libcipher.h. Este é um arquivo de cabeçalho contendo as definições das duas funções em nossa nova biblioteca.

Qualquer pessoa com a biblioteca e o arquivo de cabeçalho poderá usar as duas funções em seus próprios programas. Eles não precisam reinventar a roda e reescrever as funções; eles simplesmente fazem uso das cópias em nossa biblioteca.

Recomendado:  Como alterar a horrível cor de fundo roxo da janela 8

Compilar os arquivos cipher_encode.c e cipher_decode.c

Para compilar os arquivos do código-fonte, usaremos gcco compilador GNU padrão . A opção -c(compilar, sem link) diz gccpara compilar os arquivos e depois parar. Ele produz um arquivo intermediário a partir de cada arquivo de código-fonte denominado arquivo-objeto. O gccvinculador geralmente pega todos os arquivos-objeto e os vincula para formar um programa executável. Estamos pulando essa etapa usando a -copção. Precisamos apenas dos arquivos objeto.

Vamos verificar se temos os arquivos que achamos que temos.

ls -l

está em uma janela de terminal

Os dois arquivos de código-fonte estão presentes neste diretório. Vamos usá gcc-los para compilá-los em arquivos-objeto.

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

Não deve haver saída de gccse tudo correr bem.

saída do gcc em uma janela de terminal

Isso gera dois arquivos-objeto com o mesmo nome dos arquivos de código-fonte, mas com extensões “.o”. Esses são os arquivos que precisamos adicionar ao arquivo de biblioteca.

ls -l

saída de ls -l em uma janela de terminal

Criação da biblioteca libcipher.a

Para criar o arquivo de biblioteca – que na verdade é um arquivo morto – usaremos ar.

Estamos usando a -copção (criar) para criar o arquivo de biblioteca, a opção -r(adicionar com substituir) para adicionar os arquivos ao arquivo de biblioteca e a -sopção (índice) para criar um índice dos arquivos dentro do arquivo de biblioteca.

Vamos chamar o arquivo de biblioteca de libcipher.a. Fornecemos esse nome na linha de comando, junto com os nomes dos arquivos-objeto que iremos adicionar à biblioteca.

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

ar -crs libcipher.a cipher_encode.o cipher_decode.o em uma janela de terminal

Se listarmos os arquivos no diretório, veremos que agora temos um arquivo libcipher.a.

ls -l

saída de ls em uma janela de terminal

Se usarmos a -topção (tabela) com ar, podemos ver os módulos dentro do arquivo de biblioteca.

ar -t libcipher.a

ar -t libcipher.a em uma janela de terminal

Criação do arquivo de cabeçalho libcipher.h

O arquivo libcipher.h será incluído em qualquer programa que use a biblioteca libcipher.a. O arquivo libcipher.h deve conter a definição das funções que estão na biblioteca.

Para criar o arquivo de cabeçalho, devemos digitar as definições da função em um editor de texto como o gedit . Nomeie o arquivo “libcipher.h” e salve-o no mesmo diretório do arquivo libcipher.a.

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

Usando a biblioteca libcipher

A única maneira segura de testar nossa nova biblioteca é escrever um pequeno programa para usá-la. Primeiro, faremos um diretório chamado test.

teste mkdir

Vamos copiar a biblioteca e os arquivos de cabeçalho para o novo diretório.

cp libcipher. * ./test

Vamos mudar para o novo diretório.

teste de cd

Vamos verificar se nossos dois arquivos estão aqui.

ls -l

cp libcipher. * ./test em uma janela de terminal

Precisamos criar um pequeno programa que possa usar a biblioteca e provar que funciona conforme o esperado. Digite as seguintes linhas de texto em um editor. Salve o conteúdo do editor em um arquivo denominado “test.c” no diretório de teste .

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

#include "libcipher.h"

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

 puts (texto);

 cipher_encode (texto);
 puts (texto);

 cipher_decode (texto);
 puts (texto);

 saída (0);

} // fim do principal

O fluxo do programa é muito simples:

  • Inclui o arquivo libcipher.h para que possa ver as definições das funções da biblioteca.
  • Ele cria uma string chamada “text” e armazena as palavras “How-To Geek loves Linux” nela.
  • Ele imprime essa string na tela.
  • ele chama a cipher_encode()função para codificar a string e imprime a string codificada na tela.
  • Ele chama cipher_decode()para decodificar a string e imprime a string decodificada na tela.
Recomendado:  Como excluir rapidamente muitas postagens antigas do Facebook

Para gerar o testprograma, precisamos compilar o programa test.c e vinculá-lo à biblioteca. A -oopção (saída) informa gcco que chamar o programa executável que ela gera.

gcc test.c libcipher.a -o test

gcc test.c libcipher.a -o test em uma janela de terminal

Se gccvocê retornar silenciosamente ao prompt de comando, está tudo bem. Agora vamos testar nosso programa. Momento da verdade:

./teste

./teste em uma janela de terminal

E vemos a saída esperada. O testprograma imprime o texto simples, imprime o texto criptografado e, em seguida, imprime o texto descriptografado. Ele está usando as funções de nossa nova biblioteca. Nossa biblioteca está funcionando.

saída do programa de teste em uma janela de terminal

Sucesso. Mas por que parar aí?

Adicionando outro módulo à biblioteca

Vamos adicionar outra função à biblioteca. Adicionaremos uma função que o programador pode usar para exibir a versão da biblioteca que está usando. Precisaremos criar a nova função, compilá-la e adicionar o novo arquivo de objeto ao arquivo de biblioteca existente.

Digite as seguintes linhas em um editor. Salve o conteúdo do editor em um arquivo denominado cipher_version.c, no diretório da biblioteca .

#include <stdio.h>

void cipher_version (void)
{
 puts ("How-To Geek :: Biblioteca de Cifras MUITO INSEGURA");
 puts ("Versão 0.0.1 Alpha \ n");

} // fim de cipher_version

Precisamos adicionar a definição da nova função ao arquivo de cabeçalho libcipher.h. Adicione uma nova linha ao final desse arquivo, de modo que fique assim:

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

Salve o arquivo libcipher.h modificado.

Precisamos compilar o arquivo cipher_version.c para que tenhamos um arquivo de objeto cipher_version.o.

gcc -c cipher_version.c

gcc -c cipher_version.c em uma janela de terminal

Isso cria um arquivo cipher_version.o. Podemos adicionar o novo arquivo de objeto à biblioteca libcipher.a com o seguinte comando. A -vopção (verbosa) faz com que o geralmente silencioso arnos diga o que fez.

ar -rsv libcipher.a cipher_version.o

ar -rsv libcipher.a cipher_version.o em uma janela de terminal

O novo arquivo de objeto é adicionado ao arquivo de biblioteca. arimprime a confirmação. O “a” significa “adicionado”.

saída de ar em uma janela de terminal

Podemos usar a -topção (tabela) para ver quais módulos estão dentro do arquivo de biblioteca.

ar -t libcipher.a

ar -t libcipher.a em uma janela de terminal

Existem agora três módulos dentro do nosso arquivo de biblioteca. Vamos usar a nova função.

Usando a função cipher_version ().

Vamos remover a biblioteca antiga e o arquivo de cabeçalho do diretório de teste, copiar os novos arquivos e depois voltar para o diretório de teste.

Excluiremos as versões antigas dos arquivos.

rm ./test/libcipher.*

Vamos copiar as novas versões para o diretório de teste.

cp libcipher. * ./test

Vamos mudar para o diretório de teste.

teste de cd

rm ./test/libcipher.* em uma janela de terminal

E agora podemos modificar o programa test.c para que ele use a nova função de biblioteca.

Precisamos adicionar uma nova linha ao programa test.c que chama a cipher_version()função. Colocaremos isso antes da primeira puts(text);linha.

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

#include "libcipher.h" 

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

 // nova linha adicionada aqui
 cipher_version (); 

 puts (texto); 
 
 cipher_encode (texto); 
 puts (texto); 
 
 cipher_decode (texto); 
 puts (texto); 

 saída (0); 

} // fim do principal

Salve como test.c. Agora podemos compilá-lo e testar se a nova função está operacional.

gcc test.c libcipher.a -o test

gcc test.c libcipher.a -o test em uma janela de terminal

Vamos executar a nova versão de test:

saída do programa de teste em uma janela de terminal

A nova função está funcionando. Podemos ver a versão da biblioteca no início da saída de test.

Mas pode haver um problema.

Recomendado:  Como ocultar ou desativar a pasta “Recentes” no Mac

Substituindo um Módulo na Biblioteca

Esta não é a primeira versão da biblioteca; é o segundo. Nosso número de versão está incorreto. A primeira versão não tinha cipher_version()função nela. Este sim. Portanto, esta deve ser a versão “0.0.2”. Precisamos substituir a cipher_version()função na biblioteca por uma corrigida.

Felizmente, artorna isso muito fácil de fazer.

Primeiro, vamos editar o arquivo cipher_version.c no diretório da biblioteca . Altere o texto “Versão 0.0.1 Alpha” para “Versão 0.0.2 Alpha”. Deve ser assim:

#include <stdio.h>

void cipher_version (void)
{
 puts ("How-To Geek :: Biblioteca de Cifras MUITO INSEGURA");  
 puts ("Versão 0.0.2 Alpha \ n"); 

} // fim de cipher_version

Salve este arquivo. Precisamos compilá-lo novamente para criar um novo arquivo de objeto cipher_version.o.

gcc -c cipher_version.c

gcc -c cipher_version.c em uma janela de terminal

Agora iremos substituir o objeto cipher_version.o existente na biblioteca por nossa versão recém-compilada.

Usamos a opção  -r(adicionar com substituir) antes, para adicionar novos módulos à biblioteca. Quando o usarmos com um módulo que já existe na biblioteca, ariremos substituir a versão antiga pela nova. A -sopção (índice) atualizará o índice da biblioteca e a -v  opção (verbosa) fará com que  ar nos diga o que foi feito.

ar -rsv libcipher.a cipher_version.o

ar -rsv libcipher.a cipher_version.o em uma janela de terminal

Desta vez, arrelata que substituiu o módulo cipher_version.o. O “r” significa substituído.

saída de ar em uma janela de terminal

Usando a função cipher_version () atualizada

Devemos usar nossa biblioteca modificada e verificar se funciona.

Copiaremos os arquivos da biblioteca para o diretório de teste.

cp libcipher. * ./test

Vamos mudar para o diretório de teste.

cd ./test

Precisamos compilar nosso programa de teste novamente com nossa nova biblioteca.

gcc test.c libcipher.a -o test

E agora podemos testar nosso programa.

./teste

cp libcipher. * ./test em uma janela de terminal

O resultado do programa de teste é o que esperávamos. O número de versão correto é mostrado na string de versão e as rotinas de criptografia e descriptografia estão funcionando.

Excluindo Módulos de uma Biblioteca

Parece uma pena depois de tudo isso, mas vamos deletar o arquivo cipher_version.o do arquivo de biblioteca.

Para fazer isso, usaremos a -dopção (excluir). Também usaremos a -vopção (detalhada), para que arnos diga o que fez. Também incluiremos a -sopção (índice) para atualizar o índice no arquivo de biblioteca.

ar -dsv libcipher.a cipher_version.o

ar -dsv libcipher.a cipher_version.o em uma janela de terminal

arrelata que removeu o módulo. O “d” significa “excluído”.

Se pedirmos arpara listar os módulos dentro do arquivo de biblioteca, veremos que estamos de volta aos dois módulos.

ar -t libcipher.a

ar -t libcipher.a em uma janela de terminal

Se você for excluir módulos de sua biblioteca, lembre-se de remover suas definições do arquivo de cabeçalho da biblioteca.

Compartilhe seu código

As bibliotecas tornam o código compartilhável de maneira prática, mas privada. Qualquer pessoa a quem você forneça o arquivo de biblioteca e o arquivo de cabeçalho pode usar sua biblioteca, mas seu código-fonte real permanece privado.