Como determino a arquitetura de destino da biblioteca estática (.a) no Mac OS X?

128

Estou interessado em verificar se uma determinada biblioteca estática do iPhone foi criada para ARM ou Intel.

É mais curiosidade do que qualquer coisa. Existe algum tipo de ferramenta específica para o Mac OS X ou BSD para fazer isso? Este post fornece um exemplo no Linux.

Justicle
fonte

Respostas:

241

Outra opção é lipo; sua saída é breve e mais legível que otoola.

Um exemplo:

% lipo -info /usr/lib/libiodbc.a 
Architectures in the fat file: /usr/lib/libiodbc.a are: x86_64 i386 ppc
% lipo -info libnonfatarchive.a
input file libnonfatarchive.a is not a fat file
Non-fat file: libnonfatarchive.a is architecture: i386
%
Václav Slavík
fonte
Acabei de verificar isso com um arquivo PJSIP .a antigo. armv7. Obrigado.
Alex Zavatone
69

fileprovavelmente lhe dirá. otoolcertamente deve ser capaz. Mas eu tentaria fileprimeiro, por exemplo

logan:/Users/logan% file d2
d2: Mach-O executable ppc

Exemplo com arquivo:

logan:/Users/logan% file /usr/lib/libMallocDebug.a
/usr/lib/libMallocDebug.a: Mach-O universal binary with 2 architectures
/usr/lib/libMallocDebug.a (for architecture i386):      current ar archive random library
/usr/lib/libMallocDebug.a (for architecture ppc):       current ar archive
Logan Capaldo
fonte
34
Na minha experiência, filemuitas vezes falha.
Stefan Schmidt
4
Veja a resposta sobre lipo mais abaixo, sempre funciona.
Maciej Swic
Percebi que, se o arquivo .a is não for ranlib'd, o arquivo às vezes relata menos informações.
Paul Du Bois
4
Agora em 2015 você deve usar lipo. Veja a resposta abaixo.
DerFunk 12/02
1
Infelizmente, isso não funcionou em várias versões do sistema operacional.
rmcclellan
53

Como mencionado anteriormente, filenem sempre funciona. otool -hv -arch allé provavelmente a coisa mais próxima que é garantida que funcione - fornece informações de arquitetura para cada arquivo de objeto na biblioteca.

Exemplo:

% otool -hv /sw/lib/libfftw3.a
Arquivo: /sw/lib/libfftw3.a
/sw/lib/libfftw3.a(align.o):
Cabeçalho mach
      tipo de código mágico cpusubtype caps tipo de arquivo ncmds sizeofcmds flags
MH_MAGIC_64 X86_64 ALL ALL 0x00 OBJECT 3 336 SUBSECTIONS_VIA_SYMBOLS
/sw/lib/libfftw3.a(alloc.o):
Cabeçalho mach
      tipo de código mágico cpusubtype caps tipo de arquivo ncmds sizeofcmds flags
MH_MAGIC_64 X86_64 ALL ALL 0x00 OBJECT 3 416 SUBSECTIONS_VIA_SYMBOLS
...
Jiahao Chen
fonte
Apenas para adicionar a esta resposta, prefiro otool sobre file ou lipo. Tentei file, lipo e otool com uma biblioteca de gordura iOS e o otool foi o único que me mostrou que continha arquivos para o i386 (iPhone Simulator) e para armv6, armv7 e armv7s (iPhone OS).
8263 Roberto
1
NOTA: se você quiser verificar se sua biblioteca é gorda ou não, você deseja usar "otool -arch all"; caso contrário, ele relatará apenas uma arquitetura por arquivo .o. Para uma rápida visão geral das arquiteturas em seu .a, "otool -f"
Paul Du Bois
4

Como alternativa, eu descobri que objdumppode funcionar bem. Como exemplo, no meu ambiente, construo arquivos de biblioteca com o vxWorks e preciso vinculá-los a outros projetos. Para testar se o arquivamento é a arquitetura correta, eu poderia fazer algo como o seguinte (sintaxe do bash):

if [ "$(objdumpsparc -a ${ARCHIVE_FILE} 2>&1 | ggrep -cvP 'elf32-sparc-vxworks')" -ne "0" ]; then
  echo "Cannot build with ${ARCHIVE_FILE}, it contains one or more non-sparc components"
fi;

Este exemplo não é precisamente correto, porque algumas linhas aparecem que não dizem elf32-sparc-vxworks, mas é fácil o suficiente para adaptar isso.

Uma boa vantagem disso é que objdump, ou uma variante com nome semelhante, é instalada na maioria dos sistemas operacionais * nix, enquanto as ferramentas sugeridas em outras respostas não.

edit Apenas me ocorreu que o OP estava perguntando no OSX. Me desculpe.

Brian Vandenberg
fonte
Para usar, objdumpvocê pode instalar o GNU Binutils via MacPorts. Para ver todas as arquiteturas disponíveis, basta executar port search binutils. As ferramentas para o desenvolvimento nativo são prefixadas para evitar conflitos (por exemplo, em gobjdumpvez de objdump). Você pode criar um alias por conveniência.
Stefan Schmidt
3

Esse script bash o ajudará programaticamente a obter uma lista de arquiteturas em uma variável.

list_archs.sh:

#! /bin/bash
lipo -info $1 | sed -En -e 's/^(Non-|Architectures in the )fat file: .+( is architecture| are): (.*)$/\3/p'

Exemplo de uso:

./list_archs.sh /usr/lib/libc.dylib
x86_64 i386
bleater
fonte