Skip to content

Cabal 1.22 breaks/changes -dynamic builds #2330

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
nh2 opened this issue Jan 8, 2015 · 6 comments
Closed

Cabal 1.22 breaks/changes -dynamic builds #2330

nh2 opened this issue Jan 8, 2015 · 6 comments

Comments

@nh2
Copy link
Member

nh2 commented Jan 8, 2015

For call-haskell-from-anything I'm getting a broken TravisCI build on the same code when the only thing that changed is the version of cabal obtained with cabal install cabal-install; before it was 1.20 which worked fine, now with 1.20 it breaks.

The broken build is this one which worked before (see also this bug: nh2/call-haskell-from-anything#4), the error message being:

$ python test.py
Traceback (most recent call last):
  File "test.py", line 4, in <module>
    lib = cdll.LoadLibrary("dist/build/call-haskell-from-anything.so/call-haskell-from-anything.so")
  File "/usr/lib/python2.7/ctypes/__init__.py", line 443, in LoadLibrary
    return self._dlltype(name)
  File "/usr/lib/python2.7/ctypes/__init__.py", line 365, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: libHScall-haskell-from-anything-0.1.0.1-ghc7.8.3.so: cannot open shared object file: No such file or directory

In my cabal file I'm building a .so shared library using:

  ghc-options:
    -no-hs-main -fPIC -shared -dynamic

I'm configuring with cabal configure --enable-tests --enable-shared.

Why would I get a "missing libHScall-haskell-from-anything-0.1.0.1-ghc7.8.3.so" error with 1.22 when with 1.20 I didn't? Did anything change in the way that shared library compilations are done?

I woudl appreciate any information!

nh2 added a commit to nh2/call-haskell-from-anything that referenced this issue Jan 8, 2015
@tibbe tibbe added this to the Cabal-1.22.0.1 milestone Jan 8, 2015
@tibbe
Copy link
Member

tibbe commented Jan 8, 2015

Can you try to call cabal with -v2 and -v3 and paste the difference (presumably we pass different flags to the compiler.)

@nh2
Copy link
Member Author

nh2 commented Jan 8, 2015

Hey Johan,

yes, the output is different.
Note that differences only appear when using GHC 7.8; 7.6 and 7.4 behave the same with both cabal versions.

The builds:

Some obviously different outputs in -v2:

1.20:

Linking a.out ...
Linking...
/usr/local/ghc/7.8.3/bin/ghc --make -fbuilding-cabal-package -O -static -outputdir dist/build/call-haskell-from-anything.so/call-haskell-from-anything.so-tmp -odir dist/build/call-haskell-from-anything.so/call-haskell-from-anything.so-tmp -hidir dist/build/call-haskell-from-anything.so/call-haskell-from-anything.so-tmp -stubdir dist/build/call-haskell-from-anything.so/call-haskell-from-anything.so-tmp -i -idist/build/call-haskell-from-anything.so/call-haskell-from-anything.so-tmp -itest -idist/build/autogen -Idist/build/autogen -Idist/build/call-haskell-from-anything.so/call-haskell-from-anything.so-tmp -optP-include -optPdist/build/autogen/cabal_macros.h -lHSrts-ghc7.8.3 -hide-all-packages -package-db dist/package.conf.inplace -package-id base-4.7.0.1-1a55ebc8256b39ccbff004d48b3eb834 -package-id bytestring-0.10.4.0-aeb2ba35f192516ed4298f0656cc3a85 -package-id msgpack-0.7.2.5-37593f02103f2457807bb9570e85fb32 -package-id mtl-2.2.1-524abcb9484b29bc953548ece20e74a1 -package-id call-haskell-from-anything-0.1.0.1-inplace -XHaskell2010 test/Test1.hs -o dist/build/call-haskell-from-anything.so/call-haskell-from-anything.so -no-hs-main -fPIC -shared -dynamic
Linking dist/build/call-haskell-from-anything.so/call-haskell-from-anything.so ...

1.22:

Linking a.out ...
Linking...
/usr/local/ghc/7.8.3/bin/ghc --make -fbuilding-cabal-package -O -static -outputdir dist/build/call-haskell-from-anything.so/call-haskell-from-anything.so-tmp -odir dist/build/call-haskell-from-anything.so/call-haskell-from-anything.so-tmp -hidir dist/build/call-haskell-from-anything.so/call-haskell-from-anything.so-tmp -stubdir dist/build/call-haskell-from-anything.so/call-haskell-from-anything.so-tmp -i -idist/build/call-haskell-from-anything.so/call-haskell-from-anything.so-tmp -itest -idist/build/autogen -Idist/build/autogen -Idist/build/call-haskell-from-anything.so/call-haskell-from-anything.so-tmp -optP-include -optPdist/build/autogen/cabal_macros.h -lHSrts-ghc7.8.3 '-dynload deploy' -optl-Wl,-rpath,/home/travis/.cabal/lib/x86_64-linux-ghc-7.8.3/call-haskell-from-anything-0.1.0.1 -optl-Wl,-rpath,/usr/local/ghc/7.8.3/lib/ghc-7.8.3/array-0.5.0.0 -optl-Wl,-rpath,/home/travis/.cabal/lib/x86_64-linux-ghc-7.8.3/attoparsec-0.12.1.2 -optl-Wl,-rpath,/usr/local/ghc/7.8.3/lib/ghc-7.8.3/base-4.7.0.1 -optl-Wl,-rpath,/home/travis/.cabal/lib/x86_64-linux-ghc-7.8.3/blaze-builder-0.3.3.4 -optl-Wl,-rpath,/usr/local/ghc/7.8.3/lib/ghc-7.8.3/rts-1.0 -optl-Wl,-rpath,/usr/local/ghc/7.8.3/lib/ghc-7.8.3/bytestring-0.10.4.0 -optl-Wl,-rpath,/usr/local/ghc/7.8.3/lib/ghc-7.8.3/containers-0.5.5.1 -optl-Wl,-rpath,/usr/local/ghc/7.8.3/lib/ghc-7.8.3/deepseq-1.3.0.2 -optl-Wl,-rpath,/usr/local/ghc/7.8.3/lib/ghc-7.8.3/ghc-prim-0.3.1.0 -optl-Wl,-rpath,/home/travis/.cabal/lib/x86_64-linux-ghc-7.8.3/hashable-1.2.3.1 -optl-Wl,-rpath,/usr/local/ghc/7.8.3/lib/ghc-7.8.3/integer-gmp-0.5.1.0 -optl-Wl,-rpath,/home/travis/.cabal/lib/x86_64-linux-ghc-7.8.3/msgpack-0.7.2.5 -optl-Wl,-rpath,/home/travis/.cabal/lib/x86_64-linux-ghc-7.8.3/mtl-2.2.1 -optl-Wl,-rpath,/usr/local/ghc/7.8.3/lib/ghc-7.8.3/pretty-1.1.1.1 -optl-Wl,-rpath,/home/travis/.cabal/lib/x86_64-linux-ghc-7.8.3/primitive-0.5.4.0 -optl-Wl,-rpath,/home/travis/.cabal/lib/x86_64-linux-ghc-7.8.3/scientific-0.3.3.5 -optl-Wl,-rpath,/usr/local/ghc/7.8.3/lib/ghc-7.8.3/template-haskell-2.9.0.0 -optl-Wl,-rpath,/home/travis/.cabal/lib/x86_64-linux-ghc-7.8.3/text-1.2.0.3 -optl-Wl,-rpath,/home/travis/.cabal/lib/x86_64-linux-ghc-7.8.3/transformers-0.4.2.0 -optl-Wl,-rpath,/home/travis/.cabal/lib/x86_64-linux-ghc-7.8.3/unordered-containers-0.2.5.1 -optl-Wl,-rpath,/home/travis/.cabal/lib/x86_64-linux-ghc-7.8.3/vector-0.10.12.2 -hide-all-packages -package-db dist/package.conf.inplace -package-id base-4.7.0.1-1a55ebc8256b39ccbff004d48b3eb834 -package-id bytestring-0.10.4.0-aeb2ba35f192516ed4298f0656cc3a85 -package-id call-haskell-from-anything-0.1.0.1-inplace -package-id msgpack-0.7.2.5-37593f02103f2457807bb9570e85fb32 -package-id mtl-2.2.1-524abcb9484b29bc953548ece20e74a1 -XHaskell2010 test/Test1.hs -o dist/build/call-haskell-from-anything.so/call-haskell-from-anything.so -no-hs-main -fPIC -shared -dynamic
Linking dist/build/call-haskell-from-anything.so/call-haskell-from-anything.so ...

Something that pops into the eye is that 1.22 passes the -dynload deploy option and also a lot of -optl-Wl,-rpath,....

I'm not very familiar with the -dynload stuff. Do you think that's it?

@tibbe
Copy link
Member

tibbe commented Jan 8, 2015

@christiaanb is this related to the support for relocatable packages that you added?

@christiaanb
Copy link
Collaborator

Yes, this is due to the support for relocatable packages that I added. Specifically, that Cabal takes over the RPATH handling from GHC. What is happening is the following:

  • Cabal 1.20 lets GHC handle RPATHs, which will add an RPATH for the build location of the library in a dynamically linked executable. This is actually wrong, see --enable-executable-dynamic not working on packages containing both lib and executables, makes installation problematic #1568. Because when the executable is installed, and the dist directory is deleted, the dynamically linked executable can no longer find the library.
  • Cabal 1.22 handles RPATHs itself, and will add an RPATH for the install location of the library in the dynamically linked executable. However, this means that, as long the library is not yet installed, you have to update your LD_LIBRARY_PATH to include the build directory so that the dynamic linker can find the library. This happens automatically when you use commands like cabal test, cabal run, cabal exec, etc. But in your python test environment you have to set LD_LIBRARY_PATH yourself.

One option is to also add again the build directory of the library as an RPATH of the executable. But I think that is ugly and unwanted.

nh2 added a commit to nh2/call-haskell-from-anything that referenced this issue Jan 8, 2015
Fixes running when build with cabal >= 1.22.

See haskell/cabal#2330 (comment)
@dcoutts
Copy link
Contributor

dcoutts commented Jan 8, 2015

It's also worth noting that building shared libs like this is not actually supported by Cabal (though it's certainly useful). Ideally I'd like to add dedicated support, so that we don't need fragile hacks like people are using now (indeed I'm one of the people using such fragile hacks).

@nh2
Copy link
Member Author

nh2 commented Jan 8, 2015

However, this means that, as long the library is not yet installed, you have to update your LD_LIBRARY_PATH to include the build directory so that the dynamic linker can find the library.

Thanks @christiaanb for your explanation, it works.

From my side, the issue is solved. It seems sensible to me to have to set LD_LIBRARY_PATH.

If you think there's a way/place to better document this stuff, feel free to reopen the issue.

Thanks for everybody's quick help, as usual!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants