A macOS static linking mystery
Ryan Scott
ryan.gl.scott at gmail.com
Mon Aug 8 11:29:38 UTC 2022
I'm trying to diagnose strange GHC linking behavior which, as far as I can
tell, only occurs on macOS. I feel a bit out of my league debugging this,
so I'm hoping someone knows what is causing this.
When building the Haskell libffi library [1], it will link pass -lffi to
GHC. Typically, most installations of libffi will include both a static
library (libffi.a) and a shared library (libffi.{so,dylib,dll}). My
impression is that when the linker finds both, it will default to the
shared library. This is definitely the case on Linux and Windows, at least.
An exception to this rule is macOS, however. On macOS, building libffi
always appears to default to linking against the static version of libffi,
even when a dynamic version is also available. To reproduce this
phenomenon, check out libffi [1] and run the following commands:
$ brew install libffi # If it is not already installed
$ cabal build ctime
$ otool -L $(cabal list-bin ctime)
The output reveals that the compiled executable does not dynamically link
against libffi.dylib:
$ otool -L $(cabal list-bin ctime)
/Users/rscott/Documents/Hacking/Haskell/libffi/dist-newstyle/build/x86_64-osx/ghc-8.10.7/libffi-examples-0.1/x/ctime/build/ctime/ctime:
/usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current
version 7.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0,
current version 1281.100.1)
/usr/lib/libcharset.1.dylib (compatibility version 2.0.0,
current version 2.0.0)
This is exceedingly strange, since my Hombrew installation does in fact
provide libffi.dylib:
$ ls -alh ~/Software/homebrew/Cellar/libffi/3.4.2/lib/
total 232
drwxr-xr-x 6 rscott 1340850540 192B Aug 7 09:38 .
drwxr-xr-x 11 rscott 1340850540 352B Aug 7 08:51 ..
-rw-r--r-- 1 rscott 1340850540 70K Aug 7 08:51 libffi.8.dylib
-r--r--r-- 1 rscott 1340850540 41K Jun 28 2021 libffi.a
lrwxr-xr-x 1 rscott 1340850540 14B Jun 28 2021 libffi.dylib ->
libffi.8.dylib
drwxr-xr-x 3 rscott 1340850540 96B Aug 7 08:51 pkgconfig
What's more, this only seems to happen when building the libffi library in
particular. If I try building another library that has a C extra-libraries
dependency, such as HsOpenSSL, then I can find its dynamic dependencies
(libssl.dylib and libcrypto.dylib) using otool:
$ otool -L
dist-newstyle/build/x86_64-osx/ghc-8.10.7/HsOpenSSL-0.11.7.2/build/test-dsa/test-dsa
dist-newstyle/build/x86_64-osx/ghc-8.10.7/HsOpenSSL-0.11.7.2/build/test-dsa/test-dsa:
/usr/local/opt/openssl at 1.1/lib/libssl.1.1.dylib (compatibility
version 1.1.0, current version 1.1.0)
/usr/local/opt/openssl at 1.1/lib/libcrypto.1.1.dylib
(compatibility version 1.1.0, current version 1.1.0)
/usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current
version 7.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0,
current version 1281.100.1)
/usr/lib/libcharset.1.dylib (compatibility version 2.0.0,
current version 2.0.0)
I'm at a bit of a loss trying to figure out why this only happens for
libffi, and only on macOS. To make things even stranger, this only seems to
happen when using GHC. If I try to compile a simple libffi C program using
-lffi, for instance, then otool finds libffi.dylib. Is there something
about GHC's linking behavior that would cause this?
Ryan S.
-----
[1] https://github.com/remiturk/libffi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-devs/attachments/20220808/addc01a9/attachment.html>
More information about the ghc-devs
mailing list