What determines linking behaviour for GHC on OS X?
Asked Answered
M

1

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.

Magistrate answered 5/12, 2014 at 19:52 Comment(6)
I think it might depend in part on how GHC was compiled. Could the two distributions you used have been compiled differently?Roofdeck
A similar question: (link) which might help.Nilson
@Roofdeck 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.Magistrate
Can you add the output of command 'ghc --info' to your question?Gruel
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)Gruel
Reading the diff 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 https://mcmap.net/q/816722/-using-homebrew-gcc-and-llvm-with-c-11Hiltan
G
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.

Graphic answered 14/5, 2015 at 21:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.