o que é ranlib?


13

Estou usando um sistema MacOSX há algum tempo, mas apenas recentemente comecei a cutucá-lo. Encontrei um guia dizendo para executar 'sudo ranlib /usr/local/lib/libjpeg.a'(instalando libjpeg). Eu li o manual do ranlib e tentei procurar on-line nele. Eu simplesmente não entendo. Quais recursos eu preciso procurar para saber mais ou alguém pode dar uma explicação concisa sobre seu uso? Desde já, obrigado!

Respostas:


7

ranlibadiciona ou atualiza arquivos de objetos em uma biblioteca estática . Os vinculadores podem usar bibliotecas estáticas ao vincular para fornecer símbolos que o código precisa para operar (em oposição ao carregador que os procura em bibliotecas dinâmicas ao executar o executável).


Olá Ignacio, obrigado pela resposta. Isso significa que, se eu executar o ranlib em uma biblioteca, ele estará disponível para uso sempre que um vinculador tentar 'referenciá-lo'? Como é removido?
Ying

ranlibé usado para criar e modificar as bibliotecas. Cabe ao vinculador usá-los, geralmente passando o local e / ou o nome da biblioteca na linha de comando. Veja os argumentos -Le -lno gcc para obter detalhes.
Ignacio Vazquez-Abrams

5
Mas artambém não faz isso? Qual é a diferença?
greatwolf

18

Essa descrição parece bem clara: http://sourceware.org/binutils/docs/binutils/ranlib.html

Portanto, se você arquivar uma coleção de arquivos de objetos, diga:

$ ar r fruits.a apple.o orange.o pineapple.o

Então correndo

$ ranlib fruits.a

cria um índice do conteúdo de fruits.a e armazena o índice em fruits.a. Isso é útil para vincular e caso os objetos se chamam.


"ranlib gera um índice para o conteúdo de um arquivo e o armazena no arquivo". Isso soa mais como algo a ser combinado tare eu diria que não é muito claro.
Codebling

9

O ranlib gera um índice para o conteúdo de um arquivo e o armazena no arquivo. O índice lista cada símbolo definido por um membro de um arquivo morto que é um arquivo de objeto realocável. Um arquivo com esse índice acelera o vínculo com a biblioteca e permite que as rotinas da biblioteca se liguem sem levar em consideração a sua colocação no arquivo.

fonte: página de manual do ranlib


2

ar

No Linux, aré o arquivador de propósito geral do GNU. (Existem variantes não-GNU arem outros sistemas operacionais semelhantes ao Unix). Com a opçãoc

ar c... archive-name file...

Ele cria um arquivo contendo cópias de file.... O archive-nameconvencional, mas não necessariamente, tem a extensão .a(para arquivamento ). Cada um file...pode ser qualquer tipo de arquivo, não necessariamente um arquivo de objeto.

Quando os arquivos arquivados são todos arquivos de objetos, geralmente é a intenção usar o arquivo morto para entregar essa seleção de arquivos de objetos na vinculação de programas ou DSOs (Dynamic Shared Objects). Nesse caso archive-name, também será dado o prefixo convencionalmente lib, por exemplo libfoo.a, para que ele possa ser descoberto como um arquivo de entrada de vinculador candidato através da opção vinculador -lfoo.

Usado como um arquivo de entrada do vinculador, libfoo.anormalmente é chamado de biblioteca estática . Esse uso é uma fonte perpétua de confusão para programadores inexperientes, porque os leva a pensar que um arquivo libfoo.aé o mesmo tipo de DSO libfoo.so, normalmente chamado de biblioteca dinâmica / compartilhada , e a criar falsas expectativas com base nisso. De fato, uma "biblioteca estática" e uma "biblioteca dinâmica" não são coisas semelhantes e são usadas no vínculo de maneiras totalmente diferentes.

Uma diferença visível é que uma biblioteca estática não é produzida pelo vinculador , mas por ar. Portanto, nenhuma ligação acontece, nenhuma resolução de símbolo acontece. Os arquivos de objetos arquivados permanecem inalterados: são apenas colocados em um saco.

Quando um arquivo é a entrada na ligação de algo que é produzido pelo vinculador - como um programa ou DSO - os olhares vinculador no saco para ver se há algum objeto arquivos nele que fornecem definições para referências símbolo não resolvido adquiridos no início da ligação. Se encontrar alguma, ele extrai os arquivos objeto do saco e liga -los no arquivo de saída, exatamente como se eles foram nomeados individualmente na linha de comando vinculador eo arquivo não mencionado. Portanto, todo o papel de um arquivo morto no vínculo é como um conjunto de arquivos de objetos dos quais o vinculador pode selecionar os que precisa para continuar o vínculo.

Por padrão, o GNU arprepara seus arquivos de saída para uso como entradas do vinculador. Ele adiciona um "arquivo" falso ao arquivo morto, com um nome de arquivo falso mágico e, nesse arquivo falso, grava conteúdo que o vinculador pode ler como uma tabela de pesquisa a partir dos símbolos globais que são definidos por quaisquer arquivos de objeto no arquivo morto. para os nomes e posições desses arquivos de objeto no arquivo morto. Esta tabela de pesquisa é o que permite ao vinculador procurar no arquivo morto e identificar quaisquer arquivos de objeto que definam as referências de símbolo não resolvidas que ele tem em mãos.

