summaryrefslogtreecommitdiff
path: root/Debian/Debhelper/Buildsystem/makefile.pm
blob: 32ad517889b1151d7e68f436c00e1c9a12bb2b51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# A debhelper build system class for handling simple Makefile based projects.
#
# Copyright: © 2008 Joey Hess
#            © 2008-2009 Modestas Vainius
# License: GPL-2+

package Debian::Debhelper::Buildsystem::makefile;

=head1 NAME

B<makefile> - make (Makefile)

=head1 SYNOPSIS

B<dh_auto_*> [B<--buildsystem>=I<makefile>] ...

=head1 DESCRIPTION

Makefile based projects use C<make> to control build process. C<make> utility
is the most popular tool on *NIX for building & installing packages from
source. It is also a basis for most other popular build systems. For example,
GNU Autoconf (autoconf) or CMake (cmake) generate F<Makefile>s during I<configure>
step and leave the rest of build process for C<make> to handle.

=head1 DH_AUTO NOTES

Since C<make> itself does not strictly define standard target names, a couple
of the most popular targets are tried for each building step. Whichever first
of them is discovered to exist, it is run. If neither of the tried targets
exist in the actual, the building step is assumed to have completed
successfully. However, if executed C<make> target fails, the respective dh_auto
program will fail too.

If MAKE environment variable is set, its value is executed rather than default
C<make> command.

Both in source (default) and out of source tree building modes are supported.
Either F<Makefile>, F<makefile> or F<GNUmakefile> file should be present in the
build directory for this debhelper build system to work.

=head1 BUILD PROCESS

=head2 Configure step

=over 4

=item I<Behaviour>

Do nothing (auto-selection continues).

=item I<Auto-selection>

It will never be auto-selected at this step.

=back

=cut

use strict;
use Debian::Debhelper::Dh_Lib qw(escape_shell);
use base 'Debian::Debhelper::Buildsystem';

sub get_makecmd_C {
	my $this=shift;
	my $buildpath = $this->get_buildpath();
	if ($buildpath ne '.') {
		return $this->{makecmd} . " -C " . escape_shell($buildpath);
	}
	return $this->{makecmd};
}

sub exists_make_target {
	my ($this, $target) = @_;
	my $makecmd=$this->get_makecmd_C();

	# Use make -n to check to see if the target would do
	# anything. There's no good way to test if a target exists.
	my $ret=`$makecmd -s -n --no-print-directory $target 2>/dev/null`;
	chomp $ret;
	return length($ret);
}

sub make_first_existing_target {
	my $this=shift;
	my $targets=shift;

	foreach my $target (@$targets) {
		if ($this->exists_make_target($target)) {
			$this->doit_in_builddir($this->{makecmd}, $target, @_);
			return $target;
		}
	}
	return undef;
}

sub DESCRIPTION {
	"simple Makefile"
}

sub new {
	my $class=shift;
	my $this=$class->SUPER::new(@_);
	$this->{makecmd} = (exists $ENV{MAKE}) ? $ENV{MAKE} : "make";
	return $this;
}

sub check_auto_buildable {
	my $this=shift;
	my ($step) = @_;

	# Handles build, test, install, clean; configure - next class
	if (grep /^\Q$step\E$/, qw{build test install clean}) {
		# This is always called in the source directory, but generally
		# Makefiles are created (or live) in the the build directory.
		return -e $this->get_buildpath("Makefile") ||
		       -e $this->get_buildpath("makefile") ||
		       -e $this->get_buildpath("GNUmakefile");
	}
	return 0;
}

=head2 Build step

=over 4

=item I<Behaviour>

Execute C<make> (without arguments) with working directory changed to the build
directory.

=item I<Auto-selection>

If either F<Makefile>, F<makefile> or F<GNUmakefile> exists in the build
directory, but F<Makefile.PL> does not exist in the source directory.

=back

=cut
sub build {
	my $this=shift;
	$this->doit_in_builddir($this->{makecmd}, @_);
}

=head2 Test step

=over 4

=item I<Behaviour>

Try to C<make> either I<test> or I<check> target (the first existing one) with
working directory changed to the build directory.

=item I<Auto-selection>

If either F<Makefile>, F<makefile> or F<GNUmakefile> exists in the build
directory, but F<Makefile.PL> does not exist in the source directory.

=back

=cut
sub test {
	my $this=shift;
	$this->make_first_existing_target(['test', 'check'], @_);
}

=head2 Install step

=over 4

=item I<Behaviour>

Try to run C<make install DESTDIR=$destdir> with working directory changed to
the build directory. $desdir is the path to the appropriate temporary
installation directory under debian/ (see L<dh_auto_install(1)>).

=item I<Auto-selection>

If either F<Makefile>, F<makefile> or F<GNUmakefile> exists in the build
directory, but F<Makefile.PL> does not exist in the source directory.

=back

=cut
sub install {
	my $this=shift;
	my $destdir=shift;
	$this->make_first_existing_target(['install'], "DESTDIR=$destdir", @_);
}

=head2 Clean step

=over 4

=item I<Behaviour>

When building in source, try to C<make> either I<distclean>, I<realclean> or
I<clean> target (the first existing one) in the source directory. When building
out of source tree, recursively remove the whole build directory.

=item I<Auto-selection>

If either F<Makefile>, F<makefile> or F<GNUmakefile> exists in the build
directory, but F<Makefile.PL> does not exist in the source directory.

=back

=cut
sub clean {
	my $this=shift;
	if (!$this->rmdir_builddir()) {
		$this->make_first_existing_target(['distclean', 'realclean', 'clean'], @_);
	}
}

=head1 SEE ALSO

L<dh_auto(7)>

=head1 AUTHORS

 Joey Hess <joeyh@debian.org>
 Modestas Vainius <modestas@vainius.eu>

=cut

1;