Forcing the Mac OS X linker to choose a static libraryEdit
I am currently working on a Ruby extension written in C which uses an ANTLR-generated parser and must therefore link against the C target runtime library.
By default, when you build and install the C target runtime the following items are installed:
/usr/local/lib/libantlr3c.dylib
/usr/local/lib/libantlr3c.la
/usr/local/lib/libantlr3c.a
It appears that the Mac OS X linker is hard-wired to search dynamic libraries before static ones, so when build my Ruby extension I found that the dynamic library was used. The linker invocation (as generated by mkmf was as follows:
cc -dynamic -bundle -undefined suppress -flat_namespace -L"/usr/local/lib" \
-o walrus_parser.bundle walrus_parser.o WalrusLexer.o WalrusParser.o \
-lantlr3c -lpthread -ldl -lobjc
And otool (otool -L walrus_parser.bundle
) indicates that the followed shared libraries were used:
walrus_parser.bundle:
/usr/local/lib/libantlr3c.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.5.1)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0)
Note that you cannot pass a file extension to the -l
switch (-lantlr3c.a
) to force the static library to be used. One way to force the static library to be used is to simply remove the dynamic version. A less destructive way is recommended here.
Basically, the idea is:
- Create symlink
libname_s.a
which points to the static liblibname.a
. - Tell the compiler to link against
libname_s
(ie.-lname_s
). - Depending on where you create the symlink, may be necessary to add a
-L
switch so linker knows where to find it (for example, if you don’t have the administrator privileges necessary to write to/usr/local/
or don’t wish to modify that directory).