Você pode suprimir a criação ou atualização dessa tabela de pesquisa com a opção q(= quick ) - que de fato você usou em seu próprio arexemplo - e também com a opção (capital) S(= tabela sem símbolos ). E se você invocar arpara criar ou atualizar um arquivo que não possui uma tabela de símbolos (atualizada) por qualquer motivo, poderá escolher um com a sopção

ranlib

ranlibnão cria bibliotecas. No Linux, ranlibé um programa herdado que adiciona uma tabela de símbolos (atualizada) a um ararquivo morto, se ele não tiver uma. Seu efeito é exatamente o mesmo que ar s, com o GNU ar. Historicamente, antes de arser equipado para gerar uma tabela de símbolos, ranlibhavia o argumento que injetava o arquivo falso mágico em um arquivo para permitir que o vinculador escolhesse os arquivos de objetos. Em sistemas operacionais que não sejam do tipo GNU Unix, ranlibainda pode ser necessário para esse fim. Seu exemplo:

ar qc libgraphics.a *.o
ranlib libgraphics.a

diz:

  • Crie libgraphics.aanexando a um arquivo morto todos os *.oarquivos no diretório atual, sem tabela de símbolos.
  • Em seguida, adicione uma tabela de símbolos para libgraphics.a

No linux, isso tem o mesmo efeito líquido que:

ar cr libgraphics.a *.o

Por si só, ar qc libgraphics.a *.ocria um arquivo morto que o vinculador não pode usar porque não possui tabela de símbolos.

ld

Seu exemplo:

ld -r -o libgraphics.a *.o

é realmente pouco ortodoxo. Isso ilustra o uso bastante raro do vinculador , ldpara produzir um arquivo de objeto mesclado , vinculando vários arquivos de entrada em um único arquivo de objeto de saída, no qual a resolução do símbolo foi realizada na medida do possível , considerando os arquivos de entrada. A opção -r(= relocatable ) direciona o vinculador para produzir um destino de arquivo de objeto (em vez de um programa ou DSO) vinculando as entradas o máximo possível e não falhar no linkaqe se referências de símbolos indefinidas permanecerem no arquivo de saída. Esse uso é chamado de link parcial .

O arquivo de saída ld -r ... é um arquivo objeto, e não um ar arquivo , e especificar um nome de arquivo de saída que olhares como o de um ararquivo não torná-lo um. Portanto, seu exemplo ilustra uma decepção. Este:

ld -r -o graphics.o *.o

seria sincero. Não está claro para mim qual poderia ser o objetivo de tal engano, porque mesmo que um arquivo de objeto ELF seja chamado libgraphics.ae seja inserido em uma ligação por esse nome ou por -lgraphics, o vinculador o identificará corretamente como um arquivo de objeto ELF , não um ararquivo morto, e o consumirá da maneira que consome qualquer arquivo de objeto na linha de comando: ele o vincula incondicionalmente ao arquivo de saída, enquanto o ponto de entrada de um arquivo morto genuíno é vincular os membros do arquivo morto apenas na condição de serem referenciados . Talvez você tenha apenas um exemplo de link mal informado aqui.

Empacotando...

Na verdade, só vimos uma maneira de produzir algo que é convencionalmente chamado de biblioteca , e essa é a produção da chamada biblioteca estática , arquivando alguns arquivos de objetos e colocando uma tabela de símbolos no arquivo.

E ainda não vimos como produzir o outro e mais importante tipo de coisa convencionalmente chamada de biblioteca , a saber, um Objeto Compartilhado Dinâmico / biblioteca compartilhada / biblioteca dinâmica.

Como um programa, um DSO é produzido pelo vinculador . Um programa e um DSO são variantes do binário ELF que o carregador do SO entende e pode usar para montar um processo em execução. Geralmente nós chamar o vinculador através de um um dos frontends do CCG ( gcc, g++, gfortran, etc):

Vinculando um programa:

gcc -o prog file.o ... -Ldir ... -lfoo ...

Vinculando um DSO:

gcc -shared -o libbar.so file.o ... -Ldir ... -lfoo ...

As bibliotecas compartilhadas e as estáticas podem ser oferecidas ao vinculador pelo -lfooprotocolo uniforme , quando você vincula algum outro programa ou DSO. Essa opção instrui o vinculador a varrer seus diretórios de pesquisa especificados ou padrão para localizar libfoo.soou libfoo.a. Por padrão, uma vez que encontre um deles, ele inserirá esse arquivo na ligação e, se encontrar os dois no mesmo diretório de pesquisa, preferirá libfoo.so. Se libfoo.so, for selecionado, o vinculador adicionará esse DSO à lista de dependências de tempo de execução de qualquer programa ou DSO que você esteja criando. Se libfoo.afor selecionado, o vinculador usará o archive como uma seleção de arquivos de objeto para vinculação ao arquivo de saída, se necessário, ali mesmo. Nenhuma dependência de tempo de execução libfoo.aem si é possível; não pode ser mapeado em um processo; isso não significa nada para o carregador do SO.

Copiado de https://stackoverflow.com/a/47924864/195787 .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.