]> git.donarmstrong.com Git - debhelper.git/blob - Debian/Debhelper/Dh_Buildsystems.pm
Rename {pre,post}_step to {pre,post}_building_step.
[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 use File::Spec;
13
14 use base 'Exporter';
15 our @EXPORT=qw(&buildsystems_init &buildsystems_do &load_buildsystem &load_all_buildsystems);
16
17 # Historical order must be kept for backwards compatibility. New
18 # buildsystems MUST be added to the END of the list.
19 our @BUILDSYSTEMS = (
20     "autoconf",
21     "perl_makemaker",
22     "makefile",
23     "python_distutils",
24     "perl_build",
25     "cmake",
26 );
27
28 my $opt_buildsys;
29 my $opt_sourcedir;
30 my $opt_builddir;
31 my $opt_list;
32
33 sub create_buildsystem_instance {
34         my $system=shift;
35         my %bsopts=@_;
36         my $module = "Debian::Debhelper::Buildsystem::$system";
37
38         eval "use $module";
39         if ($@) {
40                 error("unable to load buildsystem class '$system': $@");
41         }
42
43         if (!exists $bsopts{builddir} && defined $opt_builddir) {
44                 $bsopts{builddir} = ($opt_builddir eq "") ? undef : $opt_builddir;
45         }
46         if (!exists $bsopts{sourcedir} && defined $opt_sourcedir) {
47                 $bsopts{sourcedir} = ($opt_sourcedir eq "") ? undef : $opt_sourcedir;
48         }
49         return $module->new(%bsopts);
50 }
51
52 sub load_buildsystem {
53         my ($step, $system)=@_;
54         if (defined $system) {
55                 my $inst = create_buildsystem_instance($system);
56                 return $inst;
57         }
58         else {
59                 # Try to determine build system automatically
60                 for $system (@BUILDSYSTEMS) {
61                         my $inst = create_buildsystem_instance($system, build_step=>$step);
62                         if ($inst->is_buildable()) {
63                                 return $inst;
64                         }
65                 }
66         }
67         return;
68 }
69
70 sub load_all_buildsystems {
71         my $incs=shift || \@INC;
72         my (%buildsystems, @buildsystems);
73
74         for my $inc (@$incs) {
75                 my $path = File::Spec->catdir($inc, "Debian/Debhelper/Buildsystem");
76                 if (-d $path) {
77                         for my $module_path (glob "$path/*.pm") {
78                                 my $name = basename($module_path);
79                                 $name =~ s/\.pm$//;
80                                 next if exists $buildsystems{$name};
81                                 $buildsystems{$name} = create_buildsystem_instance($name, @_);
82                         }
83                 }
84         }
85
86         # Push debhelper built-in buildsystems first
87         for my $name (@BUILDSYSTEMS) {
88                 error("Debhelper built-in buildsystem '$name' could not be found/loaded")
89                     if not exists $buildsystems{$name};
90                 push @buildsystems, $buildsystems{$name};
91                 delete $buildsystems{$name};
92         }
93
94         # The rest are 3rd party buildsystems
95         for my $name (keys %buildsystems) {
96                 my $inst = $buildsystems{$name};
97                 $inst->{thirdparty} = 1;
98                 push @buildsystems, $inst;
99         }
100
101         return @buildsystems;
102 }
103
104 sub buildsystems_init {
105         my %args=@_;
106
107         # Available command line options
108         my %options = (
109             "d" => undef, # cancel default D_FLAG option spec
110             "d=s" => \$opt_sourcedir,
111             "sourcedirectory=s" => \$opt_sourcedir,
112         
113             "b:s" => \$opt_builddir,
114             "builddirectory:s" => \$opt_builddir,
115
116             "c=s" => \$opt_buildsys,
117             "buildsystem=s" => \$opt_buildsys,
118
119             "l" => \$opt_list,
120             "--list" => \$opt_list,
121         );
122         $args{options}{$_} = $options{$_} foreach keys(%options);
123
124         # Pass options from the DH_AUTO_OPTIONS environment variable
125         if (defined $ENV{DH_AUTO_OPTIONS}) {
126                 $args{extra_args} = $ENV{DH_AUTO_OPTIONS};
127         }
128         Debian::Debhelper::Dh_Lib::init(%args);
129 }
130
131 sub buildsystems_list {
132         my $step=shift;
133
134         # List buildsystems (including auto and specified status)
135         my ($auto, $specified);
136         my @buildsystems = load_all_buildsystems(undef, build_step => undef);
137         for my $inst (@buildsystems) {
138                 my $is_specified = defined $opt_buildsys && $opt_buildsys eq $inst->NAME();
139                 if (! defined $specified && defined $opt_buildsys && $opt_buildsys eq $inst->NAME()) {
140                         $specified = $inst->NAME();
141                 }
142                 elsif (! defined $auto && ! $inst->{thirdparty} && $inst->check_auto_buildable($step)) {
143                         $auto = $inst->NAME();
144                 }
145                 printf("%s - %s", $inst->NAME(), $inst->DESCRIPTION());
146                 print " [3rd party]" if $inst->{thirdparty};
147                 print "\n";
148         }
149         print "\n";
150         print "Auto-selected: $auto\n" if defined $auto;
151         print "Specified: $specified\n" if defined $specified;
152         print "No system auto-selected or specified\n"
153                 if ! defined $auto && ! defined $specified;
154 }
155
156 sub buildsystems_do {
157         my $step=shift;
158
159         if (!defined $step) {
160                 $step = basename($0);
161                 $step =~ s/^dh_auto_//;
162         }
163
164         if (grep(/^\Q$step\E$/, qw{configure build test install clean}) == 0) {
165                 error("unrecognized build step: " . $step);
166         }
167
168         if ($opt_list) {
169                 buildsystems_list($step);
170                 exit 0;
171         }
172
173         my $buildsystem = load_buildsystem($step, $opt_buildsys);
174         if (defined $buildsystem) {
175                 $buildsystem->pre_building_step($step);
176                 $buildsystem->$step(@_, @{$dh{U_PARAMS}});
177                 $buildsystem->post_building_step($step);
178         }
179         return 0;
180 }
181
182 1;