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

Re: ddebs



On 25/03/11 18:22, Torsten Werner wrote:
> are there any example packages that build ddebs? That we can use for
> testing dak?

It should happen automatically if you patch debhelper (and CDBS to automatically
get .ddebs out of CDBS-using packages) with my patches. I have just refreshed my
debhelper patch so it applies cleanly again, and I've tested it.

What you need:

ptools (for build-id support, should be easy to remove that part from my patch,
see the pbuildid call in dh_strip). I've put it in [1].

Apply the attached patch to debhelper (applies cleanly on debhelper 8.1.2).

Install the resulting debhelper and build any package that
- produces at least one arch:any package
- doesn't have a -dbg package

E.g. I've tested it with gzip. Just dpkg-buildpackage it with the new debhelper
installed and you'll get:

[...]
dpkg-deb: building package `gzip-ddeb' in `../gzip-ddeb_1.3.12-9_amd64.ddeb'.

$ dpkg --contents gzip-ddeb_1.3.12-9_amd64.ddeb
drwxr-xr-x root/root         0 2011-03-25 21:21 ./
drwxr-xr-x root/root         0 2011-03-25 21:21 ./usr/
drwxr-xr-x root/root         0 2011-03-25 21:21 ./usr/share/
drwxr-xr-x root/root         0 2011-03-25 21:21 ./usr/share/doc/
drwxr-xr-x root/root         0 2011-03-25 21:21 ./usr/share/doc/gzip-ddeb/
-rw-r--r-- root/root     24028 2007-04-13 22:41
./usr/share/doc/gzip-ddeb/changelog.gz
-rw-r--r-- root/root      1101 2011-03-25 20:54 ./usr/share/doc/gzip-ddeb/copyright
-rw-r--r-- root/root      6637 2011-03-25 20:54
./usr/share/doc/gzip-ddeb/changelog.Debian.gz
drwxr-xr-x root/root         0 2011-03-25 21:21 ./usr/lib/
drwxr-xr-x root/root         0 2011-03-25 21:21 ./usr/lib/debug/
drwxr-xr-x root/root         0 2011-03-25 21:21 ./usr/lib/debug/.build-id/
drwxr-xr-x root/root         0 2011-03-25 21:21 ./usr/lib/debug/.build-id/93/
-rw-r--r-- root/root    151197 2011-03-25 21:21
./usr/lib/debug/.build-id/93/6c3dda20627d866fd42cb8a7b05247d7707367.debug

FWIW, build-id and .ddebs don't need to be done at the same time. The only
problem with build-id is that we could get file conflicts if two packages have
*exactly* the same ELF binary. May happen if you build two flavours of the same
package and one binary isn't affected by the different build flags / options. We
could solve this by making dpkg not complain if this happens, ref-counting the
files so it doesn't remove it until all the packages that shipped that file are
removed. Note that this is hypothetical, and if it happened, it would be the
exception.

Also see http://wiki.debian.org/AutomaticDebugPackages

Let me know if you any questions.

Cheers,
Emilio

[1] http://people.debian.org/~pochu/ptools/ptools_0.1-1.dsc
diff -Nru debhelper-8.1.2/debian/changelog debhelper-8.1.2+nmu1/debian/changelog
--- debhelper-8.1.2/debian/changelog	2011-02-14 18:22:19.000000000 +0000
+++ debhelper-8.1.2+nmu1/debian/changelog	2011-03-25 20:52:21.000000000 +0000
@@ -1,3 +1,10 @@
+debhelper (8.1.2+nmu1) UNRELEASED; urgency=low
+
+  * Non-maintainer upload.
+  * Add ddebs support.
+
+ -- Emilio Pozuelo Monfort <pochu@debian.org>  Fri, 25 Mar 2011 20:52:10 +0000
+
 debhelper (8.1.2) unstable; urgency=low
 
   * Fix logging at end of an override target that never actually runs
diff -Nru debhelper-8.1.2/debian/control debhelper-8.1.2+nmu1/debian/control
--- debhelper-8.1.2/debian/control	2011-02-10 23:51:37.000000000 +0000
+++ debhelper-8.1.2+nmu1/debian/control	2011-03-25 20:50:47.000000000 +0000
@@ -10,7 +10,7 @@
 
 Package: debhelper
 Architecture: all
-Depends: ${perl:Depends}, ${misc:Depends}, perl-base (>= 5.10), file (>= 3.23), dpkg-dev (>= 1.14.19), html2text, binutils, po-debconf, man-db (>= 2.5.1-1)
+Depends: ${perl:Depends}, ${misc:Depends}, perl-base (>= 5.10), file (>= 3.23), dpkg-dev (>= 1.14.19), html2text, binutils, po-debconf, man-db (>= 2.5.1-1), ptools
 Suggests: dh-make
 Conflicts: dpkg-cross (<< 1.18), python-support (<< 0.5.3), python-central (<< 0.5.6)
 Description: helper programs for debian/rules
diff -Nru debhelper-8.1.2/Debian/Debhelper/Dh_Lib.pm debhelper-8.1.2+nmu1/Debian/Debhelper/Dh_Lib.pm
--- debhelper-8.1.2/Debian/Debhelper/Dh_Lib.pm	2011-02-10 23:53:58.000000000 +0000
+++ debhelper-8.1.2+nmu1/Debian/Debhelper/Dh_Lib.pm	2011-03-25 20:50:12.000000000 +0000
@@ -18,7 +18,8 @@
 	    &inhibit_log &load_log &write_log &commit_override_log
 	    &dpkg_architecture_value &sourcepackage
 	    &is_make_jobserver_unavailable &clean_jobserver_makeflags
-	    &cross_command);
+	    &cross_command &is_ddeb &ddeb_filename &ddeb_in_control
+	    &ddeb_is_empty &ddebpackage);
 
 my $max_compat=8;
 
@@ -749,6 +750,9 @@
 	my $package="";
 	my $arch="";
 	my $package_type;
+	my $has_arch_dep=0;
+	my $has_ddeb_pkg=0;
+	my $has_dbg_pkg=0;
 	my @list=();
 	my %seen;
 	open (CONTROL, 'debian/control') ||
@@ -756,6 +760,12 @@
 	while (<CONTROL>) {
 		chomp;
 		s/\s+$//;
+		if (/^Maintainer:\s*(.*)/) {
+			$dh{MAINTAINER}=$1;
+		}
+		if (/^Homepage:\s*(.*)/) {
+			$dh{HOMEPAGE}=$1;
+		}
 		if (/^Package:\s*(.*)/) {
 			$package=$1;
 			# Detect duplicate package names in the same control file.
@@ -786,6 +796,9 @@
 					     ($arch ne 'all' &&
 			                      samearch(buildarch(), $arch)))) ||
 			     ! $type)) {
+				$has_arch_dep=1 unless $arch eq 'all';
+				$has_ddeb_pkg=1 if $package=~/-ddeb$/;
+				$has_dbg_pkg=1 if $package=~/-dbg$/;
 				push @list, $package;
 				$package="";
 				$arch="";
@@ -794,6 +807,9 @@
 	}
 	close CONTROL;
 
+	# If there are arch dependent packages in the list, add the -ddeb
+	push @list, ddebpackage() if $has_arch_dep and not ($has_dbg_pkg or $has_ddeb_pkg);
+
 	return @list;
 }
 
@@ -830,6 +846,42 @@
 	return "${package}_${version}_$filearch.udeb";
 }
 
+# Returns true if a given package is a ddeb.
+sub is_ddeb {
+	my $package=shift;
+
+	return $package eq ddebpackage();
+}
+
+# Generates the filename that is used for a ddeb package.
+sub ddeb_filename {
+	isnative(sourcepackage()); # To get the version
+	my $version=$dh{VERSION};
+	$version=~s/^[0-9]+://; # strip any epoch
+	return ddebpackage()."_${version}_".buildarch().".ddeb";
+}
+
+# Returns the ddeb package name
+sub ddebpackage {
+	return sourcepackage()."-ddeb";
+}
+
+# Returns whether the ddeb package is listed in the control file.
+sub ddeb_in_control {
+	my $package=shift;
+
+	return exists $package_types{$package};
+}
+
+# Returns whether the ddeb folder is empty (excluding docs)
+sub ddeb_is_empty {
+	my $tmp="debian/".ddebpackage();
+	my $files=`find $tmp -type f ! \\( -regex '$tmp/usr/share/doc.*' -or -regex '$tmp/DEBIAN/.*' \\)`;
+	chomp $files;
+
+	return $files eq "";
+}
+
 # Handles #DEBHELPER# substitution in a script; also can generate a new
 # script from scratch if none exists but there is a .debhelper file for it.
 sub debhelper_script_subst {
diff -Nru debhelper-8.1.2/dh_auto_install debhelper-8.1.2+nmu1/dh_auto_install
--- debhelper-8.1.2/dh_auto_install	2011-02-08 19:25:35.000000000 +0000
+++ debhelper-8.1.2+nmu1/dh_auto_install	2011-03-25 20:50:18.000000000 +0000
@@ -71,7 +71,7 @@
 # If destdir is not specified, determine it automatically
 if (!$destdir) {
 	my @allpackages=getpackages();
-	if (@allpackages > 1) {
+	if (@allpackages > 2 or  (@allpackages > 1 and ! $allpackages[1] =~ /-ddeb$/)) {
 		$destdir="debian/tmp";
 	}
 	else {
diff -Nru debhelper-8.1.2/dh_builddeb debhelper-8.1.2+nmu1/dh_builddeb
--- debhelper-8.1.2/dh_builddeb	2011-02-08 19:25:35.000000000 +0000
+++ debhelper-8.1.2+nmu1/dh_builddeb	2011-03-25 20:50:18.000000000 +0000
@@ -76,16 +76,20 @@
 				foreach split(":", $ENV{DH_ALWAYS_EXCLUDE});
 		}
 	}
-	if (! is_udeb($package)) {
-		doit("dpkg-deb", @{$dh{U_PARAMS}}, "--build", $tmp, $dh{DESTDIR}.$dh{FILENAME});
-	}
-	else {
-		my $filename=$dh{FILENAME};
+
+	my $filename=$dh{FILENAME};
+	if (is_udeb($package)) {
 		if (! $filename) {
 			$filename="/".udeb_filename($package);
 		}
-		doit("dpkg-deb", @{$dh{U_PARAMS}}, "--build", $tmp, $dh{DESTDIR}.$filename);
 	}
+	elsif (is_ddeb($package)) {
+		next if ddeb_is_empty();
+		if (! $filename) {
+			$filename="/".ddeb_filename();
+		}
+	}
+	doit("dpkg-deb", @{$dh{U_PARAMS}}, "--build", $tmp, $dh{DESTDIR}.$filename);
 }
 
 =head1 SEE ALSO
diff -Nru debhelper-8.1.2/dh_gencontrol debhelper-8.1.2+nmu1/dh_gencontrol
--- debhelper-8.1.2/dh_gencontrol	2011-02-08 19:25:35.000000000 +0000
+++ debhelper-8.1.2+nmu1/dh_gencontrol	2011-03-25 20:50:18.000000000 +0000
@@ -66,11 +66,64 @@
 	
 	# Generate and install control file.
 	my @command="dpkg-gencontrol";
-	if (getpackages() > 1) {
-		push @command, "-p$package";
+	push @command, "-p$package";
+	push @command, "-l$changelog";
+	push @command, "-P$tmp";
+	push @command, "-T$substvars";
+
+	if (is_ddeb($package)) {
+		push @command, "-n".ddeb_filename();
+	}
+
+	if (is_ddeb($package) && ! ddeb_in_control($package)) {
+		next if ddeb_is_empty();
+
+		# If the ddeb appears in the control file, we let the
+		# packager override our defaults there.
+		my $arch=package_arch($package);
+		my $srcpackage=sourcepackage();
+
+		my $depends="";
+		foreach my $pkg (getpackages("same")) {
+			if ($pkg ne $package) {
+				addsubstvar($package,"ddeb:Conflicts","$pkg","<< \${binary:Version}");
+				addsubstvar($package,"ddeb:Conflicts","$pkg",">> \${binary:Version}");
+				$depends="$depends | $pkg (= \${binary:Version})";
+			}
+		}
+		$depends=~s/^ \| //;
+		addsubstvar($package,"ddeb:Depends","$depends","");
+
+		my $description="\"debug package for $srcpackage
+ This package contains debugging symbols for the binary packages
+ generated from the $srcpackage package.\"";
+
+		push @command, "-c-"; # Input from stdin
+		push @command, "-DArchitecture=$arch";
+		push @command, "-DSection=debug";
+		push @command, "-DPriority=extra";
+		push @command, "-DDepends=\\\${ddeb:Depends}";
+		push @command, "-DRecommends=\\\${ddeb:Recommends}";
+		push @command, "-DSuggests=\\\${ddeb:Suggests}";
+		push @command, "-DReplaces=\\\${ddeb:Replaces}";
+		push @command, "-DConflicts=\\\${ddeb:Conflicts}";
+		push @command, "-DProvides=\\\${ddeb:Provides}";
+		push @command, "-DDescription=$description";
+
+		# FIXME: get rid of this stdin hack when #535355 is fixed
+		my $homepage="Homepage: $dh{HOMEPAGE}" if defined $dh{HOMEPAGE};
+		my $control=
+"Source: $srcpackage
+Maintainer: $dh{MAINTAINER}
+$homepage
+
+Package: $package";
+
+		complex_doit("printf \"$control\" | ", @command, @{$dh{U_PARAMS}});
+	}
+	else {
+		doit(@command, @{$dh{U_PARAMS}});
 	}
-	doit(@command, "-l$changelog", "-T$substvars", 
-		"-P$tmp",@{$dh{U_PARAMS}});
 
 	# This chmod is only necessary if the user sets the umask to
 	# something odd.
diff -Nru debhelper-8.1.2/dh_strip debhelper-8.1.2+nmu1/dh_strip
--- debhelper-8.1.2/dh_strip	2011-02-08 19:32:07.000000000 +0000
+++ debhelper-8.1.2+nmu1/dh_strip	2011-03-25 20:50:18.000000000 +0000
@@ -161,7 +161,23 @@
 	return unless get_file_type($file) =~ /not stripped/;
 
 	my ($base_file)=$file=~/^\Q$tmp\E(.*)/;
-	my $debug_path=$desttmp."/usr/lib/debug/".$base_file;
+	my $debug_path;
+
+	my $build_id=`pbuildid $file 2>/dev/null | cut -d' ' -f2`;
+	chomp $build_id;
+	if ($desttmp =~ /-ddeb$/) {
+		if ($build_id) {
+			$build_id=~s/^(..)/$1\//;
+			$debug_path=$desttmp."/usr/lib/debug/.build-id/".$build_id.".debug";
+		}
+		else {
+			return;
+		}
+	}
+	else {
+		$debug_path=$desttmp."/usr/lib/debug/".$base_file;
+	}
+
 	my $debug_dir=dirname($debug_path);
 	if (! -d $debug_dir) {
 		doit("install", "-d", $debug_dir);
@@ -195,6 +211,11 @@
 			}
 			$debugtmp=tmpdir($debugpackage);
 		}
+		else {
+			# No --dbg-package specified, create a ddeb package
+			$keep_debug=1;
+			$debugtmp="debian/".ddebpackage();
+		}
 	}
 	else {
 		if (ref $dh{DEBUGPACKAGES} && grep { $_ eq $package } @{$dh{DEBUGPACKAGES}}) {
@@ -212,14 +233,14 @@
 		# *must* inclde the --strip-unneeded.
 		doit($strip,"--remove-section=.comment",
 			"--remove-section=.note","--strip-unneeded",$_);
-		attach_debug($_, $debug_path) if defined $debug_path;
+		attach_debug($_, $debug_path) if defined $debug_path and ! $debugtmp=~/-ddeb$/;
 	}
 	
 	foreach (@executables) {
 		my $debug_path = make_debug($_, $tmp, $debugtmp) if $keep_debug;
 		doit($strip,"--remove-section=.comment",
 			"--remove-section=.note",$_);
- 		attach_debug($_, $debug_path) if defined $debug_path;
+		attach_debug($_, $debug_path) if defined $debug_path and ! $debugtmp=~/-ddeb$/;
 	}
 
 	foreach (@static_libs) {

Reply to: