[SCM] Debian Qt/KDE packaging tools branch, dhmk, updated. debian/0.9.5-2-gf9467fc

Modestas Vainius modax at alioth.debian.org
Mon Mar 7 00:12:56 UTC 2011


The following commit has been merged in the dhmk branch:
commit f9467fc05aa4f1f2e1f7a3c8b93d9461b67bded3
Author: Modestas Vainius <modestas at vainius.eu>
Date:   Mon Mar 7 01:59:12 2011 +0200

    The 2nd incarnation of dhmk.
    
    Read qt-kde-team/2/README for full description of its features. Some features
    are not implemented yet (marked as TODO in the README). What's more, all
    current snippets in qt-kde-team/1/ need porting to dhmk (as make snippets or dh
    addons).
    
    This version of dhmk is not well tested but proof of concept should be there.
    Unlike previous version of dhmk, this version no longer supports
    {target}_override_{dh_command} overrides.
---
 qt-kde-team/2/README                    |   65 +++++++++++++
 qt-kde-team/2/{commands.mk => commands} |   34 ++++----
 qt-kde-team/2/dhmk.mk                   |  114 +++++++++++------------
 qt-kde-team/2/dhmk.pl                   |  151 +++++++++++++++++++++++++++++++
 4 files changed, 289 insertions(+), 75 deletions(-)

