Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"otool" and "file" can't show architecture of the ".a" file

I have builded some static libraries for ARM7 with cMake. Usually, when you use next command for .a file, it shows architectures:

f.e.

mac:libs User$ file ./libcurl.a 
./libcurl.a: Mach-O universal binary with 3 architectures
./libcurl.a (for architecture armv6):   current ar archive random library
./libcurl.a (for architecture armv7):   current ar archive random library
./libcurl.a (for architecture i386):    current ar archive random library

or f.e.

mac:libs User$ otool -vf ./libboost_regex.a 
Fat headers
fat_magic FAT_MAGIC
nfat_arch 3
architecture armv6
    cputype CPU_TYPE_ARM
    cpusubtype CPU_SUBTYPE_ARM_V6
    capabilities 0x0
    offset 68
    size 9550024
    align 2^2 (4)
architecture armv7
    cputype CPU_TYPE_ARM
    cpusubtype CPU_SUBTYPE_ARM_V7
    capabilities 0x0
    offset 9550092
    size 9390544
    align 2^2 (4)
architecture i386
    cputype CPU_TYPE_I386
    cpusubtype CPU_SUBTYPE_I386_ALL
    capabilities 0x0
    offset 18940636
    size 9595040
    align 2^2 (4)

but now, when i build my librarie, "otool" and "file" can't show architecture of it.

mac:libs User$ otool -vf ./mylib_meta.a 
Archive : ./mylib_meta.a

What does it mean? What mistakes can I did with building of my library?

Update: Igor, thanks!

I extracted the object file with commands:

ar -t mylib.a

ar -xv mylib.a myobj.o

-t shows the list of binaries

-xv extracts concrete binary file

like image 661
BergP Avatar asked Jul 04 '13 10:07

BergP


2 Answers

Apple uses two forms of AR archives. The first one is very similar to the traditional Unix archive ("a.out archive") - basically just a bunch of .o files stuck together with a symbol index in front:

"<!arch>\n"

header 0
SYMDEF entry

header 1
object 1

header 2
object 2

...

To determine the architecture for which this archive is intended, you'll need to extract at least one object file and use file or otool on it. The archive header itself does not have this information. (In fact, the object files are not necessarily all for the same arch, and in theory you may have any kind of files, not just objects, but this is unlikely.) You can use the ar utility to extract individual files from an archive.

The other kind is Apple's own invention. They took the "Fat binary/universal binary" concept used for multi-arch Mach-O executables and used it for the archives. So, a "fat" archive looks like this:

  Fat Mach-O header
  Architecture 1 header --+
  Architecture 2 header --|--+
  Architecture 3 header --|--|--+
  [padding]               |  |  |
  Archive 1 <-------------+  |  |
  Archive 2 <----------------+  |
  Archive 3 <-------------------+

In this case file and otool can look at the fat header and list which architectures are supported.

To create or edit fat files (both archives and executables), you can use the lipo tool.

like image 199
Igor Skochinsky Avatar answered Sep 21 '22 01:09

Igor Skochinsky


One alternative is to use objdump from the GNU binutils package (available e.g. via homebrew). On macOS it's renamed gobjdump. Calling it on the archive will display the archive header info, perhaps saving the trouble of extracting the object files (much like you had originally wanted)

> gobjdump -a ./libboost_regex.a
In archive ./libboost_regex.a:
c_regex_traits.o:     file format mach-o-x86-64
rw-r--r-- 502/20 140976 Nov  8 08:03 2018 c_regex_traits.o
cpp_regex_traits.o:     file format mach-o-x86-64
rw-r--r-- 502/20 106424 Nov  8 08:03 2018 cpp_regex_traits.o
...

Late answer, but adding here for future reference.

like image 44
wardw Avatar answered Sep 18 '22 01:09

wardw