[Pkg-ocaml-maint-commits] [SCM] dh-ocaml packaging branch, master, updated. debian/0.5.0-20-gf6a757c

Sylvain Le Gall gildor at debian.org
Thu Jul 23 02:25:57 UTC 2009


The following commit has been merged in the master branch:
commit f6a757c1255ffe786d1e25db35342d345ac42508
Author: Sylvain Le Gall <gildor at debian.org>
Date:   Thu Jul 23 02:17:40 2009 +0000

    Make dh_ocaml and ocaml-md5sums works on ocaml package.
    
    * ocaml-md5sums
     * Add option to override checksum compilation
     * Dump checksum into provides/depends
    * dh_ocaml
     * Use File::Find to look for files
     * Avoid creating intermediate file
     * Refactor the process in a more linear way (less functions)
     * Introduce three types in packages: dev, runtime and binary
     * Define 3 command line options: --nodefined-map, --runtime-map
       and --checksum
     * Allow to use files .olist to define which object are taken
       into account when computing dependencies/provides

diff --git a/debhelper/dh_ocaml b/debhelper/dh_ocaml
index 7ebd922..5b54abb 100755
--- a/debhelper/dh_ocaml
+++ b/debhelper/dh_ocaml
@@ -7,9 +7,9 @@
 # Copyright © 2005-2006 Stefano Zacchiroli <zack at debian.org>
 #                       Samuel Mimram <smimram at debian.org>
 # Copyright © 2009      Mehdi Dogguy <mehdi at dogguy.org>
+#                       Sylvian Le Gall <gildor at debian.org>
 #
 # Created:        Fri, 01 Apr 2005 19:50:48 +0200 zack
-# Last-Modified:  $Id: dh_ocaml 3180 2006-09-18 17:25:50Z smimram $
 #
 # This is free software, you can redistribute it and/or modify it under the
 # terms of the GNU General Public License version 2 or above as published by the
@@ -24,71 +24,67 @@
 # this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 # Place, Suite 330, Boston, MA  02111-1307  USA
 
-# TODO ask joeyh for a O_PARAMS and s/M_PARAMS/O_PARAMS/
-
 =head1 NAME
 
-dh_ocaml - calculates OCaml packages dependencies
+dh_ocaml - calculates OCaml packages dependencies and provides
 
 =cut
 
 use strict;
 use Debian::Debhelper::Dh_Lib;
-init();
+use File::Find;
 
-my $ocamlc = "/usr/bin/ocamlc";
-my $omd5 = "/usr/bin/ocaml-md5sums";
-my @binaries = ($ocamlc, $omd5);
-foreach my $bin (@binaries) {
-  error "$bin does not exists or is not executable" unless -x $bin;
-}
-chomp (my $ocaml_lib_dir = `$ocamlc -where`);
-chomp (my $ocaml_version = `$ocamlc -version`);
-
-my $md5dir = "/var/lib/ocaml/md5sums";
-my $md5ext = ".md5sums";
-my $ocaml_magic_line = "#!/usr/bin/ocamlrun";
+init(options => {
+    "runtime-map=s"    => \$dh{RUNTIME_MAP},
+    "nodefined-map=s@" => \$dh{NODEFINED_MAP},
+    "checksum=s"       => \$dh{CHECKSUM}
+});
 
 =head1 SYNOPSIS
 
-B<dh_ocaml> [S<I<debhelper options>>]
+B<dh_ocaml> [S<I<debhelper options>>] 
+            [B<--runtime-map>=I<dev:runtime,...>] 
+            [B<--nodefined-map>=I<dev:ignore1,ignore2>]
+            [B<--checksum>=I<str>]
 
 =head1 DESCRIPTION
 
 dh_ocaml is a debhelper program that is responsible for filling the
 ${ocaml:Provides} and ${ocaml:Depends} substitutions and adding them to