diff --git a/qt-kde-team/2/README b/qt-kde-team/2/README
new file mode 100644
index 0000000..b878466
--- /dev/null
+++ b/qt-kde-team/2/README
@@ -0,0 +1,65 @@
+What is dhmk?
+-------------
+
+dhmk is yet another debhelper command sequencer. Unlike dh(1), it uses make(1)
+to execute all commands. The perl part (dhmk.pl) is used to support dh(1)
+addons and dynamically calculate override_* targets.
+
+dhmk aims to mimic the most useful features of dh(1) adding a couple of its
+own. Some highlights include:
+
+1) Unlike dh(1), dhmk sequencer is based on the traditional debian/rules
+layout. It means that progress tracking revolves around standard
+targets/actions (configure, build, install, binary etc.) rather than on
+per-(command+package) basis (i.e. debian/*.debhelper.log files) basis.
+"per-(command+package)" tracking gets complicated giving not too much real
+benefit, but makes it hard to fix bugs like #510855.
+
+2) Like dh(1), dhmk supports override_{dh_command} targets.
+
+3) dhmk should support most of dh(1) addons (TODO).
+
+4) Like dh(1), dhmk supports passing of additional options to all dh_commands (TODO).
+
+5) In addition to dh(1) addons, dhmk is extendable with makefile snippets as well.
+
+Altering default dhmk action sequences
+--------------------------------------
+
+1) If override_{dh_command} target exists in debian/rules, it will be executed
+instead of the default dh_command command whenever the latter appears in the
+action sequence (as dh(1) would do).
+
+2) In order to override the whole action (configure, build, install etc.), just
+create a respective custom make target manually. The dhmk sequence is still
+accessible via debian/dhmk_{action} target.
+
+3) In order to enable a dh(1) addon, append --with=addon (or --with addon) to
+the "dh" variable *before* including dhmk.mk (TODO).
+
+4) In order to pass additional options to all dh_commands (dh(1) way), append
+them to "dh" variable (preferably after --) *before* including dhmk.mk (TODO).
+The command line interface is compatible with dh compat level 7 or higher.
+
+Extending dhmk with makefile snippets (templating recommendations)
+------------------------------------------------------------------
+
+dhmk sequences can be extented by include'ing additional makefile snippets in
+debian/rules.
+
+1) Snippets may hook to the dhmk_pre_{action}_{dh_command} target in order to
+do additional work *before* dh_command runs at the specific action.
+
+2) Snippets may hook to the dhmk_pre_{action}_{dh_command} target in order to
+do additional work *after* dh_command runs at the specific action.
+
+3) Snippets may hook to the dhmk_pre_{action} target in order to do additional
+work at the beginning of the specific action sequence.
+
+4) Snippets may hook to the dhmk_post_{action} target in order to do additional
+work at the end of the specific action sequence.
+
+5) Snippets may alter the contents of the "{target}_{dh_command}" variable in
+order to change command line (including the command itself) of the specified
+dh_command whenever it runs during the specified action. Snippets should
+preferably NOT use override_{dh_command} targets.
diff --git a/qt-kde-team/2/commands.mk b/qt-kde-team/2/commands
similarity index 70%
rename from qt-kde-team/2/commands.mk
rename to qt-kde-team/2/commands
index 738332a..38760f9 100644
--- a/qt-kde-team/2/commands.mk
+++ b/qt-kde-team/2/commands
@@ -1,21 +1,27 @@
-define configure_commands
+# Standard target commands are defined here.
+# File format is:
+# target:
+# 	command1
+# 	command2
+# 	command3
+# 	...
+# Use $targetname in place of a command to insert commands from the previously
+# defined target.
+configure:
 	dh_testdir
 	dh_auto_configure
-endef
 
-define build_commands
+build:
 	dh_testdir
 	dh_auto_build
 	dh_auto_test
-endef
 
-define clean_commands
+clean:
 	dh_testdir
 	dh_auto_clean
 	dh_clean
-endef
 
-define install_commands
+install:
 	dh_testroot
 	dh_prep
 	dh_installdirs
@@ -54,22 +60,18 @@ define install_commands
 	dh_link
 	dh_compress
 	dh_fixperms
-endef
 
-define binary-indep_commands
+binary-indep:
 	dh_installdeb
 	dh_gencontrol
 	dh_md5sums
 	dh_builddeb
-endef
 
-define binary-arch_commands
+binary-arch:
 	dh_strip
 	dh_makeshlibs
 	dh_shlibdeps
-    $(binary-indep_commands)
-endef
+	$binary-indep
 
-define binary_commands
-    $(binary-arch_commands)
-endef
+binary:
+	$binary-arch
diff --git a/qt-kde-team/2/dhmk.mk b/qt-kde-team/2/dhmk.mk
index 36acb19..727ee38 100644
--- a/qt-kde-team/2/dhmk.mk
+++ b/qt-kde-team/2/dhmk.mk
@@ -13,86 +13,82 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>
 
-# Load command sequences: $(target)_commands variables
-include $(dir $(lastword $(MAKEFILE_LIST)))/commands.mk
-
-dhmk_top_makefile = $(firstword $(MAKEFILE_LIST))
+dhmk_top_makefile := $(firstword $(MAKEFILE_LIST))
+dhmk_this_makefile := $(lastword $(MAKEFILE_LIST))
 dhmk_stamped_targets = configure build
 dhmk_dynamic_targets = install binary-indep binary-arch binary clean
 dhmk_standard_targets = $(dhmk_stamped_targets) $(dhmk_dynamic_targets)
-dhmk_all_commands = $(strip $(foreach t,$(standard_targets),$($(t)_commands)))
-
-dhmk_overrides_mk = debian/dhmk_command_overrides.mk
-dhmk_calc_overrides_magic = \#\#dhmk_calc_overrides\#\#
+dhmk_rules_mk = debian/dhmk_rules.mk
 
-ifeq ($(dhmk_calc_overrides),yes)
+# $(call butfirstword,TEXT,DELIMITER)
+butfirstword = $(patsubst $(firstword $(subst $2, ,$1))$2%,%,$1)
 
-# Handle override calculation
+# This makefile is not parallel compatible by design (e.g. command chains
+# below)
+.NOTPARALLEL:
 
-override_%: FORCE
-	$(dhmk_calc_overrides_magic) dhmk_$@ = no
-
-# NOTE: implicit targets do not work as expected when grouped together. The
-# following workaround is needed to generate a separate rule for each target.
-define dhmk_t_override_code
-$(eval $(t)_override_%: FORCE
-	$(CALC_OVERRIDES_MAGIC) dhmk_$$@ = no
-)
-endef
-$(foreach t,$(dhmk_standard_targets),$(dhmk_t_override))
-
-calc_overrides: $(foreach cmd,$(dhmk_all_commands),override_$(cmd))
-calc_overrides: $(foreach t,$(dhmk_standard_targets),\
-    $(foreach cmd,$(strip $($(t)_commands)),$(t)_override_$(cmd)))
-.PHONY: calc_overrides
-else
+# FORCE target is used in the prerequsite lists to imitiate .PHONY behaviour
+.PHONY: FORCE
 
-# Run override calculation and include a generated file
+############ Handle override calculation ############ 
+ifeq ($(dhmk_calc_overrides),yes)
 
-$(dhmk_overrides_mk): $(MAKEFILE_LIST)
-	$(MAKE) -f $(dhmk_top_makefile) -j1 -n --no-print-directory \
-        calc_overrides dhmk_calc_overrides=yes 2>&1 | \
-        sed -n '/^$(dhmk_calc_overrides_magic)[[:space:]]\+/ \
-        { s/^$(dhmk_calc_overrides_magic)[[:space:]]\+//; p }' > $@
+# Emit magic directives for commands which are not overriden
+override_%: FORCE
+	##dhmk_no_override##$*
 
--include $(dhmk_overrides_mk)
+else
+############ Do all sequencing ######################
 
-endif
+# Generate and include a dhmk rules file
+$(dhmk_rules_mk): $(MAKEFILE_LIST)
+	$(dir $(dhmk_this_makefile))dhmk.pl $(dhmk_rules_mk) $(dhmk_top_makefile)
 
-dhmk_get_override = $(if $(dhmk_$(1)),,$(MAKE) -f $(dhmk_top_makefile) $(1))
-# Empty line before endef is necessary
-define dhmk_run_command
-$(or $(call dhmk_get_override,$(1)_override_$(2)),\
-     $(call dhmk_get_override,override_$(2)),\
-     $(2)\
-)
+# Create an out-of-date rules file if it does not exist. Avoids make warning
+include $(shell test ! -f $(dhmk_rules_mk) && touch -t 197001030000 $(dhmk_rules_mk); echo $(dhmk_rules_mk))
 
-endef
+# Routine to run a specific command ($1 should be {target}_{command})
+dhmk_override_cmd = $(if $(dhmk_$1),$(MAKE) -f $(dhmk_top_makefile) $1)
+dhmk_run_command = $(or $(call dhmk_override_cmd,override_$(call butfirstword $1,_)),$($1))
 
-# Generate command chains for the standard targets
-$(foreach t,$(dhmk_standard_targets),debian/dhmk_$(t)): debian/dhmk_%:
-	$(foreach cmd,$(strip $($*_commands)),\
-		$(call dhmk_run_command,$*,$(cmd)) $(dhmk_target_dh_options))
-	$(if $(filter $*,$(dhmk_stamped_targets)),touch $@)
-	# "$*" is done
+# Generate dhmk_{pre,post}_{target}_{command} targets for each target+command
+$(foreach t,$(dhmk_standard_targets),$(foreach c,$(dhmk_$(t)_commands),dhmk_pre_$(t)_$(c))): dhmk_pre_%:
+	$(call dhmk_run_command,$*)
+$(foreach t,$(dhmk_standard_targets),$(foreach c,$(dhmk_$(t)_commands),dhmk_post_$(t)_$(c))): dhmk_post_%:
 
-# Mark dynamic targets as phony
-.PHONY: $(foreach t,$(dhmk_dynamic_targets),debian/dhmk_$(t))
-
-# Relationships between targets + common options
-# NOTE: do not use standard targets here directly, use their debian/dhmk_target
-# counterparts.
+# Relationships between targets + export common options (to submake)
 debian/dhmk_build: debian/dhmk_configure
 debian/dhmk_install: debian/dhmk_build
 debian/dhmk_binary: debian/dhmk_install
 debian/dhmk_binary-arch: debian/dhmk_install
-debian/dhmk_binary-arch: dhmk_target_dh_options = -a
+debian/dhmk_binary-arch: export dhmk_target_dh_options = -a
 debian/dhmk_binary-indep: debian/dhmk_install
-debian/dhmk_binary-indep: dhmk_target_dh_options = -i
+debian/dhmk_binary-indep: export dhmk_target_dh_options = -i
+
+# Mark dynamic standard targets as PHONY
+.PHONY: $(foreach t,$(dhmk_dynamic_targets),debian/dhmk_$(t))
+
+# Create debina/dhmk_{action} targets.
+# NOTE: dhmk_run_{target}_commands are defined below
+$(foreach t,$(dhmk_standard_targets),debian/dhmk_$(t)): debian/dhmk_%:
+	$(MAKE) -f $(dhmk_top_makefile) dhmk_run_$*_commands
+	$(if $(filter $*,$(dhmk_stamped_targets)),touch $@)
+	$(if $(filter clean,$*),rm -f $(dhmk_rules_mk))
+	# "$*" is complete
+
+.PHONY: $(foreach t,$(dhmk_standard_targets),dhmk_run_$(t)_commands \
+    dhmk_pre_$(t) dhmk_post_$(t) \
+    $(foreach c,$(dhmk_$(t)_commands),dhmk_pre_$(t)_$(c) dhmk_post_$(t)_$(c)))
 
 # Implicitly delegate other targets to debian/dhmk_% ones. Hence the top
 # targets (build, configure, install ...) are still cancellable.
 %: debian/dhmk_%
-	echo "$@ action has been successfully completed."
+	@echo "$@ action has been completed successfully."
+
+.SECONDEXPANSION:
+
+# Generate command chains for the standard targets
+$(foreach t,$(dhmk_standard_targets),dhmk_run_$(t)_commands): dhmk_run_%_commands: dhmk_pre_% $$(foreach c,$$(dhmk_%_commands),dhmk_pre_%_$$(c) dhmk_post_%_$$(c)) dhmk_post_%
+
+endif # ifeq (dhmk_calc_overrides,yes)
 
-.PHONY: FORCE
diff --git a/qt-kde-team/2/dhmk.pl b/qt-kde-team/2/dhmk.pl
new file mode 100755
index 0000000..7c4ea54
--- /dev/null
+++ b/qt-kde-team/2/dhmk.pl
@@ -0,0 +1,151 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2011 Modestas Vainius <modax at debian.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>
+
+use strict;
+use warnings;
+
+use File::Basename qw();
+use File::Spec;
+
+sub parse_commands_file {
+    my ($filename) = @_;
+    my %targets;
+    my $t;
+
+    open (my $fh, "<", $filename) or
+        die "unable to open dhmk commands file $filename: $!";
+
+    # File format is:
+    # target:
+    # 	command1
+    # 	command2
+    # 	command3
+    # 	...
+    # Use $targetname in place of a command to insert commands from the
+    # previously defined target.
+    while (my $line = <$fh>) {
+        chop $line;
+        if ($line =~ /^\s*#/ || $line =~ /^\s*$/) {
+            next; # comment or empty line
+        } elsif ($line =~ /^(\S.+):\s*$/) {
+            $t = $1;
+        } elsif (defined $t) {
+            if ($line =~ /^\s+(.*)$/) {
+                my $c = $1;
+                # If it's a variable, dereference it
+                if ($c =~ /^\s*\$(\S+)\s*$/) {
+                    if (exists $targets{$1}) {
+                        push @{$targets{$t}}, @{$targets{$1}};
+                    } else {
+                        die "could not dereference variable \$$1. Target '$1' was not defined yet";
+                    }
+                } else {
+                    push @{$targets{$t}}, $c;
+                }
+            } else {
+                die "dangling command '$line'. Missing target definition";
+            }
+        } else {
+            die "invalid commands file syntax";
+        }
+    }
+    close($fh);
+
+    return \%targets;
+}
+
+sub get_commands {
+    my ($targets) = @_;
+    my %commands;
+    foreach my $tname (keys %$targets) {
+        my $t = $targets->{$tname};
+        foreach my $c (@$t) {
+            if ($c =~ /^(\S+)/) {
+                push @{$commands{$1}}, $tname;
+            } else {
+                die "internal error: unrecognized command '$c'";
+            }
+        }
+    }
+    return \%commands;
+}
+
+sub calc_overrides {
+    my ($commands, $rules_file) = @_;
+    my $magic = "##dhmk_no_override##";
+
+    # Initialize all overrides first
+    my %overrides;
+    my @override_targets;
+    foreach my $c (@$commands) {
+        $overrides{$c} = 1;
+        push @override_targets, "override_$c";
+    }
+
+    # Now remove overrides based on the rules file output
+    open(my $make, "-|", "make", "-f", $rules_file, "-j1", "-n",
+        "--no-print-directory",
+        @override_targets,
+        "dhmk_calc_overrides=yes") or
+        die "unable to execute make for override calculation: $!";
+    while (my $line = <$make>) {
+        if ($line =~ /^$magic(.*)$/ && exists $overrides{$1}) {
+            delete $overrides{$1};
+        }
+    }
+    if (!close($make)) {
+        die "make (calc_override) failed with $?";
+    }
+
+    return \%overrides;
+}
+
+sub write_dhmk_rules {
+    my ($dhmk_file, $rules_file, $targets, $overrides) = @_;
+    open (my $fh, ">", $dhmk_file) or
+        die "unable to open dhmk rules file ($dhmk_file) for writing: $!";
+    print $fh "# Target command sequences", "\n";
+    foreach my $tname (keys %$targets) {
+        my $t = $targets->{$tname};
+        my @commands;
+        foreach my $cline (@$t) {
+            my $c = ($cline =~ /^(\S+)/) && $1;
+            push @commands, $c;
+            print $fh $tname, "_", $c, " = ", $cline, "\n";
+        }
+        print $fh "dhmk_". $tname, "_commands = ", join(" ", @commands), "\n\n";
+    }
+    print $fh "# Overrides", "\n";
+    foreach my $o (sort keys %$overrides) {
+        print $fh "dhmk_override_", $o, " = yes", "\n";
+    }
+    close($fh);
+}
+
+my $COMMANDS_FILE = File::Spec->catfile(File::Basename::dirname($0), "commands");
+my $DHMK_RULES_FILE = $ARGV[0] || "debian/dhmk_rules.mk";
+my $RULES_FILE = $ARGV[1] || "debian/rules";
+
+eval {
+    my $targets = parse_commands_file($COMMANDS_FILE);
+    my $commands = get_commands($targets);
+    my $overrides = calc_overrides([ keys %$commands ], $RULES_FILE);
+    write_dhmk_rules($DHMK_RULES_FILE, $RULES_FILE, $targets, $overrides);
+};
+if ($@) {
+    die "error: $@"
+}

-- 
Debian Qt/KDE packaging tools



More information about the pkg-kde-commits mailing list