[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Support for dynamic libraries



Attached is a patch to add support for GHC generated dynamic libraries.  With 
this patch, all you need to do is add -dyn entry to the control file.

I've attached a patch that does this for the mtl as an example.  To compile 
against the shared libraries do

 ghc --make -dynamic <source.hs>

Cheers!  -Tyson

PS:  The choice of the extension -dyn comes from the GHC error message you get 
if you try and compile without the shared libraries installed

 $ ghc --make -dynamic Temp.hs -o Temp

 Temp.hs:3:7:
     Could not find module `Control.Monad.Error':
       Perhaps you haven't installed the "dyn" libraries for package  
`mtl-1.1.0.2'?
       Use -v to see a list of the files searched for.
From 874b90cbab68a04f5f2e625fcf916644692935d2 Mon Sep 17 00:00:00 2001
From: Tyson Whitehead <twhitehead@gmail.com>
Date: Tue, 16 Mar 2010 00:10:43 -0400
Subject: [PATCH] Add support for dynamic libraries

---
 Dh_Haskell.pm       |   19 ++++++++++++++-----
 Dh_Haskell.sh       |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 dh_haskell_depends  |   18 ++++++++++++++++--
 dh_haskell_provides |    8 +++++++-
 hlibrary.mk         |   19 ++++++++++++++++---
 5 files changed, 101 insertions(+), 11 deletions(-)

diff --git a/Dh_Haskell.pm b/Dh_Haskell.pm
index 640bceb..0ce29e2 100644
--- a/Dh_Haskell.pm
+++ b/Dh_Haskell.pm
@@ -28,7 +28,8 @@ use vars qw(@ISA @EXPORT %dh);
 @EXPORT = qw(&builddir &build_setup &cabal_version_ge &is_handled_package
 	     &dev_name &type_of_package
 	     &version_of_debpkg &version_of_type &upstream_version
-	     &profiling_name &getcabalname &getcabalversion &getcabalnameversion
+	     &dynamic_name &profiling_name
+             &getcabalname &getcabalversion &getcabalnameversion
 	     &getcabalbasepath &getcabalpkglibpath &getcabalpkgsharepath
 	     );
 
@@ -74,7 +75,7 @@ sub cabal_version_ge {
 
 sub is_handled_package {
     my $pkgname = shift;
-    if ($pkgname =~ m/^lib(ghc6|hugs)-.+-(dev|prof)$/) {
+    if ($pkgname =~ m/^lib(ghc6|hugs)-.+-(dev|dyn|prof)$/) {
 	return 1;
     } elsif ($pkgname =~ m/^libhugs-.+$/) {
 	return 1;
@@ -87,7 +88,7 @@ sub is_handled_package {
 
 sub dev_name {
     my $package = shift;
-    my @pn = ($package =~ m/^lib(ghc6|hugs)-(.+)-prof$/);
+    my @pn = ($package =~ m/^lib(ghc6|hugs)-(.+)-(dyn|prof)$/);
     return "lib$pn[0]-$pn[1]-dev";
 }
 
@@ -97,6 +98,8 @@ sub type_of_package {
 	return "hugs";
     } elsif (my @pn = ($pkgname =~ m/^lib(ghc6|hugs)-.+-dev$/)) {
 	return $pn[0];
+    } elsif ($pkgname =~ m/^libghc6-.+-dyn$/) {
+	return "ghc6-dyn";
     } elsif ($pkgname =~ m/^libghc6-.+-prof$/) {
 	return "ghc6-prof";
     } elsif ($pkgname =~ m/-doc$/) {
@@ -124,9 +127,15 @@ sub upstream_version {
     }
 }
 
+sub dynamic_name {
+    my $package = shift;
+    my @pn = ($package =~ m/^lib(ghc6|hugs)-(.+)-(dev|prof)$/);
+    return "lib$pn[0]-$pn[1]-dyn";
+}
+
 sub profiling_name {
     my $package = shift;
-    my @pn = ($package =~ m/^lib(ghc6|hugs)-(.+)-dev$/);
+    my @pn = ($package =~ m/^lib(ghc6|hugs)-(.+)-(dev|dyn)$/);
     return "lib$pn[0]-$pn[1]-prof";
 }
 
@@ -148,7 +157,7 @@ sub getcabalnameversion {
 
 sub getcabalbasepath {
     my $pkgtype = shift;
-    $pkgtype =~ s/-prof// ;
+    $pkgtype =~ s/-(dyn|prof)// ;
     return "/usr/lib/haskell-packages/$pkgtype";
 }
 
diff --git a/Dh_Haskell.sh b/Dh_Haskell.sh
index 7ffc738..8c633d0 100644
--- a/Dh_Haskell.sh
+++ b/Dh_Haskell.sh
@@ -38,6 +38,24 @@ providing_package_for_ghc6(){
     echo $package
 }
 
+providing_package_for_ghc6_dyn(){
+    local package
+    local dep
+    local dir
+    local dirs
+    local lib
+    dep=`strip_hash $1`
+    dirs=`ghc-pkg6 field $dep library-dirs | grep -i ^library-dirs | cut -d':' -f 2`
+    lib=`ghc-pkg6 field $dep hs-libraries | grep -i ^hs-libraries | sed -e 's|hs-libraries: *\([^ ]*\).*|\1|' `
+    for dir in $dirs ; do
+	if [ -e "${dir}/lib${lib}-"*.so ] ; then
+	    package=`dpkg-query -S ${dir}/lib${lib}-*.so | cut -d':' -f 1` || exit $?
+	    continue
+	fi
+    done
+    echo $package
+}
+
 providing_package_for_ghc6_prof(){
     local package
     local dep
@@ -127,6 +145,24 @@ depends_for_ghc6(){
     echo $packages | sed -e 's/^,[ ]*//'
 }
 
+depends_for_ghc6_dyn(){
+    local dep
+    local packages
+    local pkgid
+    for pkgid in `cabal_depends $@` ; do
+	dep=`hashed_dependency dyn $pkgid`
+	if [ -z "$dep" ]
+	then
+	  pkg=`providing_package_for_ghc6_dyn $pkgid`
+          echo "  $pkg" 1>&2
+	  dep=`dependency $pkg`
+	fi
+	packages="$packages, $dep"
+    done
+
+    echo $packages | sed -e 's/^,[ ]*//'
+}
+
 depends_for_ghc6_prof(){
     local dep
     local packages
@@ -153,6 +189,15 @@ provides_for_ghc6(){
     echo $packages | sed -e 's/^,[ ]*//'
 }
 
+provides_for_ghc6_dyn(){
+    local dep
+    local packages
+    for package_id in `cabal_package_ids $@` ; do
+	packages="$packages, `package_id_to_virtual_package dyn $package_id`"
+    done
+    echo $packages | sed -e 's/^,[ ]*//'
+}
+
 provides_for_ghc6_prof(){
     local dep
     local packages
@@ -186,6 +231,9 @@ find_config_for_ghc6(){
 	ghc6-prof)
 	    pkg=ghc6
 	    ;;
+        libghc6-*-dyn)
+	    pkg=`echo $pkg | sed -e 's/-dyn$/-dev/'`
+	    ;;
 	libghc6-*-prof)
 	    pkg=`echo $pkg | sed -e 's/-prof$/-dev/'`
 	    ;;
diff --git a/dh_haskell_depends b/dh_haskell_depends
index e8bbe70..c735d3a 100755
--- a/dh_haskell_depends
+++ b/dh_haskell_depends
@@ -61,7 +61,7 @@ for pkg in `dh_listpackages $args`; do
     touch $sfile
 
     case "$pkg" in
-	libghc6-*-dev|libghc6-*-prof)
+	libghc6-*-dev|libghc6-*-dyn|libghc6-*-prof)
 	    if [ -z "$files" ] ; then
 		cfiles=`find_config_for_ghc6 $pkg`
 	    else
@@ -81,10 +81,24 @@ for pkg in `dh_listpackages $args`; do
 		    echo "haskell:Depends=`depends_for_ghc6 $cfiles`" >> $sfile.tmp
                     echo "haskell:Recommends=" >> $sfile.tmp
                     doc=`echo $pkg | sed -e 's/-dev$/-doc/'`
+                    dyn=`echo $pkg | sed -e 's/-dev$/-dyn/'`
                     prof=`echo $pkg | sed -e 's/-dev$/-prof/'`
-                    suggests="$doc, $prof"
+                    suggests="$doc, $dyn, $prof"
                     echo "haskell:Suggests=$suggests" >> $sfile.tmp
 		    ;;
+		libghc6-*-dyn)
+	            grep -v \
+                        -e ^haskell:Depends \
+                        -e ^haskell:Recommends \
+                        -e ^haskell:Suggests \
+                        $sfile > $sfile.tmp || true
+                    dev=`echo $pkg | sed -e 's/-dyn$/-dev/'`
+                    version='(=${binary:Version})'
+                    depends="`depends_for_ghc6_dyn $cfiles`"
+		    echo "haskell:Depends=$depends" >> $sfile.tmp
+                    echo "haskell:Recommends=" >> $sfile.tmp
+                    echo "haskell:Suggests=" >> $sfile.tmp
+		    ;;
 		libghc6-*-prof)
 	            grep -v \
                         -e ^haskell:Depends \
diff --git a/dh_haskell_provides b/dh_haskell_provides
index c1afbaf..966229f 100755
--- a/dh_haskell_provides
+++ b/dh_haskell_provides
@@ -67,7 +67,7 @@ for pkg in `dh_listpackages $args`; do
     touch $sfile
 
     case "$pkg" in
-	libghc6-*-dev|libghc6-*-prof|ghc6|ghc6-prof)
+	libghc6-*-dev|libghc6-*-dyn|libghc6-*-prof|ghc6|ghc6-prof)
 	    if [ -z "$files" ] ; then
 		cfiles=`find_config_for_ghc6 $pkg`
 	    else
@@ -84,6 +84,12 @@ for pkg in `dh_listpackages $args`; do
                         $sfile > $sfile.tmp || true
 	            echo "haskell:Provides=`provides_for_ghc6 $cfiles`" >> $sfile.tmp
 		    ;;
+		libghc6-*-dyn|ghc6-dyn)
+	            grep -v \
+                        -e ^haskell:Provides \
+                        $sfile > $sfile.tmp || true
+	            echo "haskell:Provides=`provides_for_ghc6_dyn $cfiles`" >> $sfile.tmp
+		    ;;
 		libghc6-*-prof|ghc6-prof)
 	            grep -v \
                         -e ^haskell:Provides \