-substvars files. It also adds postinst and postrm scripts for maintaining
-system registry of OCaml md5sums where required.
-
-dh_ocaml acts on two kinds of binary packages: those shipping development part
-of OCaml libraries (usually named libXXX-ocaml-dev), and those shipping OCaml
-bytecode non-custom executables (i.e. executables interpreted by
-/usr/bin/ocamlrun).
-
-On OCaml library packages dh_ocaml will firstly look at OCaml objects (files
-matching *.cm[ao]) shipped by the package. Then, dh_ocaml uses ocamlobjinfo on
-them for collecting information about OCaml modules (or units, in ocamlobjinfo
-terminology) defined and used by them.  Information about defined units will be
-used to automatically create the OCaml md5sums registry entry for your package,
-e.g.  /var/lib/ocaml/md5sums/libXXX-ocaml-dev.md5sums. Information about
-imported units will instead be used as keys in the OCaml md5sums registry for
-retrieving dependency information for the package. Those information will then
-be used to fill the "${ocaml:Depends}" substvars. They will also be used to
-fill the "${ocaml:Provides}" substvar which will be replaced by a name of the
-form libXXX-ocaml-dev-NNNN, where NNNN is an md5sum computed from the
-interfaces of the modules provided by the library.
-
-dh_ocaml takes also care of creating postinst and postrm autoscripts which
-update the global system registry (/var/lib/ocaml/md5sums/MD5SUMS) with the
-registry entry shipped by your package.
-
-On non-library packages, dh_ocaml tries to guess the OCaml objects corresponding
-to shipped bytecode binaries and extract from them information about imported
-units. Extracted information will then be used for filling "${ocaml:Depends}" as
-discussed for the library case.
-
-In addition to dependencies extracted from the system md5sum registry, dh_ocaml
-will add in ${ocaml:Provides}:
+substvars files.
+
+dh_ocaml acts on three kinds of binary packages: those shipping development
+part of OCaml libraries (usually named libXXX-ocaml-dev), those shipping
+runtime for OCaml libraires (e.g. plugin and shared library, usually named
+libXXX-ocaml) and those shipping OCaml bytecode non-custom executables (i.e.
+executables interpreted by /usr/bin/ocamlrun).
+
+On specific package the convention is XXX for development and XXX-base for 
+runtime (e.g. ocaml-nox and ocaml-base-nox).
+
+On OCaml library packages dh_ocaml will firstly look at OCaml objects shipped
+by the package. Then, dh_ocaml uses appropriate program on them for collecting
+information about OCaml modules defined and used by them. Information about
+defined units will be used to automatically create the OCaml md5sums registry
+entry for development and runtime package, e.g.
+/var/lib/ocaml/md5sums/libXXX-ocaml-dev.md5sums. Information about imported
+units will instead be used as keys in the OCaml md5sums registry for retrieving
+dependency information for the package. Those information will then be used to
+fill the ${ocaml:Depends} substvars. They will also be used to fill the
+${ocaml:Provides} substvar which will be replaced by a name of the form
+libXXX-ocaml-dev-NNNN, where NNNN is an checksum computed from the interfaces
+of the modules provided by the library.
+
+=item *.cm[aio] are processed by ocamlobjinfo;
+
+=item *.cmxa? are processed by ocamldumpapprox;
+
+=item *.cmxs are processed by ocamlplugininfo;
+
+=item executable are processed by ocamlbyteinfo, if possible.
+
+Dependencies extracted from the system md5sum registry, dh_ocaml
+will add in ${ocaml:Depends}:
 
 =over
 
@@ -99,39 +95,47 @@ if there is a libXXX-ocaml package in debian/control;
 
 =item 2.
 
-dependency from libXXX-ocaml-dev to ocaml-findlib if the package ships any META
-file in the OCaml library directory;
+dependency from libXXX-ocaml-dev to the appropriate libYYYY-ocaml-dev-NNNN
+packages;
 
 =item 3.
 
-dependency from libXXX-ocaml, if any, to the appropriate ocaml-base-* package
-(please note that the substvar for libXXX-ocaml will be filled while processing
-libXXX-ocaml-dev);
+dependency from libXXX-ocaml to the appropriate libYYYY-ocaml-NNNN packages.
 
 =item 4.
 
-dependency on ocaml-base-nox-<ocaml_version> for packages shipping bytecode
-non-custom OCaml executables.
+dependency from XXXX to the appropriate libYYYY-ocaml-NNNN packages.
 
 =back
 
+For runtime package ${ocaml:Provides} will be set libXXXX-ocaml-NNNN and 
+for development package to libXXX-ocaml-dev-NNNN.
+
 =head1 OPTIONS
 
 =over 4
 
-=item B<-m> I<filename>
+=item B<--checksum> str
 
-By default, the list of OCaml objects or bytecode binaries shipped by your
-package which should be analyzed for retrieving dependency information is
-guessed by dh_ocaml.
+Checksum are automatically computed from exported interface by the dev/runtime
+package. This checksum can only show a partial information about the interface.
+In this case the checksum computation can be replaced by another string which 
+gives more information about dependencies.
+
+Typically, ocaml-nox/ocaml-base-nox package doesn't use a computed checksum but 
+the version of OCaml.
+
+=item B<--nodefined-map> I<dev1:unit1,unit2,...>
+
+Ignore some exported unit of package/runtime dev1. This option should be used
+with care. It is a very special case, when one library ship a drop-in replacement
+for another library. Most of the time if one library ship the same unit it
+should be considered as an error.
 
