Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What determines linking behaviour for GHC on OS X?

I'm observing different linking behaviour between two machines when compiling a binary.

Each has the same GHC (7.8.3), same code, same flags (-Wall -O2), same libgmp (installed by Homebrew on each):

machine-one$ otool -L my-binary
my-binary:
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
        /usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)

machine-two$ otool -L my-binary
my-binary:
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
        /usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)
        /usr/local/lib/libgmp.10.dylib (compatibility version 13.0.0, current version 13.0.0)

I can't for the life of me figure out why libgmp is linked dynamically on the second machine.

In terms of differences I've been able to recognize: GHC has been installed via the binary distribution for OS X on the first machine and Homebrew on the second. For C compilers, we have:

machine-one$ cc --version
Apple LLVM version 6.0 (clang-600.0.51) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin13.4.0
Thread model: posix

machine-two$ cc --version
Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin13.4.0
Thread model: posix

What typically determines the linking behaviour, and how can I enforce one linking method or the other?

EDIT: I've observed the same behaviour happening with zlib on yet another machine, so it's not a GMP-specific issue.

EDIT: I've plucked ghc --info from each of the machines, here they are for machine one and machine two. And here's the diff between the two as well.

EDIT: I've reinstalled ghc on machine two via the distribution binary, and sure enough libgmp is not dynamically linked when I recompile my binary. So it seems like this is related to installing GHC via Homebrew.

Still quite interested in what's going on exactly.

like image 348
jtobin Avatar asked Dec 05 '14 19:12

jtobin


1 Answers

The crucial difference is that machine #2 has /usr/local/lib in the linker path, and is using brew's linker (/usr/local/Library/ENV/4.3/ld). ghc still uses an external linker, even if it isn't using the C backend for code generation, so you can combine Haskell code with code written in other languages (crucial for Haskell's many FFI bindings to third-party libraries). So you should really be asking the brew people why things get linked differently. It's not actually a ghc issue.

like image 86
Neil Mayhew Avatar answered Nov 03 '22 17:11

Neil Mayhew