diff --git a/hlibrary.mk b/hlibrary.mk
index a3e7c22..4849b0f 100644
--- a/hlibrary.mk
+++ b/hlibrary.mk
@@ -24,6 +24,7 @@ CABAL_PACKAGE=$(DEB_CABAL_PACKAGE)
 CABAL_VERSION=$(shell cat *.cabal | egrep -i '^\s*version:' | head -n1 | sed -r 's,^\s*version:\s*,,i')
 
 ENABLE_PROFILING = $(shell egrep -qe '^Package: libghc6-.*-prof$$' debian/control && echo --enable-library-profiling; exit 0)
+ENABLE_SHARED = $(shell egrep -qe '^Package: libghc6-.*-dyn$$' debian/control && echo --enable-shared; exit 0)
 
 DEB_COMPRESS_EXCLUDE += .haddock
 
@@ -57,6 +58,11 @@ ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
    OPTIMIZATION = --disable-optimization
 endif
 
+# dependencies on ghc shared libraries are done by dh_haskell_depends
+
+DEB_DH_MAKESHLIBS_ARGS_libghc6-$(CABAL_PACKAGE)-dyn += -Xghc$(GHC6_VERSION)
+DEB_DH_SHLIBDEPS_ARGS_libghc6-$(CABAL_PACKAGE)-dyn += -Xghc$(GHC6_VERSION)
+
 clean::
 	rm -rf dist dist-ghc6 dist-hugs $(DEB_SETUP_BIN_NAME) Setup.hi Setup.ho Setup.o .*config*
 	rm -f build-ghc6-stamp build-hugs-stamp build-haddock-stamp
@@ -73,14 +79,14 @@ dist-ghc6: $(DEB_SETUP_BIN_NAME)
 		--prefix=/usr --libdir=/usr/lib/haskell-packages/ghc6/lib \
 		--builddir=dist-ghc6 \
 		--haddockdir=$(DEB_HADDOCK_DIR) \
-		--htmldir=$(DEB_HADDOCK_HTML_DIR) $(ENABLE_PROFILING) \
+		--htmldir=$(DEB_HADDOCK_HTML_DIR) $(ENABLE_PROFILING) $(ENABLE_SHARED) \
 		$(DEB_SETUP_GHC6_CONFIGURE_ARGS) $(OPTIMIZATION)
 
 build-ghc6-stamp: dist-ghc6
 	$(BUILD_GHC6) --builddir=dist-ghc6
 	touch build-ghc6-stamp
 
-build/libghc6-$(CABAL_PACKAGE)-prof build/libghc6-$(CABAL_PACKAGE)-dev:: build-ghc6-stamp build-haddock-stamp
+build/libghc6-$(CABAL_PACKAGE)-prof build/libghc6-$(CABAL_PACKAGE)-dyn build/libghc6-$(CABAL_PACKAGE)-dev:: build-ghc6-stamp build-haddock-stamp
 
 build-haddock-stamp:
 	[ ! -x /usr/bin/haddock ] || $(DEB_SETUP_BIN_NAME) haddock --builddir=dist-ghc6 $(DEB_HADDOCK_OPTS)
