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