[arch-haskell] Dynamic executables and RPATH
Fabien Dubosson
fabien.dubosson at gmail.com
Fri Nov 1 12:04:44 UTC 2013
Hi,
On the road of dynamic linking for Haskell executables, Magnus has pushed a
commit [1] on `cblrepo` yesterday. This commit adds the cabal flag
`--enable-executable-dynamic`. It follows a previous discussion on this
mailing list [2] and solves some of the cited problems. I tried to build
`pandoc` dynamically this morning, and there is only one issue left (unless
I do something wrong?).
For dynamic linking, Cabal/GHC embed an RPATH into the executable:
$ readelf --dynamic /usr/bin/pandoc
[[...]]
0x000000000000000f (RPATH) Library rpath:
[/home/fabien/archlinux/habs/haskell-pandoc/src/pandoc-1.12.1/dist/build:/usr/lib/ghc-7.6.3/site-local/zip-archive-0.1.4:/usr/lib/ghc-7.6.3/site-local/zlib-0.5.4.1:/usr/lib/ghc-7.6.3/site-local/utf8-string-0.3.7:/usr/lib/ghc-7.6.3/site-local/digest-0.0.1.2:/usr/lib/ghc-7.6.3/site-local/binary-0.7.1.0:/usr/lib/ghc-7.6.3/site-local/texmath-0.6.4:/usr/lib/ghc-7.6.3/site-local/xml-1.3.13:/usr/lib/ghc-7.6.3/site-local/temporary-1.1.2.4:/usr/lib/ghc-7.6.3/site-local/tagsoup-0.13:/usr/lib/ghc-7.6.3/site-local/random-1.0.1.1:/usr/lib/ghc-7.6.3/process-1.1.0.2:/usr/lib/ghc-7.6.3/site-local/hslua-0.3.7:/usr/lib/ghc-7.6.3/site-local/data-default-0.5.3:/usr/lib/ghc-7.6.3/site-local/data-default-instances-old-locale-0.0.1:/usr/lib/ghc-7.6.3/site-local/data-default-instances-dlist-0.0.1:/usr/lib/ghc-7.6.3/site-local/data-default-instances-containers-0.0.1:/usr/lib/ghc-7.6.3/site-local/data-default-instances-base-0.0.1:/usr/lib/ghc-7.6.3/site-local/data-default-class-0.0.1:/usr/lib/ghc-7.6.3/site-local/base64-bytestring-1.0.0.1:/usr/lib/ghc-7.6.3/site-local/yaml-0.8.5.1:/usr/lib/ghc-7.6.3/site-local/conduit-1.0.8:/usr/lib/ghc-7.6.3/site-local/void-0.6.1:/usr/lib/ghc-7.6.3/site-local/semigroups-0.11:/usr/lib/ghc-7.6.3/site-local/nats-0.1.2:/usr/lib/ghc-7.6.3/site-local/resourcet-0.4.9:/usr/lib/ghc-7.6.3/site-local/mmorph-1.0.0:/usr/lib/ghc-7.6.3/site-local/lifted-base-0.2.1.0:/usr/lib/ghc-7.6.3/site-local/monad-control-0.3.2.2:/usr/lib/ghc-7.6.3/site-local/transformers-base-0.4.1:/usr/lib/ghc-7.6.3/site-local/base-unicode-symbols-0.2.2.4:/usr/lib/ghc-7.6.3/site-local/pandoc-types-1.12.3:/usr/lib/ghc-7.6.3/site-local/highlighting-kate-0.5.5:/usr/lib/ghc-7.6.3/site-local/pcre-light-0.4:/usr/lib/ghc-7.6.3/site-local/blaze-html-0.6.1.1:/usr/lib/ghc-7.6.3/site-local/blaze-markup-0.5.1.5:/usr/lib/ghc-7.6.3/site-local/extensible-exceptions-0.1.1.4:/usr/lib/ghc-7.6.3/directory-1.2.0.1:/usr/lib/ghc-7.6.3/filepath-1.3.0.1:/usr/lib/ghc-7.6.3/site-local/aeson-0.6.2.1:/usr/lib/ghc-7.6.3/site-local/vector-0.10.9.1:/usr/lib/ghc-7.6.3/site-local/primitive-0.5.1.0:/usr/lib/ghc-7.6.3/site-local/unordered-containers-0.2.3.3:/usr/lib/ghc-7.6.3/template-haskell-2.8.0.0:/usr/lib/ghc-7.6.3/pretty-1.1.1.0:/usr/lib/ghc-7.6.3/site-local/syb-0.4.1:/usr/lib/ghc-7.6.3/site-local/hashable-1.2.1.0:/usr/lib/ghc-7.6.3/site-local/dlist-0.5:/usr/lib/ghc-7.6.3/site-local/blaze-builder-0.3.1.1:/usr/lib/ghc-7.6.3/site-local/attoparsec-0.10.4.0:/usr/lib/ghc-7.6.3/containers-0.5.0.0:/usr/lib/ghc-7.6.3/site-local/HTTP-4000.2.8:/usr/lib/ghc-7.6.3/old-time-1.1.0.1:/usr/lib/ghc-7.6.3/site-local/network-2.4.2.0:/usr/lib/ghc-7.6.3/unix-2.6.0.1:/usr/lib/ghc-7.6.3/time-1.4.0.1:/usr/lib/ghc-7.6.3/old-locale-1.0.0.5:/usr/lib/ghc-7.6.3/site-local/parsec-3.1.3:/usr/lib/ghc-7.6.3/site-local/text-0.11.3.1:/usr/lib/ghc-7.6.3/site-local/mtl-2.1.2:/usr/lib/ghc-7.6.3/site-local/transformers-0.3.0.0:/usr/lib/ghc-7.6.3/bytestring-0.10.0.2:/usr/lib/ghc-7.6.3/deepseq-1.3.0.1:/usr/lib/ghc-7.6.3/array-0.4.0.1:/usr/lib/ghc-7.6.3/base-4.6.0.1:/usr/lib/ghc-7.6.3/integer-gmp-0.5.0.0:/usr/lib/ghc-7.6.3/ghc-prim-0.3.0.0:/usr/lib/ghc-7.6.3]
[[...]]
This is working to find all libraries except one: `
libHSpandoc-1.12.1-ghc7.6.3.so`. The reason is the following: At compile
time, cabal first builds the pandoc library, then the pandoc executable
which is using this library. But because the library is not installed at
this moment (understand: not located in the final place
`/usr/lib/ghc-7.6.3/site-local/pandoc-1.12.1/`) the RPATH embeds its
*current* location, in my case
`/home/fabien/archlinux/habs/haskell-pandoc/src/pandoc-1.12.1/dist/build`
(see the output above). So as long as the library is present in this
folder, pandoc works, but obviously that is not working to distribute it. I
suppose this method is working for cabal-install because the library stays
at its place once built, which is not the case here: the library is moved
once built.
Also I suppose this problem doesn't appear with library-only package,
because each package generate only one `*.so` file (as far as I have seen),
so no need to link against another library of the same package at build
time.
Up to my knowledge I see three solutions:
1. Find a way to build and install in two passes, something like
separating in haskell-pandoc and haskell-pandoc-libs (first build and
install pandoc-libs, then build and install pandoc)
- Requires to find a way to create separate PKGBUILDs for the same
hackage package. Elegant but complicated solution, so not very convenient.
2. Try to modify the RPATH inside the executable
- Seems to be possible, see [3], but complicated and not very elegant
solution.
3. Change the linking paradigm to use /etc/ld.so.conf.d/* instead of the
embedded RPATH
- Requires to put or link all `*.so` libraries into on place, and add a
`/etc/ld.so.conf.d/haskell.conf` file to ghc installation. The most
tractable solution imho.
Does anyone has remarks/suggestions/ideas/solutions about this problem?
Best regards,
Fabien
[1]
https://github.com/magthe/cblrepo/commit/de9df07d398d70255c852f4de53e3d14c4eeb0b4
[2] http://www.haskell.org/pipermail/arch-haskell/2013-October/004600.html
[3]
http://stackoverflow.com/questions/13769141/can-i-change-rpath-in-an-already-compiled-binary
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/arch-haskell/attachments/20131101/b5ecfd8b/attachment.html>
More information about the arch-haskell
mailing list