Why does otool -L say dynamic libraries are linked when static libraries are configured to be linked?

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.

A static library, libq.a, is linked and otool can't display it

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.

Although a static library, libMagick++.a, is linked, otool says that its dylib version is linked.

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++.

The both, static & dynamic, are 64 bit binaries

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.

The interested library is logged to be linked.

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.

Those *.a are not stub libraries. Compare the size from their dynamic version

However, libpq.a is somewhat different. I tried to link to it by changing the host program to 32bit.

postgreSQL library was linked but otool -L didn't reveal it, as I said above

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?

One response to this post.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: