e747945a40acc63025c5ff80609127b80d255509
[manu/RT-Extension-WatchedQueues.git] / inc / Module / Install / Makefile.pm
1 package Module::Install::Makefile;
2
3 use strict 'vars';
4 use Module::Install::Base;
5 use ExtUtils::MakeMaker ();
6
7 use vars qw{$VERSION $ISCORE @ISA};
8 BEGIN {
9         $VERSION = '0.72';
10         $ISCORE  = 1;
11         @ISA     = qw{Module::Install::Base};
12 }
13
14 sub Makefile { $_[0] }
15
16 my %seen = ();
17
18 sub prompt {
19         shift;
20
21         # Infinite loop protection
22         my @c = caller();
23         if ( ++$seen{"$c[1]|$c[2]|$_[0]"} > 3 ) {
24                 die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])";
25         }
26
27         # In automated testing, always use defaults
28         if ( $ENV{AUTOMATED_TESTING} and ! $ENV{PERL_MM_USE_DEFAULT} ) {
29                 local $ENV{PERL_MM_USE_DEFAULT} = 1;
30                 goto &ExtUtils::MakeMaker::prompt;
31         } else {
32                 goto &ExtUtils::MakeMaker::prompt;
33         }
34 }
35
36 sub makemaker_args {
37         my $self = shift;
38         my $args = ($self->{makemaker_args} ||= {});
39           %$args = ( %$args, @_ ) if @_;
40         $args;
41 }
42
43 # For mm args that take multiple space-seperated args,
44 # append an argument to the current list.
45 sub makemaker_append {
46         my $self = sShift;
47         my $name = shift;
48         my $args = $self->makemaker_args;
49         $args->{name} = defined $args->{$name}
50                 ? join( ' ', $args->{name}, @_ )
51                 : join( ' ', @_ );
52 }
53
54 sub build_subdirs {
55         my $self    = shift;
56         my $subdirs = $self->makemaker_args->{DIR} ||= [];
57         for my $subdir (@_) {
58                 push @$subdirs, $subdir;
59         }
60 }
61
62 sub clean_files {
63         my $self  = shift;
64         my $clean = $self->makemaker_args->{clean} ||= {};
65           %$clean = (
66                 %$clean, 
67                 FILES => join ' ', grep { length $_ } ($clean->{FILES} || (), @_),
68         );
69 }
70
71 sub realclean_files {
72         my $self      = shift;
73         my $realclean = $self->makemaker_args->{realclean} ||= {};
74           %$realclean = (
75                 %$realclean, 
76                 FILES => join ' ', grep { length $_ } ($realclean->{FILES} || (), @_),
77         );
78 }
79
80 sub libs {
81         my $self = shift;
82         my $libs = ref $_[0] ? shift : [ shift ];
83         $self->makemaker_args( LIBS => $libs );
84 }
85
86 sub inc {
87         my $self = shift;
88         $self->makemaker_args( INC => shift );
89 }
90
91 my %test_dir = ();
92
93 sub _wanted_t {
94         /\.t$/ and -f $_ and $test_dir{$File::Find::dir} = 1;
95 }
96
97 sub tests_recursive {
98         my $self = shift;
99         if ( $self->tests ) {
100                 die "tests_recursive will not work if tests are already defined";
101         }
102         my $dir = shift || 't';
103         unless ( -d $dir ) {
104                 die "tests_recursive dir '$dir' does not exist";
105         }
106         %test_dir = ();
107         require File::Find;
108         File::Find::find( \&_wanted_t, $dir );
109         $self->tests( join ' ', map { "$_/*.t" } sort keys %test_dir );
110 }
111
112 sub write {
113         my $self = shift;
114         die "&Makefile->write() takes no arguments\n" if @_;
115
116         # Make sure we have a new enough
117         require ExtUtils::MakeMaker;
118         $self->configure_requires( 'ExtUtils::MakeMaker' => $ExtUtils::MakeMaker::VERSION );
119
120         # Generate the 
121         my $args = $self->makemaker_args;
122         $args->{DISTNAME} = $self->name;
123         $args->{NAME}     = $self->module_name || $self->name;
124         $args->{VERSION}  = $self->version;
125         $args->{NAME}     =~ s/-/::/g;
126         if ( $self->tests ) {
127                 $args->{test} = { TESTS => $self->tests };
128         }
129         if ($] >= 5.005) {
130                 $args->{ABSTRACT} = $self->abstract;
131                 $args->{AUTHOR}   = $self->author;
132         }
133         if ( eval($ExtUtils::MakeMaker::VERSION) >= 6.10 ) {
134                 $args->{NO_META} = 1;
135         }
136         if ( eval($ExtUtils::MakeMaker::VERSION) > 6.17 and $self->sign ) {
137                 $args->{SIGN} = 1;
138         }
139         unless ( $self->is_admin ) {
140                 delete $args->{SIGN};
141         }
142
143         # merge both kinds of requires into prereq_pm
144         my $prereq = ($args->{PREREQ_PM} ||= {});
145         %$prereq = ( %$prereq,
146                 map { @$_ }
147                 map { @$_ }
148                 grep $_,
149                 ($self->configure_requires, $self->build_requires, $self->requires)
150         );
151
152         # Remove any reference to perl, PREREQ_PM doesn't support it
153         delete $args->{PREREQ_PM}->{perl};
154
155         # merge both kinds of requires into prereq_pm
156         my $subdirs = ($args->{DIR} ||= []);
157         if ($self->bundles) {
158                 foreach my $bundle (@{ $self->bundles }) {
159                         my ($file, $dir) = @$bundle;
160                         push @$subdirs, $dir if -d $dir;
161                         delete $prereq->{$file};
162                 }
163         }
164
165         if ( my $perl_version = $self->perl_version ) {
166                 eval "use $perl_version; 1"
167                         or die "ERROR: perl: Version $] is installed, "
168                         . "but we need version >= $perl_version";
169         }
170
171         $args->{INSTALLDIRS} = $self->installdirs;
172
173         my %args = map { ( $_ => $args->{$_} ) } grep {defined($args->{$_})} keys %$args;
174
175         my $user_preop = delete $args{dist}->{PREOP};
176         if (my $preop = $self->admin->preop($user_preop)) {
177                 $args{dist} = $preop;
178         }
179
180         my $mm = ExtUtils::MakeMaker::WriteMakefile(%args);
181         $self->fix_up_makefile($mm->{FIRST_MAKEFILE} || 'Makefile');
182 }
183
184 sub fix_up_makefile {
185         my $self          = shift;
186         my $makefile_name = shift;
187         my $top_class     = ref($self->_top) || '';
188         my $top_version   = $self->_top->VERSION || '';
189
190         my $preamble = $self->preamble 
191                 ? "# Preamble by $top_class $top_version\n"
192                         . $self->preamble
193                 : '';
194         my $postamble = "# Postamble by $top_class $top_version\n"
195                 . ($self->postamble || '');
196
197         local *MAKEFILE;
198         open MAKEFILE, "< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!";
199         my $makefile = do { local $/; <MAKEFILE> };
200         close MAKEFILE or die $!;
201
202         $makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /;
203         $makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g;
204         $makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g;
205         $makefile =~ s/^(FULLPERL = .*)/$1 "-Iinc"/m;
206         $makefile =~ s/^(PERL = .*)/$1 "-Iinc"/m;
207
208         # Module::Install will never be used to build the Core Perl
209         # Sometimes PERL_LIB and PERL_ARCHLIB get written anyway, which breaks
210         # PREFIX/PERL5LIB, and thus, install_share. Blank them if they exist
211         $makefile =~ s/^PERL_LIB = .+/PERL_LIB =/m;
212         #$makefile =~ s/^PERL_ARCHLIB = .+/PERL_ARCHLIB =/m;
213
214         # Perl 5.005 mentions PERL_LIB explicitly, so we have to remove that as well.
215         $makefile =~ s/(\"?)-I\$\(PERL_LIB\)\1//g;
216
217         # XXX - This is currently unused; not sure if it breaks other MM-users
218         # $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg;
219
220         open  MAKEFILE, "> $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!";
221         print MAKEFILE  "$preamble$makefile$postamble" or die $!;
222         close MAKEFILE  or die $!;
223
224         1;
225 }
226
227 sub preamble {
228         my ($self, $text) = @_;
229         $self->{preamble} = $text . $self->{preamble} if defined $text;
230         $self->{preamble};
231 }
232
233 sub postamble {
234         my ($self, $text) = @_;
235         $self->{postamble} ||= $self->admin->postamble;
236         $self->{postamble} .= $text if defined $text;
237         $self->{postamble}
238 }
239
240 1;
241
242 __END__
243
244 =pod
245
246 =head1 NAME
247
248 Module::Install::MakeMaker - Extension Rules for ExtUtils::MakeMaker
249
250 =head1 SYNOPSIS
251
252 In your F<Makefile.PL>:
253
254     use inc::Module::Install;
255     WriteMakefile();
256
257 =head1 DESCRIPTION
258
259 This module is a wrapper around B<ExtUtils::MakeMaker>.  It exports
260 two functions: C<prompt> (an alias for C<ExtUtils::MakeMaker::prompt>)
261 and C<WriteMakefile>.
262
263 The C<WriteMakefile> function will pass on keyword/value pair functions
264 to C<ExtUtils::MakeMaker::WriteMakefile>. The required parameters
265 C<NAME> and C<VERSION> (or C<VERSION_FROM>) are not necessary if
266 it can find them unambiguously in your code.
267
268 =head1 CONFIGURATION OPTIONS
269
270 This module also adds some Configuration parameters of its own:
271
272 =head2 NAME
273
274 The NAME parameter is required by B<ExtUtils::MakeMaker>. If you have a
275 single module in your distribution, or if the module name indicated by
276 the current directory exists under F<lib/>, this module will use the
277 guessed package name as the default.
278
279 If this module can't find a default for C<NAME> it will ask you to specify
280 it manually.
281
282 =head2 VERSION
283
284 B<ExtUtils::MakeMaker> requires either the C<VERSION> or C<VERSION_FROM>
285 parameter.  If this module can guess the package's C<NAME>, it will attempt
286 to parse the C<VERSION> from it.
287
288 If this module can't find a default for C<VERSION> it will ask you to
289 specify it manually.
290
291 =head1 MAKE TARGETS
292
293 B<ExtUtils::MakeMaker> provides you with many useful C<make> targets. A
294 C<make> B<target> is the word you specify after C<make>, like C<test>
295 for C<make test>. Some of the more useful targets are:
296
297 =over 4
298
299 =item * all
300
301 This is the default target. When you type C<make> it is the same as
302 entering C<make all>. This target builds all of your code and stages it
303 in the C<blib> directory.
304
305 =item * test
306
307 Run your distribution's test suite.
308
309 =item * install
310
311 Copy the contents of the C<blib> directory into the appropriate
312 directories in your Perl installation.
313
314 =item * dist
315
316 Create a distribution tarball, ready for uploading to CPAN or sharing
317 with a friend.
318
319 =item * clean distclean purge
320
321 Remove the files created by C<perl Makefile.PL> and C<make>.
322
323 =item * help
324
325 Same as typing C<perldoc ExtUtils::MakeMaker>.
326
327 =back
328
329 This module modifies the behaviour of some of these targets, depending
330 on your requirements, and also adds the following targets to your Makefile:
331
332 =over 4
333
334 =item * cpurge
335
336 Just like purge, except that it also deletes the files originally added
337 by this module itself.
338
339 =item * chelp
340
341 Short cut for typing C<perldoc Module::Install>.
342
343 =item * distsign
344
345 Short cut for typing C<cpansign -s>, for B<Module::Signature> users to
346 sign the distribution before release.
347
348 =back
349
350 =head1 SEE ALSO
351
352 L<Module::Install>, L<CPAN::MakeMaker>, L<CPAN::MakeMaker::Philosophy>
353
354 =head1 AUTHORS
355
356 Audrey Tang E<lt>autrijus@autrijus.orgE<gt>
357
358 Based on original works by Brian Ingerson E<lt>INGY@cpan.orgE<gt>
359
360 =head1 COPYRIGHT
361
362 Copyright 2002, 2003, 2004 by
363 Audrey Tang E<lt>autrijus@autrijus.orgE<gt>,
364 Brian Ingerson E<lt>ingy@cpan.orgE<gt>
365
366 This program is free software; you can redistribute it and/or modify it
367 under the same terms as Perl itself.
368
369 See L<http://www.perl.com/perl/misc/Artistic.html>
370
371 =cut