[Pkg-ocaml-maint-commits] r1214 - trunk/tools/dh_ocaml
Stefano Zacchiroli
zack@costa.debian.org
Thu, 07 Apr 2005 13:45:22 +0000
Author: zack
Date: 2005-04-07 13:45:21 +0000 (Thu, 07 Apr 2005)
New Revision: 1214
Modified:
trunk/tools/dh_ocaml/dh_ocaml
Log:
- uses ocaml-md5sums (code really lighter now)
- try to guess objects related to ocaml bytecode binaries (still to be tested)
- wrote (first draft of) pod documentation
Modified: trunk/tools/dh_ocaml/dh_ocaml
===================================================================
--- trunk/tools/dh_ocaml/dh_ocaml 2005-04-06 15:01:26 UTC (rev 1213)
+++ trunk/tools/dh_ocaml/dh_ocaml 2005-04-07 13:45:21 UTC (rev 1214)
@@ -6,7 +6,7 @@
# Copyright (C) 2005, Stefano Zacchiroli <zack@debian.org>
#
# Created: Fri, 01 Apr 2005 19:50:48 +0200 zack
-# Last-Modified: Mon, 04 Apr 2005 20:52:23 +0200 zack
+# Last-Modified: Thu, 07 Apr 2005 09:40:15 +0200 zack
#
# This is free software, you can redistribute it and/or modify it under the
# terms of the GNU General Public License version 2 as published by the Free
@@ -22,17 +22,18 @@
# Place, Suite 330, Boston, MA 02111-1307 USA
#
-# TODO ask Joey Hess about how much dh_ocaml follows debhelper guidelines
# TODO check how dh_ocaml work when multiple binary packages are being built
# TODO for libraries: add proper dependencies on ocaml (and findlib?)
# TODO for binaries: check if package is shipping any bytecode binaries (head -1
# should be enough) and add proper dependencies on ocaml
# TODO complete POD documentation
-# TODO add comment headers for uncommented subs
+# TODO check if dh_ocaml md5sums calculation works with -pack -ed units (e.g.
+# Foo.Bar)
=head1 NAME
-dh_ocaml - compute OCaml md5sums and calculate OCaml dependencies
+dh_ocaml - calculates ocaml dependencies and adds postinst and prerm ocaml
+scripts
=cut
@@ -40,211 +41,116 @@
use Debian::Debhelper::Dh_Lib;
init();
-# dh_perl documentation follows, cut and pasted here since I don't know POD
-# syntax
-# -- Zack
-#
-# =head1 SYNOPSIS
-#
-# B<dh_ocaml> [S<I<debhelper options>>] [B<-d>] [S<I<library dirs ...>>]
-#
-# =head1 DESCRIPTION
-#
-# dh_perl is a debhelper program that is responsible for generating
-# the ${perl:Depends} substitutions and adding them to substvars files.
-#
-# The program will look at perl scripts and modules in your package,
-# and will use this information to generate a dependency on perl or
-# perlapi. The dependency will be substituted into your package's control
-# file wherever you place the token "${perl:Depends}".
-#
-# =head1 OPTIONS
-#
-# =over 4
-#
-# =item B<-d>
-#
-# In some specific cases you may want to depend on perl-base rather than the
-# full perl package. If so, you can pass the -d option to make dh_perl generate
-# a dependency on the correct base package. This is only necessary for some
-# packages that are included in the base system.
-#
-# Note that this flag may cause no dependency on perl-base to be generated at
-# all. perl-base is Essential, so its dependency can be left out, unless a
-# versioned dependency is needed.
-#
-# =item B<-V>
-#
-# By default, scripts and architecture independent modules don't depend
-# on any specific version of perl. The -V option causes the current
-# version of the perl (or perl-base with -d) package to be specified.
-#
-# =item I<library dirs>
-#
-# If your package installs perl modules in non-standard
-# directories, you can make dh_perl check those directories by passing their
-# names on the command line. It will only check the vendorlib and vendorarch
-# directories by default.
-#
-# =back
-#
-# =head1 CONFORMS TO
-#
-# Debian policy, version 3.0.1
-#
-# Perl policy, version 1.18
-#
-# =cut
-
my $ocamlc = "/usr/bin/ocamlc";
-my $ocamlobjinfo = "/usr/bin/ocamlobjinfo";
-foreach my $bin ($ocamlc, $ocamlobjinfo) {
+# my $ocaml_md5sums = "/usr/bin/ocaml-md5sums";
+my $ocaml_md5sums = "/home/zack/dati/source/ocaml/dh_ocaml/ocaml-md5sums";
+my @binaries = ($ocamlc, $ocaml_md5sums);
+foreach my $bin (@binaries) {
error "$bin does not exists or is not executable" unless -x $bin;
}
+chomp (my $ocaml_lib_dir = `$ocamlc -where`);
-my $ocaml_version = `$ocamlc -version`;
-my $ocaml_lib_dir = `$ocamlc -where`;
-chomp ($ocaml_version, $ocaml_lib_dir);
my $md5sums_dir = "/var/lib/ocaml/md5sums";
my $md5sums_ext = ".md5sums";
-my $md5sums_registry_path = "$md5sums_dir/MD5SUMS";
-my $dep_substvar = "ocaml:Depends";
+my $ocaml_magic_line = "#!/usr/bin/ocamlrun";
-# given as input a directory, returns a list of all ocaml objects installed (at
-# any depth) in that directory
-sub find_objects($) {
+=head1 SYNOPSIS
+
+B<dh_ocaml> [S<I<debhelper options>>]
+
+=head1 DESCRIPTION
+
+dh_ocaml is a debhelper program that is responsible for generating
+the ${ocaml:Depends} substitutions and adding them to substvars files. It will
+also add a postinst and prerm script if required.
+
+The program will look at ocaml objects (files matching *.cm[ao]) shipped by your
+package. From them, dh_ocaml uses ocamlobjinfo for collecting information about
+ocaml modules (or units, in ocamlobjinfo terminology) defined and used by your
+package. Collected information will be used both for extracting dependencies
+information from the local ocaml md5sums registry (stored in
+/var/lib/ocaml/md5sums/MD5SUMS) and for creating libfoo-ocaml-dev.md5sums entry
+for the registry.
+
+Dependencies information will be used for filling the ${ocaml:Depends}
+subtitution while .md5sums entry will be installed in /var/lib/ocaml/md5sums/.
+If such an entry gets installed, postinst and prerm script will also be created
+in order to update the registry at package install/removal time.
+
+=head1 CONFORMS TO
+
+Debian policy, version 3.6.1.1
+
+OCaml packaging policy, version 0.6
+
+=cut
+
+# find ocaml bytecode executables contained in a given directory
+sub find_ocaml_bc_binaries($) {
my ($dir) = @_;
- my $cmd = "find $dir$ocaml_lib_dir -type f -name '*.cma'";
- verbose_print $cmd;
- my $out = `$cmd` or error "can't execute \"$cmd\" for pipe-reading";
- my @objects = split /\n/, $out;
- return @objects;
+ my @binaries = split /\n/, `find $dir -type f -perm -0100`;
+ my @bc_binaries;
+ foreach my $bin (@binaries) {
+ my $line = `/usr/bin/head -1 $bin` or next;
+ chomp $line;
+ push @bc_binaries, $line if $line eq $ocaml_magic_line;
+ }
+ return @bc_binaries;
}
-# globals
-my %defined_md5sums; # (unit name -> md5sum) mappings for units _defined_ by
- # package's objects
-my %imported_md5sums; # same mappings for units _imported_ by package's objects
-my %md5sums_registry; # parsed version of local md5sums registry
-my $registry_parsed = 0; # flag used for lazy registry parsing
-
-# given as input a list of ocaml object filenames, fills
-# %{defin,import}ed_md5sums. Use ocamlobjinfo to retrieve md5sum information
-sub compute_md5sums(@) {
- my @objects = @_;
- my %md5sums;
- foreach my $object (@objects) {
- my $cmd = "$ocamlobjinfo $object";
- verbose_print "\"$cmd\"";
- open OBJINFO, "$cmd |" or error "can't execute \"$cmd\" for pipe-reading";
- my $unit_name = "";
- while (my $line = <OBJINFO>) {
+# read ocaml dependencies information from file and fill ocaml:Depends substvar
+sub fill_ocaml_depends($$) {
+ my ($package, $fname) = @_;
+ delsubstvar($package, "ocaml:Depends");
+ if (-f $fname) {
+ open DEPS, "< $fname" or die "Can't open $fname";
+ while (my $line = <DEPS>) {
chomp $line;
- if ($line =~ /^\s*Unit\s+name\s*:\s*(\w+)\s*$/) {
- $unit_name = $1;
-# verbose_print "Unit $unit_name";
- } elsif ($line =~ /^\s*([0-9A-Fa-f]{32})\s+(\w+)\s*$/) {
- if ($2 eq $unit_name) {
- $defined_md5sums{$2} = $1;
-# verbose_print "Defined $1 $2";
- } else {
- $imported_md5sums{$2} = $1;
-# verbose_print "Imported $1 $2";
- }
- }
+ my ($dep_package, $dep_version) = split /\s+/, $line;
+ next unless $dep_package and $dep_version;
+ addsubstvar($package, "ocaml:Depends", $dep_package, ">= $dep_version");
}
- close OBJINFO;
+ close DEPS;
}
}
-# create /var/lib/ocaml/md5sums/ entry and create post{inst,rm} scripts for
-# updating md5sums registry on users' machines
-sub add_md5sums_registry_entry($) {
- my ($package) = @_;
+# main
+foreach my $package (@{$dh{DOPACKAGES}}) {
my $tmpdir = tmpdir($package);
- my $md5sums_fname = "$tmpdir$md5sums_dir/$package$md5sums_ext";
- doit("mkdir -p " . dirname($md5sums_fname));
- open MD5SUMS, "> $md5sums_fname";
- foreach my $unit_name (sort (keys %defined_md5sums)) {
- print MD5SUMS "$defined_md5sums{$unit_name} $unit_name\n";
- }
- close MD5SUMS;
- if (! $dh{NOSCRIPTS}) {
+ isnative($package); # sets $dh{VERSION}
+ my $flags = "--package $package --version $dh{VERSION}";
+ my $objinfo = "debian/$package.ocamlobjinfo~";
+ my $objlist = "debian/$package.ocamlobjects~";
+ my $ocamldeps = "debian/$package.ocamldeps~";
+ if ($package =~ /^lib.*-ocaml-dev$/) { # ocaml library package
+ # create md5sum registry entry and post{inst,rm} scripts
+ complex_doit("/usr/bin/find $tmpdir$ocaml_lib_dir -type f -name '*.cm[ao]' "
+ . "> $objlist");
+ complex_doit("mkdir -p $tmpdir$md5sums_dir");
+ complex_doit("$ocaml_md5sums $flags --dump-info $objinfo compute < $objlist"
+ . " | /usr/bin/sort -k 2" # optional pass, just for "pretty" printing
+ . " > $tmpdir$md5sums_dir/$package$md5sums_ext");
my $sed = "s/#PACKAGE#/$package/; s/#VERSION#/$dh{VERSION}/";
autoscript($package, "postinst", "postinst-ocaml", $sed);
autoscript($package, "postrm", "postrm-ocaml", $sed);
- }
-}
-
-# lazy parsing of md5sum registry /var/lib/ocaml/md5sums/MD5SUMS
-sub load_md5sum_registry() {
- if (! $registry_parsed) {
- open REGISTRY, $md5sums_registry_path;
- my $lineno = 0;
- while (my $line = <REGISTRY>) {
- $lineno++;
- chomp $line;
- next if $line =~ /(^#)|(^\s*$)/; # skip blank lines and comments
- if ($line =~ /^([0-9A-Fa-f]{32})(\s+\S+){3}$/) {
- my ($md5sum, $package, $version, $unit_name) = split /\s+/, $line;
- # mappings like:
- # "9b93712a344b3b9849a73ce19d8c72ce Foo_bar"->"libfoo-ocaml-dev 0.2.3-5"
- my $key = "$md5sum $unit_name";
- if (exists($md5sums_registry{$key})) {
- warning("multiple entries for $key in md5sums registry, "
- . "ocaml dependencies may be wrong");
- }
- $md5sums_registry{$key} = "$package $version";
- } else {
- warning
- "can't parse md5sums registry line ($md5sums_registry_path:$lineno)";
- next;
- }
+ # compute deps for the library
+ complex_doit("$ocaml_md5sums $flags --load-info $objinfo dep < $objlist"
+ . " > $ocamldeps");
+ } else { # ocaml binary package
+ my @binaries = find_ocaml_bc_binaries($tmpdir);
+ complex_doit "> $ocamldeps";
+ foreach my $bin (@binaries) { # try to find .cmo of bc binaries
+ my $guess = basename($bin) . ".cm[ao]";
+ complex_doit("/usr/bin/find . -type f -name '$guess' >> $ocamldeps");
}
- close REGISTRY;
- $registry_parsed = 1;
+ complex_doit("$ocaml_md5sums $flags dep < $objlist > $ocamldeps");
}
+ fill_ocaml_depends($package, $ocamldeps);
}
-sub lookup_dep($$) {
- my ($md5sum, $unit_name) = @_;
- load_md5sum_registry();
- my $dep = $md5sums_registry{"$md5sum $unit_name"};
- if ($dep) {
- my ($deppackage, $version) = split /\s+/, $dep;
- return($deppackage, ">= $version");
- } else {
- return(0, 0);
- }
-}
-
-# compute dependencies of package using md5sum registry installed on the machine
-# which is building the package
-sub fill_substvars($) {
- my ($package) = @_;
- my $tmpdir = tmpdir($package);
- delsubstvar($package, $dep_substvar); # idempotency
- foreach my $unit_name (sort (keys %imported_md5sums)) {
- next if exists $defined_md5sums{$unit_name};
- my ($deppackage, $verinfo) =
- lookup_dep($imported_md5sums{$unit_name}, $unit_name);
- addsubstvar($package, $dep_substvar, $deppackage, $verinfo) if $deppackage;
- }
-}
-
-foreach my $package (@{$dh{DOPACKAGES}}) {
- next unless $package =~ /^lib.*-ocaml-dev$/;
- isnative($package); # sets $dh{VERSION}
- my $tmpdir = tmpdir($package);
- my @objects = find_objects($tmpdir);
- compute_md5sums(@objects); # fills %{defined,imported}_md5sums globals
- add_md5sums_registry_entry($package);
- fill_substvars($package);
-}
-
=head1 SEE ALSO
-L<debhelper(7)>
+L<ocamlobjinfo(1)>, L<debhelper(7)>
This program is a part of debhelper.