I need to run DTrace on 32-bit executables on OSX. I have two machines, both running OSX 10.8.2. On one of them, /usr/lib/dtrace/libdtrace_dyld.dylib is a fat binary, on the other it isn't:
/usr/lib/dtrace/libdtrace_dyld.dylib: Mach-O universal binary with 2 architectures
/usr/lib/dtrace/libdtrace_dyld.dylib (for architecture i386): Mach-O dynamically linked shared library i386
/usr/lib/dtrace/libdtrace_dyld.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
vs
/usr/lib/dtrace/libdtrace_dyld.dylib: Mach-O 64-bit dynamically linked shared library x86_64
Where do these two come from? How do I get the fat one "officially", i.e. without just copying it over from the other machine?
This is what happens when I try to run dtrace on a 32-bit executable with the 64-bit only dylib, btw:
dyld: could not load inserted library: /usr/lib/dtrace/libdtrace_dyld.dylib
The DTrace library on Mac OS X ML is the fat binary (i386, x86_64). Your second machine lacks 32bit because someone removed it. Probably one of that system "optimizers" was run on the system.
SHA (shasum /usr/lib/dtrace/libdtrace_dyld.dylib) of the lib on my machine is 0722f971d9999245cda234ba5fd3119820fa348a. I've tested it on a few other machines and it matched. It also matched on a machine with fresh installation of Mac OS X ML. That means it's OK to just copy it.
The only other way to restore it is to either restore it from backup or reinstall the system.
Related
I need to build a library (Ipopt) on Mac OS X and use it from two different programs (Python & Matlab). However, one program is 32-bit and the other is 64-bit. Do I have to build two separate libraries of the two architectures then set the path accordingly for each program? Or can I build both architectures in the same library file(s) and the program will select the correct architecture to load? If I can, then how?
Thanks!
You can build both architectures and combine them into a single binary. The tool to do this is lipo.
For example, if you had built libpopt as a 32 bit library and placed it in lib/, and built it again as a 64 bit library and placed that in lib64/, then the command to combine these two could be:
lipo lib/libpopt.a lib64/libpopt.a -create -output libUniversal/libpopt.a
For more information, see the lipo man page (here, or through man lipo).
I'm using Xcode 3.2.3 on Mac OS X 10.6.6 on a Mac Pro to build revision 5fd480ef577f of GrowlTunes from the growl-development repository.
With a clean build from a virgin checkout, this is what I get:
% gdb build/Debug/GrowlTunes.app/Contents/MacOS/GrowlTunes
GNU gdb 6.3.50-20050815 (Apple version gdb-1469) (Wed May 5 04:41:34 UTC 2010)
[blah blah blah]
This GDB was configured as "--host=x86_64-apple-darwin --target=powerpc-apple-darwin"...Reading symbols for shared libraries ......... done
(gdb) run
Starting program: /Volumes/RAM Disk/growl-development/Extras/GrowlTunes/build/Debug/GrowlTunes.app/Contents/MacOS/GrowlTunes
Don't know how to run. Try "help target".
When I try it in Xcode, it apparently does some internal test that fails, because it doesn't even list GDB as an option. Since there are no other debuggers (in this version of Xcode) for Cocoa applications, the pop-up menus related to debugging in the target Info window are empty, and attempting to run the app does nothing—the Run button switches back to being the Run button immediately.
The target is built for 32-bit PowerPC and 64-bit Intel:
% file build/Debug/GrowlTunes.app/Contents/MacOS/GrowlTunes
build/Debug/GrowlTunes.app/Contents/MacOS/GrowlTunes: Mach-O universal binary with 2 architectures
build/Debug/GrowlTunes.app/Contents/MacOS/GrowlTunes (for architecture ppc7400): Mach-O executable ppc
build/Debug/GrowlTunes.app/Contents/MacOS/GrowlTunes (for architecture x86_64): Mach-O 64-bit executable x86_64
I can run it directly, either from the terminal or from Finder, but that doesn't help me step-by-step debug.
This isn't a cross compilation scenario; I mean to run the 64-bit Intel architecture, which is my machine's native architecture, not the PowerPC architecture.
I'm guessing this is some build misconfiguration somewhere in the project, but I've no clue what or where. Any suggestions?
Workaround from a contact of mine:
gdb -arch x86_64 build/Debug/GrowlTunes.app/Contents/MacOS/GrowlTunes
I'd still appreciate a solution that would enable me to run/debug the app in Xcode.
Switching the order of the architectures in the relevant build setting fixed the problem both in gdb and in Xcode. This is a lame solution, and I'd still welcome a better one, but at least it works.
At gdb prompt, try 'set arch x86_64' or 'set arch i386:x86-64' (without quotes of course; I am a total newbie with gdb, I am lurking for solutions for other problems)
Is this legal? I'm getting an error "Can't find <lib>.framework/Versions/4/<lib>" from the linker. In this case, <lib> is 'QtGui' that has been built as an i386 framework (not universal), but another (third party) lib I'm linking to (that uses QtGui) is universal.
I'm thinking everything has to be built universal or not...
You can link a non-universal framework (say i386 only) with a universal framework (say with i386 and x86_64) to make an i386 binary.
Of course you can't make an x86_64 binary in this case.
Note that if your Mac has a 64 bit CPU, the linker defaults to mae an x86_64 binary. So the linker will complain if any of your library does not have the x86_64 part. If you want to create an i386 binary, you need to specify that explicitly on the command line.
Roger.
Turns out my issue actually stems from bad embedded paths in the external libraries that have to be reset (which I didn't think would affect links, but it does).
The universal build issue was a suspected culprit, but no.
Thanks,
rickb
I'm actually developping an application for iPhone and I need to use a library, initially dedicated to a Linux environment. Since I'm using a Mac (with Snow Leopard and Intel Core Duo), I guess it's possible to use this library in my app.
My library has 3 files: a file .h, a file .a and a file .so (both .a and .so are in /Developer/usr/lib). In addition I have included the .h i nmy code and I've added the .a in XCode has a framework (and it works because XCode find the .so compiling).
For your info when I use the command "file" for the file .so, I have:
ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped
When I compile for the Xcode Simulator, I have a warning and an error.
The warning is:
In /Developer/usr/lib/mylib.so, file was built for unsupported
file format which is not the architecture being linked (i386)
The error is:
"_mylib_fct", referenced from:
-[MyAppAppDelegate applicationDidBecomeActive:] in
MyAppAppDelegate.o Symbol(s) not found Collect2: ld returned 1
exit status
When I compile for the Device 3.0 with architecture arm6, I also have the same error, but the warning is quite different:
ln /Users/Pablo/MyApp/mylib.a file is not of required architecture
I try to solve this and make the app working with this lib since days, and I don't understand why the compiler is complaining... is it a 32/64 bits issues? How can I deal with that?
Mac OS X is not binary compatible with Linux. It cannot load ELF images, nor does it share the same ABI.
It can only load MACH images, e.g.:
file /usr/lib/libcrypto.dylib
[..]
/usr/lib/libcrypto.dylib (for architecture i386): Mach-O dynamically linked shared library i386
Read the dlopen man page for details.
AFAIK If Mac OS is not binary compatible to the specific Linux version, the library should not be usable in your projects.
Also you need two versions, one for the simulator (i386) and one for the device (arm..).
I would like to know how you can support i386 and ppc architectures for programs at /bin.
I run for instance
bin $ file amber
I get
amber: setgid Mach-O universal binary with 2 architectures
amber (for architecture i386): Mach-O executable i386
amber (for architecture ppc): Mach-O executable ppc
How do programs support i386 and ppc in the source code?
In other words, which components can you remove, for instance, in /bin/amber if you remove the support of ppc -architecture?
It's called a Universal binary. In short, the executable contains both types of executable code. Apple has a published document describing how developers should build their applications to run on either platform.
The executable lipo can be used to remove either version of the executable from the file. If you want your executables to contain only one version, you can use lipo to achieve this.
Be aware that there is more than just ppc and i386, although these are the "safest" architectures to choose for a Universal binary. Read the manpage for arch; there you can see that a modern OSX binary is likely to contain any of ppc, ppc64, i386 or x86_64. There are many more listed, but they exist there for completeness.
It's called a fat binary.
There's a copy of the native code for both architectures in the binary. The binary format and the operating system have to support it, so it can know where to look in the file for the correct code.