@@ -99,7 +105,7 @@ debian/tmp-inst-ghc6: $(DEB_SETUP_BIN_NAME) dist-ghc6
 
 install/libghc6-$(CABAL_PACKAGE)-dev:: debian/tmp-inst-ghc6
 	cd debian/tmp-inst-ghc6 ; find usr/lib/haskell-packages/ghc6/lib/ \
-		\( ! -name "*_p.a" ! -name "*.p_hi" \) \
+		\( ! -name "*.so" ! -name "*_p.a" ! -name "*.p_hi" \) \
 		-exec install -Dm 644 '{}' ../$(notdir $@)/'{}' ';'
 	pkg_config=`$(DEB_SETUP_BIN_NAME) register --builddir=dist-ghc6 --gen-pkg-config | sed -r 's,.*: ,,'`; \
 		$(if $(HASKELL_HIDE_PACKAGES),sed -i 's/^exposed: True$$/exposed: False/' $$pkg_config;) \
@@ -113,6 +119,13 @@ install/libghc6-$(CABAL_PACKAGE)-dev:: debian/tmp-inst-ghc6
 	dh_haskell_depends -p$(notdir $@)
 	dh_haskell_shlibdeps -p$(notdir $@)
 
+install/libghc6-$(CABAL_PACKAGE)-dyn:: debian/tmp-inst-ghc6 install/libghc6-$(CABAL_PACKAGE)-dev
+	cd debian/tmp-inst-ghc6 ; find usr/lib/haskell-packages/ghc6/lib/ \
+		! \( ! -name "*.so" \) \
+		-exec install -Dm 644 '{}' ../$(notdir $@)/'{}' ';'
+	dh_haskell_provides -p$(notdir $@)
+	dh_haskell_depends -p$(notdir $@)
+
 install/libghc6-$(CABAL_PACKAGE)-prof:: debian/tmp-inst-ghc6 install/libghc6-$(CABAL_PACKAGE)-dev
 	cd debian/tmp-inst-ghc6 ; find usr/lib/haskell-packages/ghc6/lib/ \
 		! \( ! -name "*_p.a" ! -name "*.p_hi" \) \
-- 
1.6.3.3

From 89c145f31f84aba12eec9a1cfd1a3edf28938be0 Mon Sep 17 00:00:00 2001
From: Tyson Whitehead <twhitehead@gmail.com>
Date: Mon, 15 Mar 2010 23:48:00 -0400
Subject: [PATCH] Add GHC dynamic library to control file

---
 debian/control |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/debian/control b/debian/control
index 2d6d611..5e85cf7 100644
--- a/debian/control
+++ b/debian/control
@@ -33,6 +33,24 @@ Description: Haskell monad transformer library for GHC
  by Mark P Jones (<http://www.cse.ogi.edu/~mpj/>), Advanced School
  of Functional Programming, 1995.
 
+Package: libghc6-mtl-dyn
+Architecture: any
+Depends:
+ ${haskell:Depends},
+ ${misc:Depends}
+Suggests: ${haskell:Suggests}
+Recommends: ${haskell:Recommends}
+Provides: ${haskell:Provides}
+Description: Haskell monad transformer library for GHC; profiling libraries
+ This package provides a shared library for the Haskell programming
+ language.
+ See http://www.haskell.org/ for more information on Haskell.
+ .
+ MTL is a monad transformer library, inspired by the paper "Functional
+ Programming with Overloading and Higher-Order Polymorphism",
+ by Mark P Jones (<http://www.cse.ogi.edu/~mpj/>), Advanced School
+ of Functional Programming, 1995.
+
 Package: libghc6-mtl-prof
 Architecture: any
 Depends:
-- 
1.6.3.3

Attachment: signature.asc
Description: This is a digitally signed message part.


Reply to: