Hello,

On penktadienis 11 Gruodis 2009 20:58:44 Joey Hess wrote:
> Modestas Vainius wrote:
> > If debhelper program has nothing to do, it will exit fast. Slow down
> > should be minimal.
> 
> There is some potential for speeding up dh. Josh Tripplet and I once
> discussed:
> 
> * Having dh optimize out calls to debhelper commands that will be
>   no-ops. For a subset of commands, this can be determined just
>   by looking for their config files. Some kind of metadata would be
>   necessary for dh to tell which commands are in that subset.
> 
> * Make dh run debhelper commands directly in one perl process, rather
>   than through exec. (However, I think this is unlikely to be worth the
>   insanity.)
> 
> * Writing a faster parser for simple command-line options. Benchmarks
>   show that parsing options is 50% of the overhead of running no-op
>   debhelper commands. This is because if there are options, it loads
>   Getopt::Long, which is slow. This overhead is particularly bad
>   when dh needs to pass -i / -a to all commands, which otherwise
>   would need no options.
> 
> * Removing calls to dpkg-architecture from dh_auto_configure and
>   dh_auto_build when they will not actually be configuring or building.
> 
> * Speed up dh_gencontrol, er, I mean dpkg-gencontrol, which by itself
>   is responsible for more than 1/3 of the total runtime of dh binary
>   in a package where the other debhelper commands are all no-ops.

* Detect noop (empty) override targets when parsing debian/rules and avoid 
make calls for them. Patch attached.

-- 
Modestas Vainius <modes...@vainius.eu>
From cbd509e6b6fe690c0c59df7f117b402be8c89bff Mon Sep 17 00:00:00 2001
From: Modestas Vainius <modes...@vainius.eu>
Date: Fri, 11 Dec 2009 23:10:01 +0200
Subject: [PATCH] Do not call make for noop overrides.

1) Detect if target is noop when parsing debian/rules.
2) If override target is noop, do not call make for it.
---
 dh |   79 +++++++++++++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 55 insertions(+), 24 deletions(-)

diff --git a/dh b/dh
index 11fb27b..f1b1b68 100755
--- a/dh
+++ b/dh
@@ -526,30 +526,44 @@ sub run {
 	# Check for override targets in debian/rules and
 	# run them instead of running the command directly.
 	my $override_command;
-	if (rules_explicit_target("override_".$command)) {
+	my $has_explicit_target = rules_explicit_target("override_".$command);
+	if (defined $has_explicit_target) {
 		$override_command=$command;
-		# This passes the options through to commands called
-		# inside the target.
-		$ENV{DH_INTERNAL_OPTIONS}=join("\x1e", @options);
-		$command="debian/rules";
-		@options="override_".$override_command;
+		# Check if target isn't noop
+		if ($has_explicit_target) {
+			# This passes the options through to commands called
+			# inside the target.
+			$ENV{DH_INTERNAL_OPTIONS}=join("\x1e", @options);
+			$command="debian/rules";
+			@options="override_".$override_command;
+		}
+		else {
+			$command = undef;
+		}
 	}
 	else {
 		# Pass additional command options if any
 		unshift @options, @{$command_opts{$command}} if exists $command_opts{$command};
 	}
 
-	# 3 space indent lines the command being run up under the 
-	# sequence name after "dh ".
-	print "   ".escape_shell($command, @options)."\n";
+	if (defined $command) {
+		# 3 space indent lines the command being run up under the 
+		# sequence name after "dh ".
+		print "   ".escape_shell($command, @options)."\n";
+	}
+	else {
+		print "   ", "# Skipping ", $override_command, " - empty override", "\n";
+	}
 
 	if (! $dh{NO_ACT}) {
-		my $ret=system($command, @options);
-		if ($ret >> 8 != 0) {
-			exit $ret >> 8;
-		}
-		elsif ($ret) {
-			exit 1;
+		if (defined $command) {
+			my $ret=system($command, @options);
+			if ($ret >> 8 != 0) {
+				exit $ret >> 8;
+			}
+			elsif ($ret) {
+				exit 1;
+			}
 		}
 
 		if (defined $override_command) {
@@ -575,11 +589,14 @@ my $rules_parsed;
 sub rules_explicit_target {
 	# Checks if a specified target exists as an explicit target
 	# in debian/rules. 
+	# undef is returned if target does not exist, 0 if target is noop
+	# and 1 if target has dependencies or executes commands.
 	my $target=shift;
-	
-	if (! $rules_parsed) {	
+
+	if (! $rules_parsed) {
 		my $processing_targets = 0;
 		my $not_a_target = 0;
+		my $current_target;
 		open(MAKE, "LC_ALL=C make -Rrnpsf debian/rules debhelper-fail-me 2>/dev/null |");
 		while (<MAKE>) {
 			if ($processing_targets) {
@@ -587,12 +604,26 @@ sub rules_explicit_target {
 					$not_a_target = 1;
 				}
 				else {
-					if (!$not_a_target && /^([^#:]+)::?/) {
-						# Target is defined.
-						# NOTE: if it is a depenency
-						# of .PHONY it will be
-						# defined too but that's ok.
-						$targets{$1} = 1;
+					if (!$not_a_target && /^([^#:]+)::?\s*(.*)$/) {
+						# Target is defined. NOTE: if it is a depenency of
+						# .PHONY it will be defined too but that's ok.
+						# $2 contains target dependencies if any.
+						$current_target = $1;
+						$targets{$current_target} = ($2) ? 1 : 0;
+					}
+					else {
+						if (defined $current_target) {
+							if (/^#/) {
+								# Check if target has commands to execute
+								if (/^#\s*commands to execute/) {
+									$targets{$current_target} = 1;
+								}
+							}
+							else {
+								# Target parsed.
+								$current_target = undef;
+							}
+						}
 					}
 					# "Not a target:" is always followed by
 					# a target name, so resetting this one
@@ -607,7 +638,7 @@ sub rules_explicit_target {
 		$rules_parsed = 1;
 	}
 
-	return exists $targets{$target};
+	return (exists $targets{$target}) ? $targets{$target} : undef;
 }
 
 }
-- 
1.6.5.4

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

Reply via email to