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 bibliotecareadline
. -
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).