Building LLV as a shared library on most platforms is trivial. It’s just a matter of enabling a flag on the configure phase of the build.
I actually use brew to build it, but the principle is the same:
brew install llvm --shared
However, just building it like this on Mac OS X 10.6 results in the following errors when loading the library on Ruby-FFI:
dyld: loaded: /Users/<user>/llvm/2.8/lib/libLLVM-2.8.dylib dyld: lazy symbol binding failed: Symbol not found: __ZN4llvm2cl6Option11addArgumentEv Referenced from: /Users/<user>/llvm/2.8/lib/libLLVM-2.8.dylib Expected in: flat namespace dyld: Symbol not found: __ZN4llvm2cl6Option11addArgumentEv Referenced from: /Users/<user>/llvm/2.8/lib/libLLVM-2.8.dylib Expected in: flat namespace Trace/BPT trap
After some investigation and an e-mail exchange with Takanori Ishikawa, I arrived at the following patch which solves the problem and allows LLVM to load cleanly as a shared library:
diff --git a/Makefile.rules b/Makefile.rules index 9cff105..44d5b2d 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -497,7 +497,7 @@ ifeq ($(HOST_OS),Darwin) # Get "4" out of 10.4 for later pieces in the makefile. DARWIN_MAJVERS := $(shell echo $(DARWIN_VERSION)| sed -E 's/10.([0-9]).*/\1/') - SharedLinkOptions=-Wl,-flat_namespace -Wl,-undefined,suppress \ + SharedLinkOptions=-Wl,-undefined,dynamic_lookup \ -dynamiclib ifneq ($(ARCH),ARM) SharedLinkOptions += -mmacosx-version-min=$(DARWIN_VERSION)
The options above use the default two-level namespace on OS X and change name resolution to run-time resolution.
Using those options doesn’t seem to have any ill effects but I’m curious why LLVM doesn’t do that already, especially considering many other dynamic libraries for Mac OS X are compiled using the new options specified above. In fact, the former options actually seem to be remnants from pre-10.3 days. Just in case, I’ve asked that very question on the LLVM-dev mailing list.
Meanwhile, the patch works for me. I also made available a modified version for brew. YMMV.