Skip to content

Instantly share code, notes, and snippets.

@adinapoli
Last active May 25, 2023 08:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adinapoli/d4c33a9d1ea85bcaebdf to your computer and use it in GitHub Desktop.
Save adinapoli/d4c33a9d1ea85bcaebdf to your computer and use it in GitHub Desktop.
dyamic linking woes on Mac OS X Mavericks and GHC 7.8.3

Steps to reproduce

mkdir repro
cd repro
cabal get snappy
cd snappy-0.2.0.2
brew install snappy
cabal sandbox init
cabal install

Then create a simple hello world file:

module Main where

import qualified Data.ByteString as B
import Codec.Compression.Snappy

main :: IO ()
main = do
  f <- B.readFile "foo.jpg"
  B.writeFile "foo.snp" (compress f)

And finally try to compile it:

ghc HelloSnappy.hs
[1 of 3] Compiling Codec.Compression.Snappy.Internal ( Codec/Compression/Snappy/Internal.hs, Codec/Compression/Snappy/Internal.o )
[2 of 3] Compiling Codec.Compression.Snappy ( Codec/Compression/Snappy.hs, Codec/Compression/Snappy.o )
[3 of 3] Compiling Main             ( HelloSnappy.hs, HelloSnappy.o )
Linking HelloSnappy ...
Undefined symbols for architecture x86_64:
  "__hsnappy_GetUncompressedLength", referenced from:
      _c3Jf_info in Snappy.o
  "__hsnappy_MaxCompressedLength", referenced from:
      _c2Fq_info in Internal.o
  "__hsnappy_RawCompress", referenced from:
      _c3Co_info in Snappy.o
  "__hsnappy_RawUncompress", referenced from:
      _c3Ha_info in Snappy.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

The "solution" is to compile referencing the position of the compiled .dylib directory, living inside dist/build:

ghc HelloSnappy.hs -L./dist/dist-sandbox-2e5d78d/build -lHSSnappy-0.2.0.2-ghc7.8.3
Linking HelloSnappy ...

This compiles fine, but still crashed at runtime:

./HelloSnappy
dyld: Library not loaded: @rpath/libHSsnappy-0.2.0.2-ghc7.8.3.dylib
  Referenced from: /Users/adinapoli/programming/haskell/snappy/snappy-0.2.0.2/./HelloSnappy
  Reason: image not found
[1]    1828 trace trap  ./HelloSnappy

Solution is once again to make dlopen aware of the .dylib:

☁  snappy-0.2.0.2  export LD_LIBRARY_PATH=$PWD/dist/dist-sandbox-2e5d78d/build
☁  snappy-0.2.0.2  ./HelloSnappy
HelloSnappy: foo.jpg: openBinaryFile: does not exist (No such file or directory)

Solutions

Sean Leather on the Haskell Cafè gave me this solution (thanks!):

You're installing into a cabal sandbox and compiling directly with ghc (not cabal), but ghc doesn't know anything about the sandbox. You need to point it to the package database with -package-db and tell it the package for linking with -package [2].

$ ghc -package-db .cabal-sandbox/x86_64-osx-ghc-7.8.3-packages.conf.d -package snappy HelloSnappy.hs
Linking HelloSnappy ...
$ ./HelloSnappy
HelloSnappy: foo.jpg: openBinaryFile: does not exist (No such file or directory)

[1] http://www.haskell.org/ghc/docs/latest/html/users_guide/packages.html#package-databases
[2] http://www.haskell.org/ghc/docs/latest/html/users_guide/options-phases.html#options-linker

Solution n2 (suggested by Chris Wong)

Alternatively, if you've got a recent version of cabal you can use

cabal exec -- ghc HelloSnappy.hs

instead.

You can also load up GHCi in the sandbox using cabal exec ghci or cabal repl.

@spl
Copy link

spl commented Oct 14, 2014

I wonder if there is a problem with linking snappy Haskell to C++ symbols. This makes me think so:

Undefined symbols for architecture x86_64:
  "__hsnappy_GetUncompressedLength", referenced from:
      _c3Jf_info in Snappy.o
  "__hsnappy_MaxCompressedLength", referenced from:
      _c2Fq_info in Internal.o
  "__hsnappy_RawCompress", referenced from:
      _c3Co_info in Snappy.o
  "__hsnappy_RawUncompress", referenced from:
      _c3Ha_info in Snappy.o

What happens if you add a C header file to snappy with extern "C" wrapped around the hs_snappy.cpp function signatures?

@spl
Copy link

spl commented Oct 14, 2014

Then again, maybe not. I just built snappy and ran the tests. If there was a symbol issue, it would have shown up there. You're probably right about the dylib stuff.

@spl
Copy link

spl commented Oct 14, 2014

@adinapoli
Copy link
Author

Thanks Sean, I have edited the original md file with your excellent response :)
Thanks again!

Alfredo

@spl
Copy link

spl commented Oct 15, 2014

It might be worth clarifying that “recent version of cabal” means a version >= 1.20 since, at this point in time, cabal exec is not documented in the cabal users guide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment