163

I'm interested in verifying if a given iPhone static library has been built for ARM or Intel.

It's more curiosity than anything. Is there some kind of Mac OS X or BSD specific tool to do this? This post gives an example in Linux.

6 Answers 6

288

Another option is lipo; its output is brief and more readable than otool's.

An example:

% 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
%
2
  • Just verified this with an old PJSIP .a file. armv7. Thanks. Commented Jul 27, 2015 at 17:59
  • How can I check minimum iOS version of a target architecture (.a) ?
    – DevSemenuk
    Commented Sep 14, 2022 at 8:46
73

file will probably tell you. otool certainly should be able to. But I'd try file first, e.g.

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

Example with archive:

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
5
  • 38
    In my experience file often fails. Commented Feb 13, 2012 at 15:41
  • 4
    See the answer about lipo further down, always works. Commented Feb 8, 2014 at 12:33
  • I've noticed that if the .a is is not ranlib'd, file sometimes reports less information. Commented May 2, 2014 at 2:09
  • 4
    Now in 2015 you should use lipo. See the answer below.
    – derFunk
    Commented Feb 12, 2015 at 11:10
  • 2
    Unfortunately this hasn't worked for several OS versions.
    – rmcclellan
    Commented Mar 30, 2017 at 15:24
66

As mentioned earlier, file does not always work. otool -hv -arch all is probably the closest thing that is guaranteed to work - it gives architecture information for every single object file in the library.

Example:

% otool -hv /sw/lib/libfftw3.a
Archive : /sw/lib/libfftw3.a
/sw/lib/libfftw3.a(align.o):
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL  0x00      OBJECT     3        336 SUBSECTIONS_VIA_SYMBOLS
/sw/lib/libfftw3.a(alloc.o):
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL  0x00      OBJECT     3        416 SUBSECTIONS_VIA_SYMBOLS
...
2
  • Just to add to this answer, I prefer otool over file or lipo. I tried file, lipo and otool with an iOS fat library and otool was the only one that showed me that it contained files for i386 (iPhone Simulator) and for armv6, armv7 and armv7s (iPhone OS).
    – Roberto
    Commented Apr 8, 2013 at 1:10
  • 1
    NOTE: if you want to check whether your library is fat or not, you want to use "otool -arch all"; otherwise, it will report only one architecture per .o file. For a quick overview of the architectures in your .a, "otool -f" Commented May 2, 2014 at 2:11
7

If anyone comes here looking for answers about how to tell whether a library (or the object files in it) are intended for Mac Catalyst, use otool -l to dump the load commands. Find the LC_BUILD_VERSION section for any object. Mac Catalyst is identified by platform 6 rather than platform 1.

6

This bash script will help you programmatically get a list of architectures into a variable.

list_archs.sh:

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

Usage example:

./list_archs.sh /usr/lib/libc.dylib
x86_64 i386
4

As an alternative, I've found objdump can work well. As an example, in my environment I build library archives with vxWorks and need to link those into other projects. To test whether the archive is the correct architecture, I could do something like the following (bash syntax):

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;

This example isn't precisely correct, because some lines DO show up that don't say elf32-sparc-vxworks, but it's easy enough to adapt this.

One nice benefit of this is that objdump, or a similarly named variant, is installed on most *nix operating systems, whereas tools suggested in other responses aren't.

edit It just occurred to me the OP was asking on OSX. My apologies.

1
  • To use objdump you can install the GNU Binutils via MacPorts. To see all available architectures just execute port search binutils. The tools for native development are prefixed to avoid conflicts (e.g. gobjdump instead of objdump). You might want to create an alias for convenience. Commented Feb 13, 2012 at 15:37

Not the answer you're looking for? Browse other questions tagged or ask your own question.