MacOS X uses fat files.
A fat bundle contains data for different architectures. Here are some examples:
root@gilva:/Applications/Utilities/Terminal.app/Contents/MacOS[02:03 AM]# file * Terminal: Mach-O fat file with 2 architectures Terminal (for architecture i386): Mach-O executable i386 Terminal (for architecture ppc): Mach-O executable ppc root@gilva:/Applications/Utilities/Terminal.app/Contents/MacOS[02:03 AM]#
or even:
stany@gilva:/System/Library/Frameworks/Accelerate.framework/Versions/A[02:07 AM]$ file Accelerate Accelerate: Mach-O fat file with 3 architectures Accelerate (for architecture i386): Mach-O dynamically linked shared library i386 Accelerate (for architecture ppc): Mach-O dynamically linked shared library ppc Accelerate (for architecture ppc64): Mach-O 64-bit dynamically linked shared library ppc64 stany@gilva:/System/Library/Frameworks/Accelerate.framework/Versions/A[02:07 AM]$
In order to operate on fat bundles Apple provides a utility called lipo.
If you are in a situation where you are limited by processor architecture – for example, if you never expect to use internal hard drive of your iBook in firewire target mode to boot up an i386 system – it is possible to remove the extra “fat” from fat binaries, to save some disk space.
Here is an example:
root@gilva:/Applications/Utilities/Terminal.app/Contents/MacOS[02:09 AM]# mv Terminal Terminal.bak root@gilva:/Applications/Utilities/Terminal.app/Contents/MacOS[02:10 AM]# ls Terminal.bak root@gilva:/Applications/Utilities/Terminal.app/Contents/MacOS[02:10 AM]#lipo Terminal.bak -remove i386 -output Terminal root@gilva:/Applications/Utilities/Terminal.app/Contents/MacOS[02:10 AM]# ls -la total 2296 drwxrwxr-x 4 root admin 136 Sep 6 02:10 . drwxrwxr-x 7 root admin 238 Aug 31 00:07 .. -rwxr-xr-x 1 root admin 386472 Sep 6 02:10 Terminal -rwxrwxr-x 1 root admin 783784 May 14 22:22 Terminal.bak root@gilva:/Applications/Utilities/Terminal.app/Contents/MacOS[02:10 AM]# file * Terminal: Mach-O fat file with 1 architecture Terminal (for architecture ppc): Mach-O executable ppc Terminal.bak: Mach-O fat file with 2 architectures Terminal.bak (for architecture i386): Mach-O executable i386 Terminal.bak (for architecture ppc): Mach-O executable ppc root@gilva:/Applications/Utilities/Terminal.app/Contents/MacOS[02:10 AM]#
A quick test confirms that Terminal.app continues to run as before, however to make sure that everything is kosher I would probably want to correct permissions on the new binary to match what it was on the original.
Disk space saving will not be big, as an average .app consists of many other objects besides the executable itself, so this is probably not a very big issue. If one tries to remove a non-existing architecture from a binary, lipo will complain:
root@gilva:/Applications/Utilities/Terminal.app/Contents/MacOS[02:18 AM]# lipo Terminal.bak -remove ppc64 -output Terminal lipo: -remove ppc64 specified but fat file: Terminal.bak does not contain that architecture root@gilva:/Applications/Utilities/Terminal.app/Contents/MacOS[02:19 AM]#
Another interesting option to lipo is -detailed_info:
stany@gilva:~[02:22 AM]$ lipo -detailed_info /System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate Fat header in: /System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate fat_magic 0xcafebabe nfat_arch 3 architecture i386 cputype CPU_TYPE_I386 cpusubtype CPU_SUBTYPE_I386_ALL offset 4096 size 8488 align 2^12 (4096) architecture ppc cputype CPU_TYPE_POWERPC cpusubtype CPU_SUBTYPE_POWERPC_ALL offset 16384 size 8564 align 2^12 (4096) architecture ppc64 cputype CPU_TYPE_POWERPC64 cpusubtype CPU_SUBTYPE_POWERPC_ALL offset 28672 size 8488 align 2^12 (4096) stany@gilva:~[02:22 AM]$
writing a script that processes the output of:
find . -type f -perm -55 -exec file {} ; | grep i386 | sed 's/.for arch.*$//g'
while stripping out the arch, AND not screwing up the system is left as an excercise for the reader. 😛
One thought to “MacOSX: Trimming fat from Mach-O fat files”
Comments are closed.