-The -m option permit to specify a file which lists, one per line, that
-OCaml objects or bytecode binaries. Objects should be in one of the
-format understandable by ocamlobjinfo (*.cma, *.cmi, *.cmo) and
-binaries understandable by ocamlbyteinfo. Files are considered
-relative to the package build directory.
+This option can be repeated as much as needed to define ignore for all development 
+packages.
 
-=item B<-l> I<dev1:runtime1,dev2:runtime2,...>
+=item B<--runtime-map> I<dev1:runtime1,dev2:runtime2,...>
 
 The association between development part of libraries and their runtimes is
 guessed by dh_ocaml according to the OCaml packaging policy. Thus,
@@ -139,20 +143,33 @@ libXXX-ocaml-dev is the name of the package shipping the development part of XXX
 library while libXXX-ocaml, if any, is the name of the package shipping the
 corresponding runtime.
 
-Using -l you could override the pairs development package name, runtime package
-name. The value passed to -l admits no spaces and must be a comma separated list
-of items. Each item can be a single package name (stating that that name
-corresponds to the development part of a library) or two package names separated
-by a colon (stating that the first corresponds to the development part of a
-library, while the second to its accompanying runtime part).
+Using --runtime-map you could override the pairs development package name,
+runtime package name. The value passed to --runtime-map admits no spaces and
+must be a comma separated list of items. Each item can be a single package name
+(stating that that name corresponds to the development part of a library) or
+two package names separated by a colon (stating that the first corresponds to
+the development part of a library, while the second to its accompanying runtime
+part).
 
-=item B<-v>, B<--verbose>
-
-Verbose mode: show all commands that modify the package build
-directory and pass verbose option to ocaml-md5sums.
+Every package that doesn't follow libXXX-ocaml-dev/libXXX-ocaml or which is not
+defined in the runtime map are considered to be binary package and will be searched
+only for bytecode.
 
 =back
 
+=head1 FILES
+
+=item I<debian/libXXX-ocaml-dev.olist>
+
+By default, the list of OCaml objects or bytecode binaries shipped by your
+package which should be analyzed for retrieving dependency information is
+guessed by dh_ocaml.
+
+This file permit to specify a file which lists, one per line, that OCaml
+objects or bytecode binaries. Objects should be in one of the format
+understandable by ocamlobjinfo, ocamldumpapprox, ocamlplugininfo or
+ocamlbyteinfo. Files are considered relative to the package build directory.
+
 =head1 CONFORMS TO
 
 Debian policy, version 3.7.2
@@ -161,174 +178,285 @@ OCaml packaging policy, version 1.0.0
 
 =cut
 
-# add an entry to the ocaml:Depends substvar, filter out dummy "-" values
-sub add_ocaml_dep($$$) {
-  my ($package, $dep, $version) = @_;
-  return if $dep eq "-" or $package eq "";
-  if ($version =~ /-\s*$/) {  # ocaml-md5sums returns "-" for "no version"
-    addsubstvar $package, "ocaml:Depends", $dep;
-  } else {
-    addsubstvar $package, "ocaml:Depends", $dep, $version;
-  }
-}
+my $omd5 = $ENV{OCAML_MD5SUMS};
+$omd5 = "/usr/bin/ocaml-md5sums" unless $omd5;
+error "$omd5 does not exists or is not executable" unless -x $omd5;
 
-# fill the ocaml:Depends substvar, reading info from file
-sub fill_ocaml_depends($$$$$) {
-  my ($package, $tmp, $fname, $is_library, $runtime) = @_;
-  delsubstvar $package, "ocaml:Depends"; # for idempotency
-  if (-f $fname) {
-    open DEPS, "< $fname" or die "can't open $fname";
-    while (my $line = <DEPS>) {
-      chomp $line;
-      if ($line =~ /^\s*(.+)\s+(.+)\s+(.+)\s*$/) {
-        # matched groups: dev_dep, runtime_dep, dep_version
-        if ($is_library) {
-          add_ocaml_dep $package, $1, ">= $3";
-          add_ocaml_dep $package, $runtime, "= $dh{VERSION}" if $runtime;
-          add_ocaml_dep $runtime, $2, ">= $3";
-        } else {
-          add_ocaml_dep $package, $2, ">= $3";
-        }
-      }
-    }
-    close DEPS;
-  }
-  add_ocaml_dep $package, "ocaml-base-nox-$ocaml_version", "-" unless $is_library;
-}
+my $md5dir = "/var/lib/ocaml/md5sums";
+my $md5ext = ".md5sums";
+my $ocaml_magic_line = "#!/usr/bin/ocamlrun";
 
-# fill the ocaml:Provides substvar
-sub fill_ocaml_provides($$$$) {
-  my ($package, $tmp, $fname, $is_library) = @_;
-  return if (not $is_library);
-  delsubstvar $package, "ocaml:Provides"; # for idempotency
-  if (-f $fname) {
-    open PROV, "< $fname" or die "can't open $fname";
-    while (my $line = <PROV>) {
-      chomp $line;
-      addsubstvar $package, "ocaml:Provides", $line;
+# Parse provides/depends line
+sub parse_provides ($)
+{
+  my ($line) = @_;
+  my ($dev, $runtime, $version, $ck) = split /\s+/,$line;
+  error "Malformed provides/depends line '$line'" unless $dev && $runtime && $version && $ck;
+  return ($dev, $runtime, $version, $ck);
+};
+
+# Build map for dev/runtime packages from command line options
+my %override_run_of_dev;
+my %override_dev_of_run;
+if (defined($dh{RUNTIME_MAP}))
+{
+  my @lst = split /,/,$dh{RUNTIME_MAP};
+  foreach (@lst)
+  {
+    if (/(.*):(.*)/)
+    {
+      $override_run_of_dev{$1} = $2;
+      $override_dev_of_run{$2} = $1;
     }
-    close PROV;
+    elsif (/(.*)/)
+    {
+      $override_run_of_dev{$1} = "-";
+    }
+    else
+    {
+      error "Malformed map runtime '$_'";
+    };
+  };
+};
+
+# Build map for dev/nodefined from command line options and file
+my %nodefined;
+if (defined($dh{NODEFINED_MAP}))
+{
+  foreach (@{$dh{NODEFINED_MAP}})
+  {
+    error "Malformed nodefined map '$_'" unless /(.*):(.*)/;
+    my $package = $1;
+    my @former = ();
+    my @nodef = @{$nodefined{$package}} if exists $nodefined{$package};
+    push(@nodef,split /,/,$2);
+    $nodefined{$1} = \@nodef;
+  };
+};
+foreach (@{$dh{DOPACKAGES}}) {
+  my $fn = pkgfile($_, "onodefined");
+  if ($fn && -e $fn)
+  {
+    open(FH, "<", $fn);
+    my @nodef = @{$nodefined{$_}} if exists $nodefined{$_};
+    push(@nodef,<FH>);
+    $nodefined{$_} = \@nodef;
   }
+};
+
+# Sort packages into dev, runtime and simple binary package
+my %dev_packages;
+my @binary_packages;
+foreach (@{$dh{DOPACKAGES}}) {
+  if (exists $override_run_of_dev{$_})
+  { $dev_packages{$_} = $override_run_of_dev{$_} }
+  elsif (exists $override_dev_of_run{$_})
+  { $dev_packages{$override_dev_of_run{$_}} = $_ }
+  elsif (/^lib.*-ocaml-dev$/)
+  { $dev_packages{$_} = "-" }
+  elsif (/^lib(.*)-ocaml$/)
+  { $dev_packages{"lib$1-ocaml-dev"} = $_ }
+  else
+  { push(@binary_packages, $_) }
 }
 
-# check if a given binary package exists in debian/control
-sub package_exists($) {
-  my ($name) = @_;
-  my $retval = grep /^\Q$name\E$/, getpackages();
-  return $retval;
-}
-
-# return true if a given package has to be handled as an ocaml development
-# library package. Usually this implies that package has a name like
-# libXXX-ocaml-dev, but could be overridden with -l
-# -l argument has the form "devpkg:runtime,devpkg:runtime,..." devpkg is the
-# name of the development package :runtime (optional part) is the name of the
-# associated runtime package
-# examples: -l foo    -l foo:bar    -l foo:bar,baz,dum:dam
-sub is_library($$) {
-  my ($package, $overrides) = @_;
-  return 1 if $overrides and $overrides =~ /(^|,)\Q$package\E($|:|,)/;
-  return ($package =~ /^lib.*-ocaml-dev$/);
-}
-
-# return true if a given package has to be handled as containing ocaml binaries
-# usually this implies that package name does not match libXXX-ocaml(-dev)? but
-# overrides should be considered as per is_library above
-sub is_binary($$) {
-  my ($package, $overrides) = @_;
-  return 0 if $overrides and $overrides =~ /(^|,|:)\Q$package\E($|:|,)/;
-  return (not ($package =~ /^lib.*-ocaml(-dev)?$/));
-}
-
-# return the runtime package corresponding to a given one
-sub runtime_of_library($$) {
-  my ($package, $overrides) = @_;
-  my $runtime = "";
-  if ($overrides and $overrides =~ /(^|,)\Q$package\E:([^,]+)/) {
-    $runtime = $2;
-  } elsif ($package =~ /^(lib.*-ocaml)-dev$/) {
-    $runtime = $1;
+# Check that every package exists
+my %all_packages;
+$all_packages{$_} = 1 foreach getpackages();
+foreach (keys(%dev_packages), values(%dev_packages), @binary_packages)
+{
+  error "'$_' doesn't exists" unless ($_ eq "-" || exists($all_packages{$_}));
+};
+
+# Flags for calling ocaml-md5sums
+my $flags = "";
+$flags .= " -v" if $dh{VERBOSE};
+$flags .= " -checksum $dh{CHECKSUM}" if $dh{CHECKSUM};
+
+verbose_print "+++ Remove former .olist.debhelper files +++";
+foreach (keys(%dev_packages), @binary_packages) {
+  my $fn = pkgfile($_, "olist.debhelper");
+  if ($fn)
+  {
+    verbose_print("Remove $fn");
+    unlink $fn unless $dh{NO_ACT};
+  };
+};
+
+verbose_print "+++ Generate .olist.debhelper files +++";
+sub test_bytecode ($)
+{
+  my ($bin) = @_;
+  my $line = `head -1 $bin` || return 0;
+  chomp $line;
+  return ($line eq $ocaml_magic_line)
+};
+
+my %olist;
+foreach my $package (keys(%dev_packages), @binary_packages)
+{
+  my $is_dev = exists $dev_packages{$package};
+  my $has_runtime = $is_dev && $dev_packages{$package} ne "-";
+  my $olist_fn = "debian/".(pkgext $package)."olist.debhelper";
+  $olist{$package} = $olist_fn;
+  if (pkgfile($package, "olist"))
+  {
+    if (!$dh{NO_ACT})
+    {
+      open(FH, "<", pkgfile($package, "olist"));
+      open(FD, ">", $olist_fn);
+      foreach (<FH>)
+      {
+        print FD (tmpdir $package)."/$_\n";
+      }
+      close(FH);
+      close(FD);
+    }
   }
-  return (package_exists $runtime ? $runtime : "");
-}
+  else
+  {
+    my @search_path = tmpdir $package;
+    push(@search_path, tmpdir($dev_packages{$package})) if $is_dev && $has_runtime;
+
+    open(OLIST, ">", $olist_fn) unless $dh{NO_ACT};
+    # Search for OCaml bytecode binaries
+    {
+      find
+        sub {
+          (-f $_ && -x $_)
+          &&
+          !excludefile($File::Find::name)
+          &&
+          test_bytecode($_)
+          &&
+          (verbose_print "Adding $File::Find::name to scanned object")
+          &&
+          (!$dh{NO_ACT})
+          &&
+          (print OLIST $File::Find::name."\n")
+        }, @search_path;
+    };
+
+    # Search for OCaml objects
+    if ($is_dev)
+    {
+      my @paths = map {"$_/usr/lib" if -e "$_/usr/lib"} @search_path;
+
+      find 
+        sub {
+          $_ =~ /\.cm([iaox]|x[as])$/
+          &&
+          !excludefile($File::Find::name)
+          &&
+          (verbose_print "Adding ".$File::Find::name." to scanned object")
+          &&
+          (!$dh{NO_ACT})
+          &&
+          (print OLIST $File::Find::name."\n")
+        }, @paths;
+    };
+    close(OLIST) unless $dh{NO_ACT};
+  };
+};
+
+verbose_print "+++ Compute .md5sums files for dev packages +++";
+my %oinfo;
+foreach my $package (keys(%dev_packages)) {
+  my $runtime = $dev_packages{$package};
+  $runtime = undef if $runtime && $runtime eq "-";
+  my $md5sums_fn = (tmpdir $package)."/$md5dir/$package$md5ext";
+  my $oinfo_fn = "debian/".(pkgext $package)."oinfo.debhelper";
+  $oinfo{$package} = $oinfo_fn;
+  my $oprovides_fn = "debian/".(pkgext $package)."oprovides.debhelper";
+
+  isnative($package); # set $dh{VERSION}
+  my $local_flags = "$flags --package $package --version $dh{VERSION}";
+  $local_flags .= " --runtime ".$runtime if $runtime;
+  $local_flags .= " ".join(" ",map {("--nodefined", $_)} @{$nodefined{$package}})
+    if exists $nodefined{$package};
 
-sub get_omd5_params($) {
-  my ($package) = @_;
-  my %omd5_params;
-  isnative($package); # sets $dh{VERSION}
-  $omd5_params{"tmp"} = tmpdir $package;
-  $omd5_params{"ext"} = pkgext $package;
-  $omd5_params{"oinfo"} = "debian/".$omd5_params{"ext"} . "oinfo.debhelper"; # ocaml objects info
-  $omd5_params{"olist"} = "debian/".$omd5_params{"ext"} . "olist.debhelper"; # ocaml object list
-  $omd5_params{"oprovides"} = "debian/".$omd5_params{"ext"} . "oprovides.debhelper"; # provided package
-  $omd5_params{"olist"} = $dh{M_PARAMS} if $dh{M_PARAMS}; # override object list with -m
-  $omd5_params{"odeps"} = "debian/".$omd5_params{"ext"} . "odeps.debhelper"; # ocaml dependencies
-  $omd5_params{"runtime"} = runtime_of_library $package, $dh{L_PARAMS};
-  return %omd5_params;
+  # compute md5sums files
+  doit(qw/mkdir -p/, dirname $md5sums_fn);
+  complex_doit("$omd5 $local_flags" 
+    . " --dump-info $oinfo_fn"
+    . " --dump-provides $oprovides_fn"
+    . " compute < ".$olist{$package}
+    . " > $md5sums_fn");
+
+  if (!$dh{NO_ACT})
+  {
+    open (FH, "<", $oprovides_fn) || die "Cannot open $oprovides_fn";
+    foreach (<FH>)
+    {
+      my ($prov_dev, $prov_run, $version, $ck) = parse_provides($_);
+      # Prepare ocaml:Provides|Depends for dev/runtime package
+      delsubstvar $package, "ocaml:Provides";
+      delsubstvar $package, "ocaml:Depends";
+      addsubstvar $package, "ocaml:Provides", "$prov_dev-$ck";
+      if ($runtime)
+      {
+        addsubstvar $package, "ocaml:Depends", "$runtime-$ck";
+        delsubstvar $runtime, "ocaml:Provides";
+        delsubstvar $runtime, "ocaml:Depends";
+        addsubstvar $runtime, "ocaml:Provides", "$prov_run-$ck";
+      };
+    };
+    close(FH);
+  };
+
+  $flags .= " --md5sums-dir ".(dirname $md5sums_fn);
+  unlink $oprovides_fn if -f $oprovides_fn;
 }
 
-# main
-exit 0 if $dh{NO_ACT};
-complex_doit "mkdir -p debian/dh_ocaml_md5sums";
-foreach my $package (@{$dh{DOPACKAGES}}) {
-  my %omd5_params = get_omd5_params($package);
-  my $flags = "--package $package --version $dh{VERSION}";
-  $flags .= " --runtime ".$omd5_params{"runtime"} if $omd5_params{"runtime"};
-  $flags .= " -v" if $dh{VERBOSE};
-
-  # search for OCaml objects
-  unless ($dh{M_PARAMS}) {
-    complex_doit " > $omd5_params{'olist'}";
-    complex_doit "find $omd5_params{'tmp'}$ocaml_lib_dir -type f "
-               . "-name '*.cm[ao]' >> $omd5_params{'olist'}"
-      unless (not -e "$omd5_params{'tmp'}$ocaml_lib_dir");
-
-    # search for OCaml bc binaries
-    my @binaries = split /\n/, `find $omd5_params{"tmp"} -type f -perm -0100`;
-    open(OLIST, ">> $omd5_params{'olist'}");
-    foreach my $bin (@binaries) {
-      my $line = `head -1 $bin` or next;
-      chomp $line;
-      print OLIST "$bin\n" if $line eq $ocaml_magic_line;
+verbose_print "+++ Compute dependencies for dev +++";
+foreach my $package (keys(%dev_packages)) {
+  my $runtime = $dev_packages{$package};
+  $runtime = undef if $runtime && $runtime eq "-";
+
+  # Extract deps
+  my $cmd = "$omd5 $flags --load-info $oinfo{$package} dep";
+  verbose_print $cmd;
+  if (!$dh{NO_ACT})
+  {
+    foreach (`$cmd`)
+    {
+      my ($dep_dev, $dep_run, $version, $ck) = parse_provides($_);
+      # matched groups: dev_dep, runtime_dep, dep_version
+      addsubstvar $package, "ocaml:Depends", "$dep_dev-$ck";
+      addsubstvar $runtime, "ocaml:Depends", "$dep_run-$ck" if $runtime && $dep_run ne "-";
     }
-    close(OLIST);
   }
-
-  # compute md5sums files
-  complex_doit "mkdir -p $omd5_params{'tmp'}$md5dir";
-  complex_doit("$omd5 $flags --dump-info $omd5_params{'oinfo'}"
-    . " compute < $omd5_params{'olist'}"
-    . " | sort -k 2"  # optional pass, just for "pretty" printing
-    . " > $omd5_params{'tmp'}$md5dir/$package$md5ext");
-  complex_doit "cp $omd5_params{'tmp'}$md5dir/$package$md5ext debian/dh_ocaml_md5sums";
 }
 
-foreach my $package (@{$dh{DOPACKAGES}}) {
-  my %omd5_params = get_omd5_params($package);
-  my $library_bit=0;
-  if (is_library $package, $dh{L_PARAMS}) {
-    $library_bit=1;
+verbose_print "+++ Compute dependencies for binary packages+++";
+foreach my $package (@binary_packages) {
+  # For idempotency
+  delsubstvar $package, "ocaml:Depends";
+
+  # Compute deps
+  my $cmd = "$omd5 $flags --package $package dep < $olist{$package}";
+  verbose_print "$cmd";
+  if (!$dh{NO_ACT})
+  {
+    foreach (`$cmd`)
+    {
+      my ($dep_dev, $dep_run, $version, $ck) = parse_provides($_);
+      # matched groups: dev_dep, runtime_dep, dep_version
+      addsubstvar $package, "ocaml:Depends", "$dep_run-$ck" if $dep_run ne "-";
+    }
   }
-
-  # compute deps
-  complex_doit "$omd5 --load-info $omd5_params{'oinfo'}"
-             . " --md5sums-dir debian/dh_ocaml_md5sums"
-             . " dep < $omd5_params{'olist'} > $omd5_params{'odeps'}";
-
-  # fill depends and provides fields
-  fill_ocaml_depends $package, $omd5_params{"tmp"}, $omd5_params{"odeps"}, $library_bit, $omd5_params{"runtime"};
-  fill_ocaml_provides $package, $omd5_params{"tmp"}, $omd5_params{"oprovides"}, $library_bit;
 }
-complex_doit "rm -Rf debian/dh_ocaml_md5sums";
 
 =head1 SEE ALSO
 
-L<ocamlobjinfo(1)>, L<ocamlbyteinfo(1)>, L<debhelper(7)>, L<ocaml-md5sums(1)>
+L<ocamlobjinfo(1)>, L<ocamlbyteinfo(1)>, L<ocamldumpapprox>,
+L<ocamlplugininfo>, L<debhelper(7)>, L<ocaml-md5sums(1)>
 
 This program is a part of debhelper.
 
 =head1 AUTHORS
 
-Stefano Zacchiroli <zack at debian.org>, Samuel Mimram <smimram at debian.org>, Mehdi Dogguy <mehdi at dogguy.org>
+Stefano Zacchiroli <zack at debian.org>, Samuel Mimram <smimram at debian.org>, 
+Mehdi Dogguy <mehdi at dogguy.org>, Sylvain Le Gall <gildor at debian.org>
 
 =cut
diff --git a/ocaml-md5sums/ocaml-md5sums b/ocaml-md5sums/ocaml-md5sums
index e9819ce..6f698da 100755
--- a/ocaml-md5sums/ocaml-md5sums
+++ b/ocaml-md5sums/ocaml-md5sums
@@ -50,11 +50,18 @@ sub new
   $self->{file} = ();
   $self->{nodefined} = ();
   $self->{nodefined}{$_} = 1 foreach @nodefined;
+  $self->{checksum} = ();
 
   bless $self, $class;
   return $self;
 };
 
+sub set_checksum 
+{
+  my ($self, $checksum) = @_;
+  $self->{checksum} = $checksum;
+};
+
 sub add_unit
 {
   my ($self, $symbol_table, $unit_name, $md5) = @_;
@@ -152,7 +159,7 @@ sub add_object
     foreach (`$ocamlbyteinfo $obj_file`)
     {
       $processed = 1;
-      if (/UNIT ([A-Fa-f0-9]+) (\S+)/)
+      if (/^\s*([a-fA-F0-9]+)\s+(\S+)$/)
       {
         $self->add_unit("imported", $2, $1);
       };
@@ -222,10 +229,7 @@ sub print
         (" ",
          $md5,
          $unit_name,
-         $self->{dev},
-         $self->{runtime},
-         $self->{version}),
-         "\n");
+         $self->compute_provides()));
   };
 };
 
@@ -259,11 +263,12 @@ sub load
   open(FH, "<", $file) || die "Cannot open file $file";
   foreach (<FH>)
   {
-    my ($md5, $unit_name, $dev, $runtime, $version) = split /\s+/;
+    my ($md5, $unit_name, $dev, $runtime, $version, $ck) = split /\s+/;
     $self->load_assign("dev", $dev);
     $self->load_assign("runtime", $runtime);
     $self->load_assign("version", $version);
     $self->add_unit("defined", $unit_name, $md5);
+    $self->{checksum} = $ck;
   };
   close(FH);
   $self->squeeze_imported();
@@ -274,7 +279,7 @@ sub load
 sub to_string
 {
   my ($self) = @_;
-  if (defined($self->{file}))
+  if ($self->{dev} eq "-" && defined($self->{file}))
   {
     return $self->{file};
   }
@@ -342,8 +347,7 @@ sub print_depends
 {
   my ($self) = @_;
 
-  print "$_->{dev} $_->{runtime} $_->{version}\n"
-    foreach (@{$self->{depends}});
+  print $_->compute_provides() foreach (@{$self->{depends}});
 
   foreach (keys(%{$self->{imported}}))
   {
@@ -368,22 +372,36 @@ sub check_exported
 
 use Digest::MD5 qw/md5_hex/;
 
-sub dump_provides
+sub compute_provides 
 {
-  my ($self, $file) = @_;
-  my $hex = md5_hex(join("",sort keys(%{$self->{"defined"}})));
-  my $sig = hex(substr($hex, 0, 6));
-  my $fact;
-  my @fact_print;
-  for (my $i = 0; $i < 5; $i++)
+  my ($self) = @_;
+
+  my $ck = $self->{checksum};
+  if (!$ck)
   {
-    $fact = $sig % 36;
-    $sig = $sig / 36;
-    push(@fact_print, (chr ($fact + ($fact < 10 ? (ord '0') : ((ord 'a') - 10)))));
+    my $hex = md5_hex(join("",sort keys(%{$self->{"defined"}})));
+    my $sig = hex(substr($hex, 0, 6));
+    my $fact;
+    my @fact_print;
+    for (my $i = 0; $i < 5; $i++)
+    {
+      $fact = $sig % 36;
+      $sig = $sig / 36;
+      push(@fact_print, (chr ($fact + ($fact < 10 ? (ord '0') : ((ord 'a') - 10)))));
+    };
+
+    $ck = join "", @fact_print;
   };
 
+  return "$self->{dev} $self->{runtime} $self->{version} $ck\n";
+};
+
+sub dump_provides
+{
+  my ($self, $file) = @_;
+  my $ck = $self->compute_provides();
   open(FH, ">", $file) || die "Cannot open file $file";
-  print FH ($self->{dev},"-", at fact_print);
+  print FH ($self->compute_provides());
   close(FH);
 };
 
@@ -406,6 +424,7 @@ my $dump_info_fn;
 my $load_info_fn;
 my $print_version;
 my $dump_provides;
+my $checksum;
 my @md5sums_dirs=("/var/lib/ocaml/md5sums");
 my @nodefined = ();
 
@@ -437,6 +456,7 @@ GetOptions(
   "dump-provides=s" => \$dump_provides,
   "md5sums-dir=s"   => \@md5sums_dirs,
   "nodefined=s"     => \@nodefined,
+  "checksum=s"      => \$checksum,
   "my-version"      => \$print_version,
   "v+"              => \$verbose,
   "<>"              => \&process_not_option,
@@ -461,6 +481,7 @@ if ($action eq "compute" || $action eq "dep")
        $package_runtime,
        $package_version,
        @nodefined);
+  $md5sums->set_checksum($checksum) if defined($checksum);
   $md5sums->read_dump($load_info_fn) if defined($load_info_fn);
   foreach (get_objects(defined($load_info_fn)))
   {
@@ -560,6 +581,10 @@ Write provides for the package into given file.
 
 Add directory to the list of directory looked for md5sums files.
 
+=item B<--checksum> str
+
+Checksum to use.
+
 =item B<-help>
 
 Print a brief help message and exits.

-- 
dh-ocaml packaging



More information about the Pkg-ocaml-maint-commits mailing list