1 # A module for loading and managing debhelper buildsystem plugins.
3 # Copyright: © 2009 Modestas Vainius
6 package Debian::Debhelper::Dh_Buildsystems;
10 use Debian::Debhelper::Dh_Lib;
12 use Exporter qw( import );
13 our @EXPORT_OK = qw( DEFAULT_BUILD_DIRECTORY );
15 # IMPORTANT: more specific buildsystems should go first
16 # XXX JEH as noted, this has to match historical order for back-compat
26 sub DEFAULT_BUILD_DIRECTORY {
27 return "obj-" . dpkg_architecture_value("DEB_BUILD_GNU_TYPE");
36 'loaded_buildsystems' => [] }, $cls);
38 # XXX JEH AFAICS, these 2 env variables are never used or documented
39 if (!exists $opts{noenv}) {
40 if (exists $ENV{DH_AUTO_BUILDDIRECTORY}) {
41 $self->_set_build_directory_option("env", $ENV{DH_AUTO_BUILDDIRECTORY});
43 if (exists $ENV{DH_AUTO_BUILDSYSTEM}) {
44 $self->{o_system} = $ENV{DH_AUTO_BUILDSYSTEM};
54 my $set_dir = sub { $self->_set_build_directory_option(@_) };
55 my $list_bs = sub { $self->list_buildsystems(@_); exit 0 };
59 "build-directory:s" => $set_dir,
60 "builddirectory:s" => $set_dir,
62 "m=s" => \$self->{o_system},
63 "build-system=s" => \$self->{o_system},
64 "buildsystem=s" => \$self->{o_system},
69 my %options = @options;
73 sub _set_build_directory_option {
74 # XXX JEH option argument is not used, would be less confusing to
75 # not pass extra getopt value in
76 my ($self, $option, $value) = @_;
77 if (!$value || $value eq "auto") {
78 # Autogenerate build directory name
79 $self->{o_dir} = DEFAULT_BUILD_DIRECTORY;
82 $self->{o_dir} = $value;
86 # XXX JEH this sub is not used
89 for my $opt (qw(o_dir o_system)) {
90 if (defined $self->{$opt}) {
91 print $opt, ": ", $self->{$opt}, "\n";
96 sub _get_buildsystem_module {
97 my ($self, $system) = @_;
98 my $module = "Debian::Debhelper::Buildsystem::$system";
100 if (grep $module, @{$self->{loaded_buildsystems}} == 0) {
103 error("Unable to load buildsystem '$system': $@");
105 push @{$self->{loaded_buildsystems}}, $module;
110 sub load_buildsystem {
111 # XXX JEH the $system param is never passed
112 # by any call to this function
113 my ($self, $action, $system) = @_;
115 if (!defined $system) {
116 $system = $self->{o_system};
118 if (defined $system) {
119 my $module = $self->_get_buildsystem_module($system);
120 verbose_print("Selected buildsystem (specified): ".$module->NAME());
121 return $module->new($self->{o_dir});
124 # Try to determine build system automatically
125 for $system (@BUILDSYSTEMS) {
126 my $module = $self->_get_buildsystem_module($system);
127 my $inst = $module->new($self->{o_dir});
128 if ($inst->is_buildable($action)) {
129 verbose_print("Selected buildsystem (auto): ".$module->NAME());
137 sub load_all_buildsystems {
139 for my $system (@BUILDSYSTEMS) {
140 $self->_get_buildsystem_module($system);
142 return @{$self->{loaded_buildsystems}};
145 sub list_buildsystems {
147 for my $system ($self->load_all_buildsystems()) {
148 printf("%s - %s.\n", $system->NAME(), $system->DESCRIPTION());
152 sub init_dh_auto_tool {
155 Debian::Debhelper::Dh_Lib::init(
156 options => $self->get_options(@_));
157 $self->{initialized}=1;
160 sub run_dh_auto_tool {
162 my $toolname = basename($0);
165 # XXX JEH does this if ever not fire?
166 if (!exists $self->{initialized}) {
167 $self->init_dh_auto_tool();
170 # Guess action from the dh_auto_* name
171 $toolname =~ s/^dh_auto_//;
172 if (grep(/^\Q$toolname\E$/, qw{configure build test install clean}) == 0) {
173 error("Unrecognized dh auto tool: ".basename($0));
176 $buildsystem = $self->load_buildsystem($toolname);
177 if (defined $buildsystem) {
178 return $buildsystem->$toolname(@_, @{$dh{U_PARAMS}});
183 # XXX JEH generally, why does this need to be an OO object at all?
184 # The entire state stored in this object is o_dir and o_system;
185 # and the object is used as a singleton. So why not have a single sub
186 # that parses the command line, loads the specified system, and uses it,
187 # passing it the build directory. It would be both shorter and easier to