90

We distribute in Linux a static lib in both 64-bit and 32-bit versions. When troubleshooting a customer, I would like my diagnostic shell script to quickly eliminate the issue by checking the .a archive file to detetmine whether it is 32 or 64 bit. The methods that occur to me are less than elegant:

  1. extract a .o member and ask the "file" command (e.g., ELF 32-bit etc)

  2. start including a dummy member coded to indicate, e.g. 32bit.o/64bit.o and use "ar -t" to check

I have tried "strings xyz.a | grep 32" but this doesn't work well over versions. Not a heartbreaker problem, but if you know of an elegant solution, I would like to know.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
cvsdave
  • 1,576
  • 2
  • 12
  • 18
  • I know about http://stackoverflow.com/questions/184502/on-a-unix-linux-system-how-can-i-learn-more-about-a-mylib-a-archive , looking for a better soln. – cvsdave Apr 14 '11 at 15:04
  • 2
    The solution in the other question seems to address the problem quite neatly, but a quick way is nm foo.a | grep '^0' | head -1 | wc -c - if the result is 17 (16+1 == 8bytes + 1 char for line return), it's 64bit, if it's 9 it's 32bit (8+1 == 4bytes + 1 char for line return) – Anya Shenanigans Apr 14 '11 at 15:45
  • What if I get 14? o_0 – Almo Apr 28 '15 at 20:29

5 Answers5

127

objdump seems like the best way:

objdump -f libfoo.a | grep ^architecture
caf
  • 233,326
  • 40
  • 323
  • 462
  • 2
    `file` is easier to read as stated below http://stackoverflow.com/a/8909086/233906 – Cerber Mar 25 '13 at 16:18
  • 1
    I get `architecture: i386:x86-64, flags 0x00000039:`.. does it mean that it's both..? that's unlikely. please help :D – graywolf May 10 '16 at 15:55
  • 12
    @Paladin: That's 64 bit - the x86 architectures are described by objdump as `i386` (plain old IA32), `i386:x86-64` (AMD64) and `i386:x64-32` (the X32 32-bit-address-space-in-long-mode architecture). – caf May 11 '16 at 01:30
  • @caf Thanks a lot :) – graywolf May 11 '16 at 09:03
  • 1
    The flag '-f' in 'objdump' specifies to display the contents of the overall file header of the library 'libfoo.a'. This output from 'objdump' is then piped into the grep command which searches for the word 'architecture'. The character '^' signifies that 'architecture' should begin the line. – laker93 Feb 09 '18 at 16:53
  • 4
    Clean it up and remove dupes: `objdump -f lib.a | grep ^architecture | cut -d' ' -f-2 | sort -u` :) – legends2k Jun 01 '18 at 23:42
39

The simplest way is to use the file command.

$ file <.so file or .a file>
Nathan F.
  • 3,250
  • 3
  • 35
  • 69
pankaj kapoor
  • 463
  • 4
  • 2
  • 31
    in the msys environment this simply echos *: current ar archive*, not the target architecture. – scones Jul 28 '13 at 20:30
  • 11
    Likewise in my current Linux (Ubuntu) environment. – Asherah Apr 25 '14 at 09:42
  • 4
    likewise in centos7 – Chaim Geretz Aug 17 '16 at 21:43
  • It works fine on Ubuntu 16.04. (1) `file armeabi/libpique.so` --> `libpique.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, stripped`. (2) `file x86/libpique.so` --> `libpique.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped` – rpattabi Dec 09 '16 at 06:00
  • 5
    A .so file and a .a file are not the same thing. Showing that this works for a shared library is not the same as showing that it works with a static library. The original question is about a static library (.a file). In my case (using MSYS) the objdump solution posted by caf works where using file just prints 'ar archive' the same as scones gets. – Sean Burton Feb 22 '17 at 16:06
17

Just use the file command; i.e. file library.so

Monolo
  • 18,205
  • 17
  • 69
  • 103
Erik
  • 187
  • 1
  • 2
5

oops, that missing sed means that it was displaying to many items.

Just in an answer:

count=$(nm foo.a | grep '^0' | head -1 | sed 's/ .*//' | wc -c)
((count == 17)) && echo 64bit
((count == 9)) && echo 32bit
((count == 0)) && echo '??bit'

How it's supposed to work:

  • nm - get the symbols from the library
  • grep - get lines starting with a hex string (address of symbol in file)
  • head - get the first line
  • sed - remove everything past the whitespace, including the whitespace
  • wc - count the number of characters.

In a 32 bit environment, you get addresses made up of 8 hex digits, adding the new line gives you 9, In a 64bit environment, you get addresses made up of 16 hex digits, adding the new line gives you 17.

Anya Shenanigans
  • 91,618
  • 3
  • 107
  • 122
1

If there are functions that are specific to a particular version you could try nm then grep for the function.

ColWhi
  • 1,077
  • 6
  • 16
  • You might be able to write some code that looks for specific bytes in the library. You could try using od on both files and finding differences between the two. – ColWhi Apr 14 '11 at 15:38
  • 1
    Another solution would be to rename the libraries. – ColWhi Apr 15 '11 at 07:35