otool -L shows what libraries are linked to a host a program.
otool -L <path to a binary of a host program>
On 10.4 and 10.5, if a static library was linked, otool didn’t display them ( as far as I remember. )
OK. Fortunately, I have a program I built at Harris corp.
For the program, I linked a postgreSQL static library, i.e. libq.a. It is very reasonable. The binary code of a static library is merged with a host program. So, it doesn’t have any information about what libraries are linked.
However, when I created a new project with 10.6 as a target, it is whole lot different.
As you can see, libMagick++.a is specified in a project file. However, when I checked the binary of a host program with otool, it said that libMagick++.4.dylib was linked.
From Snow Leopard (10.6), Mac OS X framework were all linked with dynamic library. libstdc++ for C++ was also changed to be linked by default even when it was not specified. (Umm… probably libstdc++ case was done in Mac OS X 10.5 Leopard, because at that time the decoration name in a compiled binary adopted Unix 2003 spec, and I remember that when they adopted Unix 2003 spec, they dropped explicit linkage to libstdc++.
On my Twitter time line, godrm suspect the architecture. However, they are all 64bit for the libMagick++.
Also, he raised question about build log. To see if -l<library name> is actually logged. (Well, before I suspected this, I checked all of this. But to people who still don’t have clue, here is another screenshot.
However, this -l<library name> doesn’t help, because no matter what library type is linked, they are all specified with -l<library name>
Why this problem matter is that it will confuse developers. When a developer decides to deploy his/her program, he/she needs to make sure all dependency is resolved. Although it is possible to deploy a Mac app with dynamic library by adding a new copy build phase, which creates a “Framework” folder in the app bundle. All dynamic binaries are set to be copied to that folder by the developer. Then when the app is launched on a system which doesn’t have the library, it first searches its own bundle and find those libraries.
However, cleaner option is to link to static libraries. In this case, the binary of the static libraries are embedded in the main host program. Then it is very clean. Downside of this is that the size of host program will be bigger. However, coping dynamic libraries into the app bundle makes the bundle size bigger. So, there is no difference between the two.
Why we prefer dynamic library usually is that we want to reduce size of a S/W product especially when we can be sure that the libraries are already installed on users’ HDDs.
However, if otool says like this for libGraphicsMagick++.a and libMagick++.a, it is not easy to be sure of safety of distribution by linking static libraries.
godrm also mentioned if those libraries were different from other libraries. Well.. in a way that the static library somehow transfer linkage to a dynamic library? However, the size of those static libraries are almost same to dynamic libraries.
However, libpq.a is somewhat different. I tried to link to it by changing the host program to 32bit.
So, maybe it is due to 64bit vs. 32bit. However PPC64 was different ( do you remember 64bit PowerPC? ). Anyway Mach-O architecture for Intel and PowerPC were said to be different slightly. So, maybe this part was struck by that difference.
Does any one know if there is any Apple’s official document on this issue?