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.awhich 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
-Lswitch 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).