Por que eu tenho que definir LD_LIBRARY_PATH antes de executar um programa, mesmo que eu já tenha vinculado os locais da biblioteca no estágio de compilação? [duplicado]

2

Estou compilando um modelo usando make ; o modelo tem um Makefile que conecta o código-fonte com bibliotecas dependentes por meio de sinalizadores parecidos com -L/lib1 -L/lib2 . Mas quando eu tento rodar esse modelo, ele falha a menos que eu também garanta a variável ambiental

export LD_LIBRARY_PATH=/lib1:/lib2

e aponta para as bibliotecas exatamente iguais . Isso parece redundante para mim.

O que poderia estar acontecendo sob o capô aqui? Por que tenho efetivamente que especificar o local das bibliotecas antes da compilação e antes da execução?

Esta pode ser uma pergunta boba; Eu não tenho muita experiência em compilar código de máquina, geralmente apenas uso linguagens de script.

    
por Luke Davis 18.02.2018 / 20:40

1 resposta

4

Embora todos usem a compilação no sentido coloquial de transformar o código-fonte em um executável, ele é tecnicamente uma única etapa em um pipeline bastante longo:

  1. O arquivo de entrada é executado no pré-processador, resultando em uma única unidade de tradução.
  2. A saída do pré-processador é compilada para montagem.
  3. O assembler toma isso como entrada e gera um arquivo de objeto.
  4. O vinculador une os arquivos de objeto para produzir um executável.

[Para ser pedante, não há exigência de que as etapas sejam separadas e os compiladores modernos normalmente os combinam para obter eficiência. ]

Nossa preocupação é a etapa de vinculação, que combina seu código com bibliotecas de sistema padrão. O vinculador copia objetos de bibliotecas estáticas diretamente para o executável. Para bibliotecas compartilhadas, no entanto, ele fornece apenas uma referência à biblioteca.

As bibliotecas compartilhadas têm muitas vantagens. Você pode atualizá-los sem recompilar programas e eles usam menos memória porque os programas podem compartilhar código comum. Eles também têm a desvantagem óbvia de que o código não está no executável.

A solução para isso é o carregador dinâmico, que é responsável por resolver todas as referências de biblioteca compartilhada no tempo de execução. O carregador é executado automaticamente; instruções para fazer isso são uma coisa que o vinculador inclui no executável. Claro que isso pressupõe que o carregador possa encontrar as bibliotecas.

As bibliotecas do sistema estão em diretórios padrão, o que é simples. Quando esse não for o caso, o carregador pesquisará o LD_LIBRARY_PATH. Por que o vinculador não coloca o caminho no executável? Porque então você seria incapaz de mover ou alterar a biblioteca.

Na prática, você também não pode mover o executável, pois a biblioteca está fora do caminho de pesquisa do sistema. Se ele só rodou quando a biblioteca estava localizada em ~ luke / lib, então você não pode dar a joe a menos que ele possa ler seus arquivos. Suga para joe se você mudar para um novo emprego.

Apenas FYI seria sugar em uma infinidade de outras formas também. Isso tornaria a depuração um pesadelo eterno se você pudesse especificar apenas a localização da biblioteca em tempo de compilação, entre outras coisas.

    
por 19.02.2018 / 08:45