]> git.donarmstrong.com Git - debhelper.git/blob - Debian/Debhelper/Dh_Buildsystems.pm
Modular object-orientied buildsystem implementation (try 2).
[debhelper.git] / Debian / Debhelper / Dh_Buildsystems.pm
1 # A module for loading and managing debhelper buildsystem plugins.
2 # This module is intended to be used by all dh_auto_* helper commands.
3 #
4 # Copyright: © 2009 Modestas Vainius
5 # License: GPL-2+
6
7 package Debian::Debhelper::Dh_Buildsystems;
8
9 use strict;
10 use warnings;
11 use Debian::Debhelper::Dh_Lib;
12
13 use base 'Exporter';
14 our @EXPORT=qw(&buildsystems_init &buildsystems_do &load_buildsystem);
15
16 # XXX JEH as noted, this has to match historical order for back-compat
17 # XXX MDX Current dh_auto_* look like:
18 # configure: autotools, perl_makemaker, perl_build
19 # build:     makefile, python_distutils, perl_build
20 # test:      makefile, perl_build
21 # install:   makefile (with perl_makermaker) hack, python_distutils, perl_build
22 # clean:     makefile, python_distutils, perl_build
23 # So historical @BUILDSYSTEMS order (as per autodetection, see
24 # is_auto_buildable() of the respective classes):
25 #   autotools (+configure; the rest - next class)
26 #   python_distutils (+build +install +clean; the rest - next class)
27 #   perl_makemaker (+configure +install (special hack); the rest - next class)
28 #   makefile (+build +test +install +clean; configure - next class)
29 #   perl_build (handles everything)
30
31 # Historical order must be kept for backwards compatibility. New
32 # buildsystems MUST be added to the END of the list.
33 our @BUILDSYSTEMS = (
34     "autotools",
35     "python_distutils",
36     "perl_makemaker",
37     "makefile",
38     "perl_build",
39     "cmake",
40 );
41
42 sub create_buildsystem_instance {
43         my $system=shift;
44         my %bsopts=@_;
45         my $module = "Debian::Debhelper::Buildsystem::$system";
46
47         eval "use $module";
48         if ($@) {
49                 error("unable to load buildsystem class '$system': $@");
50         }
51
52         if (!exists $bsopts{builddir} && exists $dh{BUILDDIR}) {
53                 $bsopts{builddir} = $dh{BUILDDIR};
54         }
55         return $module->new(%bsopts);
56 }
57
58 sub load_buildsystem {
59         # XXX JEH the $system param is never passed
60         # by any call to this function
61         # XXX MDX Yes, it was sort of redudant. But see buildsystems_do() now.
62         my ($action, $system)=@_;
63         if (defined $system) {
64                 my $inst = create_buildsystem_instance($system);
65                 verbose_print("Selected buildsystem (specified): ".$inst->NAME());
66                 return $inst;
67         }
68         else {
69                 # Try to determine build system automatically
70                 for $system (@BUILDSYSTEMS) {
71                         my $inst = create_buildsystem_instance($system, is_auto=>1);
72                         if ($inst->is_auto_buildable($action)) {
73                                 verbose_print("Selected buildsystem (auto): ". $inst->NAME());
74                                 return $inst;
75                         }
76                 }
77         }
78         return;
79 }
80
81 sub list_buildsystems {
82         for my $system (@BUILDSYSTEMS) {
83                 my $inst = create_buildsystem_instance($system);
84                 printf("%s - %s.\n", $inst->NAME(), $inst->DESCRIPTION());
85         }
86 }
87
88 sub buildsystems_init {
89         my %args=@_;
90
91         # XXX JEH AFAICS, these 2 env variables are never used or documented
92         # XXX MDX They are used (see below), not documented though.
93         # TODO: Not documented in the manual pages yet.
94         # Initialize options from environment variables
95         if (exists $ENV{DH_AUTO_BUILDDIRECTORY}) {
96                 $dh{BUILDDIR} = $ENV{DH_AUTO_BUILDDIRECTORY};
97         }
98         if (exists $ENV{DH_AUTO_BUILDSYSTEM}) {
99                 $dh{BUILDSYS} = $ENV{DH_AUTO_BUILDSYSTEM};
100         }
101
102         # Available command line options
103         my $list_bs = sub { list_buildsystems(); exit 0 };
104         my $set_builddir = sub { $dh{BUILDDIR} = $_[1] };
105         my %options = (
106             "b:s" => $set_builddir,
107             "build-directory:s" => $set_builddir,
108             "builddirectory:s" => $set_builddir,
109
110             "m=s" => \$dh{BUILDSYS},
111             "build-system=s" => \$dh{BUILDSYS},
112             "buildsystem=s" => \$dh{BUILDSYS},
113
114             "l" => $list_bs,
115             "--list" => $list_bs,
116         );
117         map { $args{options}{$_} = $options{$_} } keys(%options);
118         Debian::Debhelper::Dh_Lib::init(%args);
119 }
120
121 sub buildsystems_do {
122         my $action=shift;
123
124         if (!defined $action) {
125                 $action = basename($0);
126                 $action =~ s/^dh_auto_//;
127         }
128
129         # XXX JEH does this if ever not fire?
130         # XXX MDX See dh_auto_install. I'm removing this anyway
131         # and making buildsystem_init() call in dh_auto_* mandatory.
132
133         if (grep(/^\Q$action\E$/, qw{configure build test install clean}) == 0) {
134                 error("unrecognized auto action: ".basename($0));
135         }
136
137         my $buildsystem = load_buildsystem($action, $dh{BUILDSYS});
138         if (defined $buildsystem) {
139                 $buildsystem->pre_action($action);
140                 $buildsystem->$action(@_, @{$dh{U_PARAMS}});
141                 $buildsystem->post_action($action);
142         }
143         return 0;
144 }
145
146 # XXX JEH generally, why does this need to be an OO object at all?
147 # The entire state stored in this object is o_dir and o_system;
148 # and the object is used as a singleton. So why not have a single sub
149 # that parses the command line, loads the specified system, and uses it,
150 # passing it the build directory. It would be both shorter and easier to
151 # understand.
152 # XXX I refactored this into a module rather than OO class. I do not agree
153 # about a single sub though as it is more complicated than that and
154 # I think it is more clear to have the code segmented a bit. See also
155 # dh_auto_install why both buildsystems_init() and buildsystems_do()
156 # are needed.
157
158 1;