Onde os executáveis procuram objetos compartilhados no tempo de execução?

86

Eu entendo como definir incluir objetos compartilhados no tempo de vinculação / compilação. No entanto, ainda me pergunto como os executáveis procuram o objeto compartilhado ( *.so libraries) em tempo de execução.

Por exemplo, meu aplicativo a.out chama funções definidas na biblioteca lib.so . Depois de compilar, eu movo lib.so para um novo diretório no meu $HOME .

Como posso dizer a a.out para procurá-lo lá?

    
por rahmu 19.10.2011 / 14:07

4 respostas

88

O HOWTO da biblioteca compartilhada explica a maioria dos mecanismos envolvidos, e o manual do carregador dinâmico entra em mais detalhes. Cada variante do unix tem seu próprio caminho, mas a maioria usa o mesmo formato executável ( ELF ) e tem o mesmo linkers dinâmicos (derivados do Solaris). Abaixo, resumirei o comportamento comum com foco no Linux; verifique os manuais do seu sistema para ver a história completa.

Em poucas palavras, quando estiver procurando por uma biblioteca dinâmica ( .so file), o vinculador tentará:

  • diretórios listados na variável de ambiente LD_LIBRARY_PATH ( DYLD_LIBRARY_PATH no OSX);
  • diretórios listados no caminho do executável ;
  • diretórios no caminho de pesquisa do sistema, que (pelo menos no Linux) consiste nas entradas em /etc/ld.so.conf plus /lib e /usr/lib .

O rpath é armazenado no executável (é o atributo DT_RPATH ou DT_RUNPATH dynamic). Ele pode conter caminhos ou caminhos absolutos começando com $ORIGIN para indicar um caminho relativo ao local do executável (por exemplo, se o executável estiver em /opt/myapp/bin e seu caminho for $ORIGIN/../lib:$ORIGIN/../plugins , o vinculador dinâmico procurará em /opt/myapp/lib e /opt/myapp/plugins ). O rpath é normalmente determinado quando o executável é compilado, com a opção -rpath para ld , mas você pode alterá-lo posteriormente com chrpath .

No cenário descrito, se você for o desenvolvedor ou empacotador do aplicativo e pretender que ele seja instalado em uma estrutura …/bin , …/lib , vincule-se a -rpath='$ORIGIN/../lib' . Se você estiver instalando um binário pré-compilado em seu sistema, coloque a biblioteca em um diretório no caminho de pesquisa ( /usr/local/lib se você for o administrador do sistema, caso contrário, um diretório incluído em $LD_LIBRARY_PATH ) ou tente chrpath .

    
por 20.10.2011 / 19:19
16

No Linux, o comportamento é explicitado na página ld(1) man

       The linker uses the following search paths to locate required
       shared libraries:

       1.  Any directories specified by -rpath-link options.

       2.  Any directories specified by -rpath options.  The difference
           between -rpath and -rpath-link is that directories specified by
           -rpath options are included in the executable and used at
           runtime, whereas the -rpath-link option is only effective at
           link time. Searching -rpath in this way is only supported by
           native linkers and cross linkers which have been configured
           with the --with-sysroot option.

       3.  On an ELF system, for native linkers, if the -rpath and
           -rpath-link options were not used, search the contents of the
           environment variable "LD_RUN_PATH".

       4.  On SunOS, if the -rpath option was not used, search any
           directories specified using -L options.

       5.  For a native linker, the search the contents of the environment
           variable "LD_LIBRARY_PATH".

       6.  For a native ELF linker, the directories in "DT_RUNPATH" or
           "DT_RPATH" of a shared library are searched for shared
           libraries needed by it. The "DT_RPATH" entries are ignored if
           "DT_RUNPATH" entries exist.

       7.  The default directories, normally /lib and /usr/lib.

       8.  For a native linker on an ELF system, if the file
           /etc/ld.so.conf exists, the list of directories found in that
           file.

       If the required shared library is not found, the linker will issue
       a warning and continue with the link.
    
por 19.10.2011 / 16:04
2

Tenho certeza de que a resposta aqui é ldconfig .

ldconfig creates the necessary links and cache to the most recent shared libraries found in the directories specified on the command line, in the file /etc/ld.so.conf, and in the trusted directories (/lib and /usr/lib). The cache is used by the run-time linker, ld.so or ld-linux.so. ldconfig checks the header and filenames of the libraries it encounters when determining which versions should have their links updated.

link

    
por 19.10.2011 / 14:14
0

Para executar aplicativos, o arquivo /proc/1234/maps contém todas as bibliotecas reais vinculadas dinamicamente.

Onde 1234 é o pid do executável em execução.

O Linux segue LD_LIBRARY_PATH e outras variáveis, conforme apontado na resposta de Gilles.

    
por 15.10.2015 / 16:49