7

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.

jtobin
  • 3,253
  • 3
  • 18
  • 27
  • I think it might depend in part on how GHC was compiled. Could the two distributions you used have been compiled differently? – dfeuer Dec 05 '14 at 20:07
  • A similar question: [(link)](http://stackoverflow.com/questions/10539857/statically-link-gmp-to-an-haskell-application-using-ghc-llvm) which might help. – ErikR Dec 05 '14 at 20:07
  • @dfeuer GHC was indeed installed differently - via a binary vs via Homebrew - but I can't find any information on what to expect there in either case. @user5402 I understand that one can't pass the static linking flags on OS X as there's no way to statically link `libSystem` and `libiconv`. – jtobin Dec 05 '14 at 20:44
  • Can you add the output of command 'ghc --info' to your question? – harmic Dec 08 '14 at 02:44
  • Interesting. Machine one is using gcc as Haskell C Compiler, while #2 uses clang. They are also using different linkers. Although I would have thought that would have no effect when using native compilation mode (which is the default, I think) – harmic Dec 08 '14 at 22:52
  • Reading the diff https://gist.github.com/jtobin/aed0dba674f46f9bdd41 the official distribution was compiled with ```/usr/bin/gcc``` while the homebrew version with ```clang``` This discusses installing gcc vs clang http://stackoverflow.com/questions/14128298/homebrew-gcc-llvm-and-c11 – gliptak Dec 13 '14 at 19:49

1 Answers1

1

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.

Neil Mayhew
  • 14,206
  • 3
  • 33
  • 25