Quais são as diferenças entre .so e .dylib no osx?

214

.dylib é a extensão de biblioteca dinâmica no OSX, mas nunca ficou claro para mim quando não posso / não devo usar um objeto .so compartilhado unix tradicional.

Algumas das perguntas que tenho:

  • No nível conceitual, quais são as principais diferenças entre .so e .dylib?
  • Quando posso / devo usar um sobre o outro?
  • Dicas e truques de compilação (por exemplo, a substituição do gcc -shared -fPIC, já que isso não funciona no osx)
Trent Davies
fonte

Respostas:

206

O formato de arquivo de objeto Mach-O usado pelo Mac OS X para executáveis ​​e bibliotecas distingue entre bibliotecas compartilhadas e módulos carregados dinamicamente . Use otool -hv some_filepara ver o tipo de arquivo de some_file.

As bibliotecas compartilhadas do Mach-O têm o tipo de arquivo MH_DYLIBe carregam a extensão .dylib. Eles podem ser vinculados aos sinalizadores estáticos comuns do vinculador, por exemplo, -lfoopara libfoo.dylib. Eles podem ser criados passando o -dynamiclibsinalizador para o compilador. ( -fPICé o padrão e não precisa ser especificado.)

Módulos carregáveis ​​são chamados de "pacotes" na fala do Mach-O. Eles têm o tipo de arquivo MH_BUNDLE. Eles podem carregar qualquer extensão; a extensão .bundleé recomendada pela Apple, mas a maioria dos softwares portados usa .sopor razões de compatibilidade. Normalmente, você usará pacotes configuráveis ​​para plug-ins que estendem um aplicativo; nessas situações, o pacote será vinculado ao binário do aplicativo para obter acesso à API exportada do aplicativo. Eles podem ser criados passando o -bundlesinalizador para o compilador.

Dylibs e pacotes configuráveis ​​podem ser carregados dinamicamente usando as dlAPIs (por exemplo dlopen, dlclose). Não é possível vincular a pacotes configuráveis ​​como se fossem bibliotecas compartilhadas. No entanto, é possível que um pacote configurável esteja vinculado a bibliotecas compartilhadas reais; esses serão carregados automaticamente quando o pacote configurável for carregado.

Historicamente, as diferenças foram mais significativas. No Mac OS X 10.0, não havia como carregar dinamicamente bibliotecas. Um conjunto de APIs dyld (por exemplo NSCreateObjectFileImageFromFile, NSLinkModule) foi introduzido com 10.1 para carregar e descarregar pacotes configuráveis , mas eles não funcionaram para dylibs. Uma dlopenbiblioteca de compatibilidade que funcionou com pacotes configuráveis ​​foi adicionada na 10.3; na dlopenversão 10.4, foi reescrita para ser uma parte nativa do dyld e adicionou suporte para carregar (mas não descarregar) dylibs. Por fim, o 10.5 adicionou suporte ao uso dlclosecom dylibs e reprovou as APIs do dyld.

Em sistemas ELF como o Linux, ambos usam o mesmo formato de arquivo ; qualquer parte do código compartilhado pode ser usada como uma biblioteca e para carregamento dinâmico.

Por fim, lembre-se de que, no Mac OS X, "pacote" também pode se referir a diretórios com uma estrutura padronizada que contém código executável e os recursos usados ​​por esse código. Há alguma sobreposição conceitual (particularmente com "pacotes configuráveis ​​carregáveis", como plug-ins, que geralmente contêm código executável na forma de um pacote configurável Mach-O), mas eles não devem ser confundidos com os pacotes configuráveis ​​Mach-O discutidos acima.

Referências adicionais:

Milhas
fonte
1
Obrigado por este extenso comentário :) Entendi corretamente que, se eu carregar um pacote de outro pacote (ou seja, o caminho é app -> pacote A -> pacote B), o pacote B não poderá ver nenhum símbolos no pacote A? E se sim, existem maneiras de resolver isso de alguma forma? Acabei de bater, eu penso: stackoverflow.com/questions/4193539/...
Mikhail Edoshin
4
@ noloader: -dynamiclibé uma bandeira do GCC. Faz o compilador passar -dylibpara ld.
Miles
URL atualizado para a página do manual para ld no Mac OSX: manpages.info/macosx/ld.1.html
netpoetica
18

O arquivo .so não é uma extensão de arquivo UNIX para a biblioteca compartilhada.

Acontece que é comum.

Verifique a linha 3b em página compartilhada ArnaudRecipes

Basicamente .dylib é a extensão de arquivo mac usada para indicar uma biblioteca compartilhada.

Martin York
fonte
9
@ninefingers. Corrigir. Mas algumas das ferramentas usarão valores padrão, a menos que algo seja muito explícito. por exemplo, os compiladores usarão a extensão de biblioteca compartilhada específica da plataforma quando o sinalizador -l <lib> for usado (o sinalizador real pode muito entre compiladores).
Martin York
14

A diferença entre .dylib e .so no mac os x é como eles são compilados. Para arquivos .so você usa -shared e para .dylib você usa -dynamiclib. .So e .dylib são intercambiáveis ​​como arquivos de biblioteca dinâmica e têm um tipo como DYLIB ou BUNDLE. Aqui está a leitura para diferentes arquivos mostrando isso.

libtriangle.dylib:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL  0x00       DYLIB    17       1368   NOUNDEFS DYLDLINK TWOLEVEL NO_REEXPORTED_DYLIBS



libtriangle.so:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL  0x00       DYLIB    17       1256   NOUNDEFS DYLDLINK TWOLEVEL NO_REEXPORTED_DYLIBS

triangle.so:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL  0x00      BUNDLE    16       1696   NOUNDEFS DYLDLINK TWOLEVEL

O motivo pelo qual os dois são equivalentes no Mac OS X é a compatibilidade com outros programas do SO UNIX que são compilados no tipo de arquivo .so.

Notas de compilação: se você compila um arquivo .so ou um arquivo .dylib, precisa inserir o caminho correto na biblioteca dinâmica durante a etapa de vinculação. Você faz isso adicionando -install_name e o caminho do arquivo ao comando de vinculação. Se você não fizer isso, encontrará o problema visto neste post: Loucura na Biblioteca Dinâmica do Mac (pode ser apenas Fortran) .

Zachary Kraus
fonte
como posso ./configuregerar .dylibarquivos em vez de agrupar arquivos .so? ./configure --enable-sharednão faz esta tarefa.
Admia 14/05/19
da minha experiência, a maioria dos arquivos de configuração no mac criará um arquivo .so ou um arquivo de biblioteca estática, porque os arquivos de configuração estão usando nomes de arquivo padrão unix / linux.
Zachary Kraus
4

Apenas uma observação que acabei de fazer ao criar código ingênuo no OSX com o cmake:

cmake ... -DBUILD_SHARED_LIBS=OFF ...

cria .so arquivos

enquanto

cmake ... -DBUILD_SHARED_LIBS=ON ...

cria .dynlib arquivos .

Talvez isso ajude alguém.

user2996950
fonte