File Coverage

blib/lib/Module/Install/Makefile.pm
Criterion Covered Total %
statement 18 188 9.5
branch 0 92 0.0
condition 0 65 0.0
subroutine 6 23 26.0
pod 0 15 0.0
total 24 383 6.2


line stmt bran cond sub pod time code
1             package Module::Install::Makefile;
2              
3 1     1   852 use strict 'vars';
  1         1  
  1         29  
4 1     1   3 use ExtUtils::MakeMaker ();
  1         2  
  1         9  
5 1     1   3 use Module::Install::Base ();
  1         1  
  1         13  
6 1     1   3 use Fcntl qw/:flock :seek/;
  1         1  
  1         159  
7              
8 1     1   4 use vars qw{$VERSION @ISA $ISCORE};
  1         1  
  1         54  
9             BEGIN {
10 1     1   1 $VERSION = '1.18';
11 1         8 @ISA = 'Module::Install::Base';
12 1         1947 $ISCORE = 1;
13             }
14              
15 0     0 0   sub Makefile { $_[0] }
16              
17             my %seen = ();
18              
19             sub prompt {
20 0     0 0   shift;
21              
22             # Infinite loop protection
23 0           my @c = caller();
24 0 0         if ( ++$seen{"$c[1]|$c[2]|$_[0]"} > 3 ) {
25 0           die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])";
26             }
27              
28             # In automated testing or non-interactive session, always use defaults
29 0 0 0       if ( ($ENV{AUTOMATED_TESTING} or -! -t STDIN) and ! $ENV{PERL_MM_USE_DEFAULT} ) {
      0        
30 0           local $ENV{PERL_MM_USE_DEFAULT} = 1;
31 0           goto &ExtUtils::MakeMaker::prompt;
32             } else {
33 0           goto &ExtUtils::MakeMaker::prompt;
34             }
35             }
36              
37             # Store a cleaned up version of the MakeMaker version,
38             # since we need to behave differently in a variety of
39             # ways based on the MM version.
40             my $makemaker = eval $ExtUtils::MakeMaker::VERSION;
41              
42             # If we are passed a param, do a "newer than" comparison.
43             # Otherwise, just return the MakeMaker version.
44             sub makemaker {
45 0 0 0 0 0   ( @_ < 2 or $makemaker >= eval($_[1]) ) ? $makemaker : 0
46             }
47              
48             # Ripped from ExtUtils::MakeMaker 6.56, and slightly modified
49             # as we only need to know here whether the attribute is an array
50             # or a hash or something else (which may or may not be appendable).
51             my %makemaker_argtype = (
52             C => 'ARRAY',
53             CONFIG => 'ARRAY',
54             # CONFIGURE => 'CODE', # ignore
55             DIR => 'ARRAY',
56             DL_FUNCS => 'HASH',
57             DL_VARS => 'ARRAY',
58             EXCLUDE_EXT => 'ARRAY',
59             EXE_FILES => 'ARRAY',
60             FUNCLIST => 'ARRAY',
61             H => 'ARRAY',
62             IMPORTS => 'HASH',
63             INCLUDE_EXT => 'ARRAY',
64             LIBS => 'ARRAY', # ignore ''
65             MAN1PODS => 'HASH',
66             MAN3PODS => 'HASH',
67             META_ADD => 'HASH',
68             META_MERGE => 'HASH',
69             PL_FILES => 'HASH',
70             PM => 'HASH',
71             PMLIBDIRS => 'ARRAY',
72             PMLIBPARENTDIRS => 'ARRAY',
73             PREREQ_PM => 'HASH',
74             CONFIGURE_REQUIRES => 'HASH',
75             SKIP => 'ARRAY',
76             TYPEMAPS => 'ARRAY',
77             XS => 'HASH',
78             # VERSION => ['version',''], # ignore
79             # _KEEP_AFTER_FLUSH => '',
80              
81             clean => 'HASH',
82             depend => 'HASH',
83             dist => 'HASH',
84             dynamic_lib=> 'HASH',
85             linkext => 'HASH',
86             macro => 'HASH',
87             postamble => 'HASH',
88             realclean => 'HASH',
89             test => 'HASH',
90             tool_autosplit => 'HASH',
91              
92             # special cases where you can use makemaker_append
93             CCFLAGS => 'APPENDABLE',
94             DEFINE => 'APPENDABLE',
95             INC => 'APPENDABLE',
96             LDDLFLAGS => 'APPENDABLE',
97             LDFROM => 'APPENDABLE',
98             );
99              
100             sub makemaker_args {
101 0     0 0   my ($self, %new_args) = @_;
102 0   0       my $args = ( $self->{makemaker_args} ||= {} );
103 0           foreach my $key (keys %new_args) {
104 0 0         if ($makemaker_argtype{$key}) {
105 0 0         if ($makemaker_argtype{$key} eq 'ARRAY') {
    0          
    0          
106 0 0         $args->{$key} = [] unless defined $args->{$key};
107 0 0         unless (ref $args->{$key} eq 'ARRAY') {
108 0           $args->{$key} = [$args->{$key}]
109             }
110 0           push @{$args->{$key}},
111             ref $new_args{$key} eq 'ARRAY'
112 0           ? @{$new_args{$key}}
113 0 0         : $new_args{$key};
114             }
115             elsif ($makemaker_argtype{$key} eq 'HASH') {
116 0 0         $args->{$key} = {} unless defined $args->{$key};
117 0           foreach my $skey (keys %{ $new_args{$key} }) {
  0            
118 0           $args->{$key}{$skey} = $new_args{$key}{$skey};
119             }
120             }
121             elsif ($makemaker_argtype{$key} eq 'APPENDABLE') {
122 0           $self->makemaker_append($key => $new_args{$key});
123             }
124             }
125             else {
126 0 0         if (defined $args->{$key}) {
127 0           warn qq{MakeMaker attribute "$key" is overriden; use "makemaker_append" to append values\n};
128             }
129 0           $args->{$key} = $new_args{$key};
130             }
131             }
132 0           return $args;
133             }
134              
135             # For mm args that take multiple space-separated args,
136             # append an argument to the current list.
137             sub makemaker_append {
138 0     0 0   my $self = shift;
139 0           my $name = shift;
140 0           my $args = $self->makemaker_args;
141             $args->{$name} = defined $args->{$name}
142 0 0         ? join( ' ', $args->{$name}, @_ )
143             : join( ' ', @_ );
144             }
145              
146             sub build_subdirs {
147 0     0 0   my $self = shift;
148 0   0       my $subdirs = $self->makemaker_args->{DIR} ||= [];
149 0           for my $subdir (@_) {
150 0           push @$subdirs, $subdir;
151             }
152             }
153              
154             sub clean_files {
155 0     0 0   my $self = shift;
156 0   0       my $clean = $self->makemaker_args->{clean} ||= {};
157             %$clean = (
158             %$clean,
159 0   0       FILES => join ' ', grep { length $_ } ($clean->{FILES} || (), @_),
  0            
160             );
161             }
162              
163             sub realclean_files {
164 0     0 0   my $self = shift;
165 0   0       my $realclean = $self->makemaker_args->{realclean} ||= {};
166             %$realclean = (
167             %$realclean,
168 0   0       FILES => join ' ', grep { length $_ } ($realclean->{FILES} || (), @_),
  0            
169             );
170             }
171              
172             sub libs {
173 0     0 0   my $self = shift;
174 0 0         my $libs = ref $_[0] ? shift : [ shift ];
175 0           $self->makemaker_args( LIBS => $libs );
176             }
177              
178             sub inc {
179 0     0 0   my $self = shift;
180 0           $self->makemaker_args( INC => shift );
181             }
182              
183       0     sub _wanted_t {
184             }
185              
186             sub tests_recursive {
187 0     0 0   my $self = shift;
188 0   0       my $dir = shift || 't';
189 0 0         unless ( -d $dir ) {
190 0           die "tests_recursive dir '$dir' does not exist";
191             }
192 0   0       my %tests = map { $_ => 1 } split / /, ($self->tests || '');
  0            
193 0           require File::Find;
194             File::Find::find(
195 0 0 0 0     sub { /\.t$/ and -f $_ and $tests{"$File::Find::dir/*.t"} = 1 },
196 0           $dir
197             );
198 0           $self->tests( join ' ', sort keys %tests );
199             }
200              
201             sub write {
202 0     0 0   my $self = shift;
203 0 0         die "&Makefile->write() takes no arguments\n" if @_;
204              
205             # Check the current Perl version
206 0           my $perl_version = $self->perl_version;
207 0 0         if ( $perl_version ) {
208 0 0         eval "use $perl_version; 1"
209             or die "ERROR: perl: Version $] is installed, "
210             . "but we need version >= $perl_version";
211             }
212              
213             # Make sure we have a new enough MakeMaker
214 0           require ExtUtils::MakeMaker;
215              
216 0 0 0       if ( $perl_version and $self->_cmp($perl_version, '5.006') >= 0 ) {
217             # This previous attempted to inherit the version of
218             # ExtUtils::MakeMaker in use by the module author, but this
219             # was found to be untenable as some authors build releases
220             # using future dev versions of EU:MM that nobody else has.
221             # Instead, #toolchain suggests we use 6.59 which is the most
222             # stable version on CPAN at time of writing and is, to quote
223             # ribasushi, "not terminally fucked, > and tested enough".
224             # TODO: We will now need to maintain this over time to push
225             # the version up as new versions are released.
226 0           $self->build_requires( 'ExtUtils::MakeMaker' => 6.59 );
227 0           $self->configure_requires( 'ExtUtils::MakeMaker' => 6.59 );
228             } else {
229             # Allow legacy-compatibility with 5.005 by depending on the
230             # most recent EU:MM that supported 5.005.
231 0           $self->build_requires( 'ExtUtils::MakeMaker' => 6.36 );
232 0           $self->configure_requires( 'ExtUtils::MakeMaker' => 6.36 );
233             }
234              
235             # Generate the MakeMaker params
236 0           my $args = $self->makemaker_args;
237 0           $args->{DISTNAME} = $self->name;
238 0   0       $args->{NAME} = $self->module_name || $self->name;
239 0           $args->{NAME} =~ s/-/::/g;
240 0 0         $args->{VERSION} = $self->version or die <<'EOT';
241             ERROR: Can't determine distribution version. Please specify it
242             explicitly via 'version' in Makefile.PL, or set a valid $VERSION
243             in a module, and provide its file path via 'version_from' (or
244             'all_from' if you prefer) in Makefile.PL.
245             EOT
246              
247 0 0 0       if ( $self->tests ) {
    0 0        
    0          
248 0           my @tests = split ' ', $self->tests;
249 0           my %seen;
250             $args->{test} = {
251 0           TESTS => (join ' ', grep {!$seen{$_}++} @tests),
  0            
252             };
253             } elsif ( $Module::Install::ExtraTests::use_extratests ) {
254             # Module::Install::ExtraTests doesn't set $self->tests and does its own tests via harness.
255             # So, just ignore our xt tests here.
256             } elsif ( -d 'xt' and ($Module::Install::AUTHOR or $ENV{RELEASE_TESTING}) ) {
257             $args->{test} = {
258 0           TESTS => join( ' ', map { "$_/*.t" } grep { -d $_ } qw{ t xt } ),
  0            
  0            
259             };
260             }
261 0 0         if ( $] >= 5.005 ) {
262 0           $args->{ABSTRACT} = $self->abstract;
263 0 0         $args->{AUTHOR} = join ', ', @{$self->author || []};
  0            
264             }
265 0 0         if ( $self->makemaker(6.10) ) {
266 0           $args->{NO_META} = 1;
267             #$args->{NO_MYMETA} = 1;
268             }
269 0 0 0       if ( $self->makemaker(6.17) and $self->sign ) {
270 0           $args->{SIGN} = 1;
271             }
272 0 0         unless ( $self->is_admin ) {
273 0           delete $args->{SIGN};
274             }
275 0 0 0       if ( $self->makemaker(6.31) and $self->license ) {
276 0           $args->{LICENSE} = $self->license;
277             }
278              
279 0   0       my $prereq = ($args->{PREREQ_PM} ||= {});
280             %$prereq = ( %$prereq,
281 0           map { @$_ } # flatten [module => version]
282 0           map { @$_ }
  0            
283             grep $_,
284             ($self->requires)
285             );
286              
287             # Remove any reference to perl, PREREQ_PM doesn't support it
288 0           delete $args->{PREREQ_PM}->{perl};
289              
290             # Merge both kinds of requires into BUILD_REQUIRES
291 0   0       my $build_prereq = ($args->{BUILD_REQUIRES} ||= {});
292             %$build_prereq = ( %$build_prereq,
293 0           map { @$_ } # flatten [module => version]
294 0           map { @$_ }
  0            
295             grep $_,
296             ($self->configure_requires, $self->build_requires)
297             );
298              
299             # Remove any reference to perl, BUILD_REQUIRES doesn't support it
300 0           delete $args->{BUILD_REQUIRES}->{perl};
301              
302             # Delete bundled dists from prereq_pm, add it to Makefile DIR
303 0   0       my $subdirs = ($args->{DIR} || []);
304 0 0         if ($self->bundles) {
305 0           my %processed;
306 0           foreach my $bundle (@{ $self->bundles }) {
  0            
307 0           my ($mod_name, $dist_dir) = @$bundle;
308 0           delete $prereq->{$mod_name};
309 0           $dist_dir = File::Basename::basename($dist_dir); # dir for building this module
310 0 0         if (not exists $processed{$dist_dir}) {
311 0 0         if (-d $dist_dir) {
312             # List as sub-directory to be processed by make
313 0           push @$subdirs, $dist_dir;
314             }
315             # Else do nothing: the module is already present on the system
316 0           $processed{$dist_dir} = undef;
317             }
318             }
319             }
320              
321 0 0         unless ( $self->makemaker('6.55_03') ) {
322 0           %$prereq = (%$prereq,%$build_prereq);
323 0           delete $args->{BUILD_REQUIRES};
324             }
325              
326 0 0         if ( my $perl_version = $self->perl_version ) {
327 0 0         eval "use $perl_version; 1"
328             or die "ERROR: perl: Version $] is installed, "
329             . "but we need version >= $perl_version";
330              
331 0 0         if ( $self->makemaker(6.48) ) {
332 0           $args->{MIN_PERL_VERSION} = $perl_version;
333             }
334             }
335              
336 0 0         if ($self->installdirs) {
337 0 0         warn qq{old INSTALLDIRS (probably set by makemaker_args) is overriden by installdirs\n} if $args->{INSTALLDIRS};
338 0           $args->{INSTALLDIRS} = $self->installdirs;
339             }
340              
341             my %args = map {
342 0           ( $_ => $args->{$_} ) } grep {defined($args->{$_} )
  0            
  0            
343             } keys %$args;
344              
345 0           my $user_preop = delete $args{dist}->{PREOP};
346 0 0         if ( my $preop = $self->admin->preop($user_preop) ) {
347 0           foreach my $key ( keys %$preop ) {
348 0           $args{dist}->{$key} = $preop->{$key};
349             }
350             }
351              
352 0           my $mm = ExtUtils::MakeMaker::WriteMakefile(%args);
353 0   0       $self->fix_up_makefile($mm->{FIRST_MAKEFILE} || 'Makefile');
354             }
355              
356             sub fix_up_makefile {
357 0     0 0   my $self = shift;
358 0           my $makefile_name = shift;
359 0   0       my $top_class = ref($self->_top) || '';
360 0   0       my $top_version = $self->_top->VERSION || '';
361              
362 0 0         my $preamble = $self->preamble
363             ? "# Preamble by $top_class $top_version\n"
364             . $self->preamble
365             : '';
366 0   0       my $postamble = "# Postamble by $top_class $top_version\n"
367             . ($self->postamble || '');
368              
369 0           local *MAKEFILE;
370 0 0         open MAKEFILE, "+< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!";
371 0           eval { flock MAKEFILE, LOCK_EX };
  0            
372 0           my $makefile = do { local $/; };
  0            
  0            
373              
374 0           $makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /;
375 0           $makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g;
376 0           $makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g;
377 0           $makefile =~ s/^(FULLPERL = .*)/$1 "-Iinc"/m;
378 0           $makefile =~ s/^(PERL = .*)/$1 "-Iinc"/m;
379              
380             # Module::Install will never be used to build the Core Perl
381             # Sometimes PERL_LIB and PERL_ARCHLIB get written anyway, which breaks
382             # PREFIX/PERL5LIB, and thus, install_share. Blank them if they exist
383 0           $makefile =~ s/^PERL_LIB = .+/PERL_LIB =/m;
384             #$makefile =~ s/^PERL_ARCHLIB = .+/PERL_ARCHLIB =/m;
385              
386             # Perl 5.005 mentions PERL_LIB explicitly, so we have to remove that as well.
387 0           $makefile =~ s/(\"?)-I\$\(PERL_LIB\)\1//g;
388              
389             # XXX - This is currently unused; not sure if it breaks other MM-users
390             # $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg;
391              
392 0           seek MAKEFILE, 0, SEEK_SET;
393 0           truncate MAKEFILE, 0;
394 0 0         print MAKEFILE "$preamble$makefile$postamble" or die $!;
395 0 0         close MAKEFILE or die $!;
396              
397 0           1;
398             }
399              
400             sub preamble {
401 0     0 0   my ($self, $text) = @_;
402 0 0         $self->{preamble} = $text . $self->{preamble} if defined $text;
403 0           $self->{preamble};
404             }
405              
406             sub postamble {
407 0     0 0   my ($self, $text) = @_;
408 0   0       $self->{postamble} ||= $self->admin->postamble;
409 0 0         $self->{postamble} .= $text if defined $text;
410             $self->{postamble}
411 0           }
412              
413             1;
414              
415             __END__