Mac No Suitable Image Found
14:36 Wednesday, 23 February 2011
If you’re building native extensions for python or ruby on a Mac and you get an error like:
no suitable image found
It probably means the language and extension were compiled for different architectures, i.e. 32-bit vs 64-bit or i386 vs x86_64. I use fink on the Mac and it defaults to compiling 32-bit versions. You can tell fink to default to 64-bit when you do an initial install from source but it’s not as well tested as 32-bit and 32-bit works fine so why bother? However, 10.6, left to its own devices, will compile code to 64-bit versions. So we need to tell the system to compile 32-bit versions. The option to cc/ld is:
-arch i386
A common way to set compiler options is to set the CFLAGS environment variable:
setenv CFLAGS "-arch i386"
This works fine for building python extensions using a standard setuptools setup.py file. But ruby gems are another kettle of spanners…
It seems (at least with ruby gems from fink on a Mac) the environment is ignored when it comes to compiling native extensions. Rather the same options that were used to compile ruby are used. These are read from a file called rbconfig.rb - in fink the location is /sw/lib/ruby/1.8/i686-darwin/rbconfig.rb Now, the issue seems to be that as far as ruby is concerned when it was compiled is never got the “-arch i386” flag. But it did. It just doesn’t know it. When compiling on 10.6 fink wraps the cc command with a shell script (in /sw/var/lib/fink/path-prefix-10.6) which adds the “-arch i386” flag before finally calling cc with the specified arguments.
So we simply edit /sw/lib/ruby/1.8/i686-darwin/rbconfig.rb to add the “-arch i386” option. For example as in the two lines below.
CONFIG["LDFLAGS"] = "-arch i386 -L. -L/sw/lib/system-openssl/lib -L/sw/lib" CONFIG["CFLAGS"] = "-arch i386 -g -Os -fno-schedule-insns2 -fno-common -pipe -fno-common $(cflags)"
Now it all works.
The ruby gems stuff all came about because I was trying out Vagrant as recommended on the Maestro blog.