Build, processos de link no linux

4

Eu não consigo diferença entre compilar e compilar. Eles são mesmo? como exatamente a vinculação funciona? O que exatamente o arquivo .so e o arquivo .o contém e como devo usá-los? Todos esses arquivos eu vejo todos os dias, mas não sei exatamente o que eles contêm. Alguém pode sugerir algum tutorial para contar claramente esses processos?

    
por user997704 05.08.2012 / 12:11

1 resposta

13

O termo "build" é geralmente usado para significar todo o processo que começa com um conjunto de arquivos de código fonte e outros recursos, e termina com um conjunto de executáveis, bibliotecas compartilhadas (e possivelmente outros recursos). > Isso pode envolver várias etapas, como pré-processadores especiais ( moc para o código Qt, por exemplo), geradores de código ( flex / yacc ou bison , por exemplo), compilação, vinculação e possivelmente pós-processamento. etapas de processamento (por exemplo, criação de arquivos tar.gz ou rpm para distribuição).

Para C e C ++ (e linguagens relacionadas), a compilação é a única coisa que transforma arquivos de origem (digamos, .c arquivos para código C) em arquivos de objeto ( .o ). Esses arquivos de objeto contêm o código de máquina gerado pelo compilador para o código-fonte correspondente, mas não são produtos finais - em particular, as referências de funções externas (e dados) não são resolvidas. Eles são "incompletos" nesse sentido.
Arquivos de objetos são, às vezes, agrupados em arquivos ( .a files), também chamados de bibliotecas estáticas. Isso é praticamente uma maneira conveniente de agrupá-los juntos.

A vinculação pega (geralmente vários) arquivos de objeto ( .o ou .a ) e bibliotecas compartilhadas, combina os arquivos de objeto, resolve as referências (principalmente) entre os próprios arquivos de objetos e as bibliotecas compartilhadas e produz executáveis que você pode realmente usar, ou bibliotecas compartilhadas ( .so ) que podem ser usadas por outros programas ou bibliotecas compartilhadas.

Bibliotecas compartilhadas são repositórios de código / funções que podem ser usados diretamente por outros executáveis. A principal diferença entre a vinculação dinâmica em relação a uma biblioteca compartilhada e a vinculação (estática) de um objeto ou arquivo morto diretamente é que as bibliotecas compartilhadas podem ser atualizadas sem recriar os executáveis que as usam (há muitas restrições para isso).
Por exemplo, se em algum momento um bug for encontrado em uma biblioteca compartilhada OpenSSL, a correção poderá ser feita nesse código, e bibliotecas compartilhadas atualizadas poderão ser produzidas e enviadas. Os programas vinculados dinamicamente a essa biblioteca compartilhada não precisam ser reconstruídos para obter a correção de erros. A atualização da biblioteca compartilhada corrige automaticamente todos os seus usuários.
Se eles tivessem vinculado a um arquivo objeto (ou estaticamente em geral), eles teriam que reconstruir (ou pelo menos re-linkar ) para obter a correção.

Um exemplo prático: digamos que você queira escrever um programa - uma calculadora de linha de comando sofisticada - em C, que possui suporte a histórico de linha de comando / edição. Você escreveria o código da calculadora, mas usaria a biblioteca readline para o tratamento de entrada.
Você pode dividir seu código em duas partes: as funções matemáticas (coloque essas funções em mathfuncs.c ) e o código "principal" da calculadora que lida com entrada / saída (digamos em main.c ).

Seu build consistiria em:

  • Compilar mathfuncs.c ( gcc -o mathfuncs.o -c mathfuncs.c , -c significa "compilar apenas")
    mathfuncs.o agora contém suas funções matemáticas compiladas, mas não é "executável" - é apenas um repositório de código de função.

  • Compile seu frontend ( gcc -o main.o -c main.c )
    main.o é da mesma forma apenas um monte de funções, não executáveis

  • Vincule seu executável da calculadora, vinculando com readline :

    gcc -o supercalc main.o mathfuncs.o -lreadline
    #      ^ executable                    ^ dynamic link with libreadline.so
    #                  ^         ^ two .o files statically linked in
    

    Agora você tem um executável real que pode ser executado ( supercalc ), que depende da biblioteca readline .

  • Crie um pacote rpm com toda a biblioteca executável e compartilhada (e cabeçalho) nele. (Os arquivos .o , sendo produtos de construção temporários e não produtos finais, geralmente não são enviados.)

Com isso, se um bug for encontrado em readline , você não precisará reconstruir (e reenviar) seu executável para obter a correção - a atualização libreadline.so é tudo que é necessário. Mas se você encontrar um bug em mathfuncs.c , você precisará re-compilá-lo e vincular novamente o supercalc (e enviar uma nova versão).

    
por 05.08.2012 / 13:09

Tags