
On Thu, Oct 31, 2013 at 05:49:27PM +0100, Fabien Dubosson wrote:
Look at the generated PKGBUILD for a tool such as `cblrepo` and you'll see what I mean.
Hum, I looked again but they seem to use already `depends`. There is 233 packages in habs, and 218 have empty `makedepends`:
$ cd habs $ cblrepo pkgbuild $(cblrepo build base|tail -n +2) $ ls */PKGBUILD | wc -l 233 $ grep -R "makedepends=()" */PKGBUILD | wc -l 218 $ grep -R "makedepends=()" */PKGBUILD haskell-abstract-deque/PKGBUILD:makedepends=() haskell-abstract-par/PKGBUILD:makedepends=() haskell-aeson/PKGBUILD:makedepends=() haskell-anansi/PKGBUILD:makedepends=() [[...]] haskell-xmonad/PKGBUILD:makedepends=() haskell-yaml/PKGBUILD:makedepends=() haskell-zip-archive/PKGBUILD:makedepends=() haskell-zlib/PKGBUILD:makedepends=()
Exactly, everything named haskell-* are library packages, only a few packages are pure tool packages (e.g. cblrepo, git-annex). Pure tool packages make use of makedepends. The relevant lines in cblrepo are found in Util.Translation, lines 302 and 303 in the current version (https://github.com/magthe/cblrepo/blob/master/src/Util/Translation.hs#L302).
The default for GHC has always been to link statically, so that's where we started. Then we added building of shared libs at one point, but there was never any push to actually use them.
After reading the page you point to above (in the GHC 7.6.3 docs) I'm also wondering what flags to give at build time to make an executable use dynamic libs. I had a look at pandoc, which is a package providing both a lib and an exe. It is configured with `--enable-shared` but the executable isn't dynamically linked against the libs it uses:
% ldd /usr/bin/pandoc linux-vdso.so.1 (0x00007fffbbb93000) libz.so.1 => /usr/lib/libz.so.1 (0x00007f23e993a000) libpcre.so.1 => /usr/lib/libpcre.so.1 (0x00007f23e96d4000) libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f23e94d0000) libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f23e92b2000) libgmp.so.10 => /usr/lib/libgmp.so.10 (0x00007f23e903b000) libm.so.6 => /usr/lib/libm.so.6 (0x00007f23e8d38000) librt.so.1 => /usr/lib/librt.so.1 (0x00007f23e8b30000) libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f23e891a000) libc.so.6 => /usr/lib/libc.so.6 (0x00007f23e856f000) /lib64/ld-linux-x86-64.so.2 (0x00007f23e9b50000)
The flag "--enable-shared" generates the shared libraries. The flag "-dynamic" builds executable against these libraries. I managed to build pandoc with shared libraries (and it worked, with a small hack, see problem at the end of the message):
So, while it's possible to pass --enable-shared to build shared libs when configuring the package, it won't actually *use* shared libs. -dynamic is a flag for GHC, correct?
$ ldd /usr/bin/pandoc linux-vdso.so.1 (0x00007fff819fe000) libHSpandoc-1.12.1-ghc7.6.3.so => /usr/lib/ghc-7.6.3/shared/ libHSpandoc-1.12.1-ghc7.6.3.so (0x00007fd3929ec000) libHSzip-archive-0.1.4-ghc7.6.3.so => /usr/lib/ghc-7.6.3/shared/ libHSzip-archive-0.1.4-ghc7.6.3.so (0x00007fd39279c000) libHSzlib-0.5.4.1-ghc7.6.3.so => /usr/lib/ghc-7.6.3/shared/ libHSzlib-0.5.4.1-ghc7.6.3.so (0x00007fd392577000) [[...]] libHStransformers-0.3.0.0-ghc7.6.3.so => /usr/lib/ghc-7.6.3/shared/ libHStransformers-0.3.0.0-ghc7.6.3.so (0x00007fd3869d6000) libHSinteger-gmp-0.5.0.0-ghc7.6.3.so => /usr/lib/ghc-7.6.3/shared/ libHSinteger-gmp-0.5.0.0-ghc7.6.3.so (0x00007fd3867c5000) libHSmtl-2.1.2-ghc7.6.3.so => /usr/lib/ghc-7.6.3/site-local/mtl-2.1.2/ libHSmtl-2.1.2-ghc7.6.3.so (0x00007fd386598000) librt.so.1 => /usr/lib/librt.so.1 (0x00007fd386390000) libutil.so.1 => /usr/lib/libutil.so.1 (0x00007fd38618d000) libdl.so.2 => /usr/lib/libdl.so.2 (0x00007fd385f89000) libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007fd385d6b000) libHSdeepseq-1.3.0.1-ghc7.6.3.so => /usr/lib/ghc-7.6.3/deepseq-1.3.0.1/ libHSdeepseq-1.3.0.1-ghc7.6.3.so (0x00007fd385b62000) libHSarray-0.4.0.1-ghc7.6.3.so => /usr/lib/ghc-7.6.3/array-0.4.0.1/ libHSarray-0.4.0.1-ghc7.6.3.so (0x00007fd3858c1000) libgmp.so.10 => /usr/lib/libgmp.so.10 (0x00007fd38564a000) libffi.so.6 => /usr/lib/libffi.so.6 (0x00007fd385442000) libm.so.6 => /usr/lib/libm.so.6 (0x00007fd38513f000) /lib64/ld-linux-x86-64.so.2 (0x00007fd3937a3000)
I have modified cblrepo to add a flag "--dynamic" to the "pkgbuild" command to generate a PKGBUILD with dynamic linking:
$ cblrepo pkgbuild --dynamic pandoc
See: https://github.com/StreakyCobra/cblrepo/commit/677fe94c311c9e71f0ad99c1f7ee3...
I'll propose that as a pull request when all will be working.
What effects does passing --ghc-options at `Setup.hs configure` have on any `ghc-options:` field present in the .cabal?
The current problem -----------------------------
There is still a small problem: Referencing the shared libraries. As stated at the bottom of [1], there is two ways:
1. By embedding a RPATH into the executable. 2. Using LD_LIBRARY_PATH (or equivalently and better /etc/ld.so.conf.d/*) to specify libraries paths.
Interestingly the shared libs don't seem to suffer from this problem; run `ldd´ on one of the shared libs in a package to see what I mean. It sure looks like cabal has solved the problem halfway only.
The first solution is system dependent, and also less elegant from my point of view. So I focused on the second. Sadly the current hierarchy of Haskell packages doesn't place all shared libraries in the same folder, but in separate folders of the form:
/usr/lib/ghc-<version>/[site-local]/<package>-<version>/<sharedLibraryName>.so
It is unfeasible to reference all these folders (even more with the version in the folder name).
So I actually just made a small hack: a "/usr/lib/ghc-7.6.3/shared" folder and soft-links of all "*.so" inside. Then I added a new "/etc/ld.so.conf.d/haskell.conf" file containing the line: /usr/lib/ghc-7.6.3/shared and run `ldconfig` to update the libraries paths.
Do you see any better way to reference these libraries?
I'll start with asking on haskell-cafe, because it sure looks like this problem ought to be solved by Cabal and not by us.
If no I suggest to put (or link) all "*.so" libraries either in "/usr/lib" or in another folder on a specific place on the system. It is also possible to add, if it is needed, a "/etc/ld.so.conf.d/haskell.conf" file to a new package like "haskell-runtime" and make all Haskell package depends on.
I think the /usr/lib/ghc-7.6.3/shared folder is as good a place as any. IMHO we shouldn't place the Haskell libs straight into /usr/lib. Then the easiest thing would be to put the haskell-ldconf file into ghc itself, since each lib package depends on ghc anyway. Of course, this highlights one aspect to consider before going down the path of using shared libs for pure tools: installing such a package will bring with it all libs it depends on as well as ghc, while at the moment it is completely free standing. However, I think using shared libs for executables contained in libs packaged, e.g. /usr/bin/pandoc from haskell-pandoc, clearly is a good thing. /M -- Magnus Therning OpenPGP: 0xAB4DFBA4 email: magnus@therning.org jabber: magnus@therning.org twitter: magthe http://therning.org/magnus Good powers of observation are frequently called "cynicism" by those that don't have them.