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/de9df07d398d70255c852f4de53e3d14c4…
[2] http://www.haskell.org/pipermail/arch-haskell/2013-October/004600.html
[3]
http://stackoverflow.com/questions/13769141/can-i-change-rpath-in-an-alread…
Hi,
Continuing my investigations about my building problem, I think I have
found its cause and a way to reproduce it.
Briefly, the important point is that the chroot environment must be created
with devtools <= 20130408 (the last version that has makechrootpkg that
support the "-d" flag). Once created, packages can be built even with
newest versions of devtools that doesn't support the "-d" flag (but this
requires to adapt the makeahpkg script to remove it).
At the opposite, if the chroot is created with a newer version, Haskell
packages will build and install, but with a message like:
Diff-0.3.0: cannot find libHSDiff-0.3.0.a on library path (use --force
to override)
To reproduce, run the following commands once with devtools 20130408 and
once with 20131020 (and don't forget to remove completely the "habs-temp"
folder between the two tests):
git clone https://github.com/StreakyCobra/habs.git habs-temp
cd habs-temp
cblrepo sync
cblrepo pkgbuild Diff
./makeahpkg -c -- Diff
# sudo rm habs-temp -rf
Can anybody confirm this behavior? Or is it just me?
Best regards,
Fabien Dubosson