Jak określić docelową architekturę biblioteki statycznej (.a) w systemie Mac OS X?

128

Interesuje mnie sprawdzenie, czy dana biblioteka statyczna iPhone'a została zbudowana dla ARM lub Intel.

To bardziej ciekawość niż cokolwiek innego. Czy jest do tego jakieś narzędzie specyficzne dla Mac OS X lub BSD? Ten post zawiera przykład w systemie Linux.

Justicle
źródło

Odpowiedzi:

241

Inną opcją jest lipo; jego wyjście jest krótkie i bardziej czytelne niż otoolto.

Przykład:

% 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
źródło
Właśnie zweryfikowałem to za pomocą starego pliku PJSIP .a. armv7. Dzięki.
Alex Zavatone
69

fileprawdopodobnie ci powie. otoolz pewnością powinien móc. Ale najpierw spróbuję file, np

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

Przykład z archiwum:

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
źródło
34
Z mojego doświadczenia fileczęsto zawodzi.
Stefan Schmidt
4
Zobacz odpowiedź na temat lipo poniżej, zawsze działa.
Maciej Swic
Zauważyłem, że jeśli .a nie jest ranlib'd, plik czasami raportuje mniej informacji.
Paul Du Bois
4
Teraz w 2015 roku powinieneś używać lipo. Zobacz odpowiedź poniżej.
derFunk
1
Niestety nie zadziałało to w przypadku kilku wersji systemu operacyjnego.
rmcclellan
53

Jak wspomniano wcześniej, filenie zawsze działa. otool -hv -arch alljest prawdopodobnie najbliższą rzeczą, która na pewno zadziała - dostarcza informacji o architekturze dla każdego pliku obiektowego w bibliotece.

Przykład:

% otool -hv /sw/lib/libfftw3.a
Archiwum: /sw/lib/libfftw3.a
/sw/lib/libfftw3.a(align.o):
Nagłówek Macha
      magic cputype cpusubtype kapsle typu filetype ncmds sizeofcmds flagi
MH_MAGIC_64 X86_64 ALL 0x00 OBJECT 3336 SUBSECTIONS_VIA_SYMBOLS
/sw/lib/libfftw3.a(alloc.o):
Nagłówek Macha
      magic cputype cpusubtype kapsle typu filetype ncmds sizeofcmds flagi
MH_MAGIC_64 X86_64 ALL 0x00 OBJECT 3416 SUBSECTIONS_VIA_SYMBOLS
...
Jiahao Chen
źródło
Aby dodać do tej odpowiedzi, wolę otool od pliku lub lipo. Wypróbowałem file, lipo i otool z biblioteką fat na iOS, a otool jako jedyny pokazał mi, że zawiera pliki dla i386 (iPhone Simulator) oraz dla armv6, armv7 i armv7s (iPhone OS).
Roberto,
1
UWAGA: jeśli chcesz sprawdzić, czy twoja biblioteka jest gruba, czy nie, użyj "otool -arch all"; w przeciwnym razie zgłosi tylko jedną architekturę na plik .o. Szybki przegląd architektur w .a, „otool -f”
Paul Du Bois
4

Odkryłem, że jako alternatywa objdumpmoże działać dobrze. Na przykład w swoim środowisku tworzę archiwa bibliotek za pomocą vxWorks i muszę je łączyć z innymi projektami. Aby sprawdzić, czy archiwum jest poprawną architekturą, mógłbym zrobić coś takiego (składnia 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;

Ten przykład nie jest do końca poprawny, ponieważ pojawiają się pewne wiersze, które nie mówią elf32-sparc-vxworks, ale łatwo jest to dostosować.

Jedną z fajnych korzyści jest to objdump, że lub podobnie nazwany wariant jest instalowany w większości systemów operacyjnych * nix, podczas gdy narzędzia sugerowane w innych odpowiedziach nie.

edytuj Po prostu przyszło mi do głowy, że OP pyta na OSX. Przepraszam.

Brian Vandenberg
źródło
Aby użyć objdump, możesz zainstalować GNU Binutils przez MacPorts. Aby zobaczyć wszystkie dostępne architektury, po prostu wykonaj port search binutils. Narzędzia do programowania natywnego są poprzedzone, aby uniknąć konfliktów (np. gobjdumpZamiast objdump). Dla wygody możesz chcieć utworzyć alias.
Stefan Schmidt
3

Ten skrypt bash pomoże ci programowo pobrać listę architektur do zmiennej.

list_archs.sh:

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

Przykład użycia:

./list_archs.sh /usr/lib/libc.dylib
x86_64 i386
bleater
źródło