This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
A builtin hard upper bound for sLOCALTIME_max to prevent AIX
[perl5.git] / lib / Module / Build / Compat.pm
CommitLineData
bb4e9162
YST
1package Module::Build::Compat;
2
3use strict;
4use vars qw($VERSION);
7a827510 5$VERSION = '0.2808_01';
bb4e9162
YST
6
7use File::Spec;
8use IO::File;
9use Config;
10use Module::Build;
11use Module::Build::ModuleInfo;
12use Data::Dumper;
13
14my %makefile_to_build =
15 (
16 TEST_VERBOSE => 'verbose',
17 VERBINST => 'verbose',
f943a5bf 18 INC => sub { map {('--extra_compiler_flags', $_)} Module::Build->split_like_shell(shift) },
bb4e9162
YST
19 POLLUTE => sub { ('--extra_compiler_flags', '-DPERL_POLLUTE') },
20 INSTALLDIRS => sub {local $_ = shift; 'installdirs=' . (/^perl$/ ? 'core' : $_) },
21 LIB => sub { ('--install_path', 'lib='.shift()) },
22
23 # Some names they have in common
24 map {$_, lc($_)} qw(DESTDIR PREFIX INSTALL_BASE UNINST),
25 );
26
27
28
29sub create_makefile_pl {
30 my ($package, $type, $build, %args) = @_;
31
32 die "Don't know how to build Makefile.PL of type '$type'"
33 unless $type =~ /^(small|passthrough|traditional)$/;
34
35 my $fh;
36 if ($args{fh}) {
37 $fh = $args{fh};
38 } else {
39 $args{file} ||= 'Makefile.PL';
40 $fh = IO::File->new("> $args{file}") or die "Can't write $args{file}: $!";
41 }
42
43 print {$fh} "# Note: this file was auto-generated by ", __PACKAGE__, " version $VERSION\n";
44
7a827510
RGS
45 # Minimum perl version should be specified as "require 5.XXXXXX" in
46 # Makefile.PL
47 my $requires = $build->requires;
48 if ( my $minimum_perl = $requires->{perl} ) {
49 print {$fh} "require $minimum_perl;\n";
50 }
51
dc8021d3
SP
52 # If a *bundled* custom subclass is being used, make sure we add its
53 # directory to @INC.
bb4e9162
YST
54 my $subclass_load = '';
55 if (ref($build) ne "Module::Build") {
56 my $subclass_dir = $package->subclass_dir($build);
dc8021d3 57
bb4e9162
YST
58 if (File::Spec->file_name_is_absolute($subclass_dir)) {
59 my $base_dir = $build->base_dir;
60
61 if ($build->dir_contains($base_dir, $subclass_dir)) {
62 $subclass_dir = File::Spec->abs2rel($subclass_dir, $base_dir);
dc8021d3 63 $subclass_load = "use lib '$subclass_dir';";
bb4e9162 64 }
dc8021d3
SP
65
66 } else {
67 $subclass_load = "use lib '$subclass_dir';";
bb4e9162 68 }
bb4e9162 69 }
dc8021d3 70
bb4e9162
YST
71 if ($type eq 'small') {
72 printf {$fh} <<'EOF', $subclass_load, ref($build), ref($build);
73 use Module::Build::Compat 0.02;
74 %s
75 Module::Build::Compat->run_build_pl(args => \@ARGV);
76 require %s;
77 Module::Build::Compat->write_makefile(build_class => '%s');
78EOF
79
80 } elsif ($type eq 'passthrough') {
81 printf {$fh} <<'EOF', $subclass_load, ref($build), ref($build);
82
83 unless (eval "use Module::Build::Compat 0.02; 1" ) {
84 print "This module requires Module::Build to install itself.\n";
85
86 require ExtUtils::MakeMaker;
87 my $yn = ExtUtils::MakeMaker::prompt
88 (' Install Module::Build now from CPAN?', 'y');
89
90 unless ($yn =~ /^y/i) {
91 die " *** Cannot install without Module::Build. Exiting ...\n";
92 }
93
94 require Cwd;
95 require File::Spec;
96 require CPAN;
97
98 # Save this 'cause CPAN will chdir all over the place.
99 my $cwd = Cwd::cwd();
100
bb4e9162 101 CPAN::Shell->install('Module::Build::Compat');
47f13fd5
SP
102 CPAN::Shell->expand("Module", "Module::Build::Compat")->uptodate
103 or die "Couldn't install Module::Build, giving up.\n";
bb4e9162
YST
104
105 chdir $cwd or die "Cannot chdir() back to $cwd: $!";
106 }
107 eval "use Module::Build::Compat 0.02; 1" or die $@;
108 %s
109 Module::Build::Compat->run_build_pl(args => \@ARGV);
110 require %s;
111 Module::Build::Compat->write_makefile(build_class => '%s');
112EOF
113
114 } elsif ($type eq 'traditional') {
115
116 my (%MM_Args, %prereq);
117 if (eval "use Tie::IxHash; 1") {
118 tie %MM_Args, 'Tie::IxHash'; # Don't care if it fails here
119 tie %prereq, 'Tie::IxHash'; # Don't care if it fails here
120 }
121
122 my %name = ($build->module_name
123 ? (NAME => $build->module_name)
124 : (DISTNAME => $build->dist_name));
125
126 my %version = ($build->dist_version_from
127 ? (VERSION_FROM => $build->dist_version_from)
128 : (VERSION => $build->dist_version)
129 );
130 %MM_Args = (%name, %version);
131
132 %prereq = ( %{$build->requires}, %{$build->build_requires} );
133 %prereq = map {$_, $prereq{$_}} sort keys %prereq;
134
135 delete $prereq{perl};
136 $MM_Args{PREREQ_PM} = \%prereq;
137
138 $MM_Args{INSTALLDIRS} = $build->installdirs eq 'core' ? 'perl' : $build->installdirs;
139
140 $MM_Args{EXE_FILES} = [ sort keys %{$build->script_files} ] if $build->script_files;
141
142 $MM_Args{PL_FILES} = {};
143
144 local $Data::Dumper::Terse = 1;
145 my $args = Data::Dumper::Dumper(\%MM_Args);
146 $args =~ s/\{(.*)\}/($1)/s;
147
148 print $fh <<"EOF";
149use ExtUtils::MakeMaker;
150WriteMakefile
151$args;
152EOF
153 }
154}
155
156
157sub subclass_dir {
158 my ($self, $build) = @_;
159
160 return (Module::Build::ModuleInfo->find_module_dir_by_name(ref $build)
161 || File::Spec->catdir($build->config_dir, 'lib'));
162}
163
164sub makefile_to_build_args {
165 shift;
166 my @out;
167 foreach my $arg (@_) {
168 next if $arg eq '';
169
170 my ($key, $val) = ($arg =~ /^(\w+)=(.+)/ ? ($1, $2) :
171 die "Malformed argument '$arg'");
172
173 # Do tilde-expansion if it looks like a tilde prefixed path
174 ( $val ) = glob( $val ) if $val =~ /^~/;
175
176 if (exists $makefile_to_build{$key}) {
177 my $trans = $makefile_to_build{$key};
178 push @out, ref($trans) ? $trans->($val) : ("--$trans", $val);
179 } elsif (exists $Config{lc($key)}) {
180 push @out, '--config', lc($key) . "=$val";
181 } else {
182 # Assume M::B can handle it in lowercase form
183 push @out, "--\L$key", $val;
184 }
185 }
186 return @out;
187}
188
189sub makefile_to_build_macros {
190 my @out;
191 while (my ($macro, $trans) = each %makefile_to_build) {
192 # On some platforms (e.g. Cygwin with 'make'), the mere presence
193 # of "EXPORT: FOO" in the Makefile will make $ENV{FOO} defined.
194 # Therefore we check length() too.
195 next unless exists $ENV{$macro} && length $ENV{$macro};
196 my $val = $ENV{$macro};
197 push @out, ref($trans) ? $trans->($val) : ($trans => $val);
198 }
199 return @out;
200}
201
202sub run_build_pl {
203 my ($pack, %in) = @_;
204 $in{script} ||= 'Build.PL';
205 my @args = $in{args} ? $pack->makefile_to_build_args(@{$in{args}}) : ();
206 print "# running $in{script} @args\n";
207 Module::Build->run_perl_script($in{script}, [], \@args) or die "Couldn't run $in{script}: $!";
208}
209
210sub fake_makefile {
211 my ($self, %args) = @_;
212 unless (exists $args{build_class}) {
213 warn "Unknown 'build_class', defaulting to 'Module::Build'\n";
214 $args{build_class} = 'Module::Build';
215 }
c1d8f74e 216 my $class = $args{build_class};
bb4e9162 217
c1d8f74e
SP
218 my $perl = $class->find_perl_interpreter;
219 my $noop = ($class->is_windowsish ? 'rem>nul' :
220 $class->is_vmsish ? 'Continue' :
bb4e9162
YST
221 'true');
222 my $Build = 'Build --makefile_env_macros 1';
223
224 # Start with a couple special actions
225 my $maketext = <<"EOF";
226all : force_do_it
227 $perl $Build
228realclean : force_do_it
229 $perl $Build realclean
230 $perl -e unlink -e shift $args{makefile}
231
232force_do_it :
233 @ $noop
234EOF
235
c1d8f74e 236 foreach my $action ($class->known_actions) {
bb4e9162
YST
237 next if $action =~ /^(all|realclean|force_do_it)$/; # Don't double-define
238 $maketext .= <<"EOF";
239$action : force_do_it
240 $perl $Build $action
241EOF
242 }
243
244 $maketext .= "\n.EXPORT : " . join(' ', keys %makefile_to_build) . "\n\n";
245
246 return $maketext;
247}
248
249sub fake_prereqs {
250 my $file = File::Spec->catfile('_build', 'prereqs');
251 my $fh = IO::File->new("< $file") or die "Can't read $file: $!";
252 my $prereqs = eval do {local $/; <$fh>};
253 close $fh;
254
255 my @prereq;
256 foreach my $section (qw/build_requires requires/) {
257 foreach (keys %{$prereqs->{$section}}) {
258 next if $_ eq 'perl';
259 push @prereq, "$_=>q[$prereqs->{$section}{$_}]";
260 }
261 }
262
263 return unless @prereq;
264 return "# PREREQ_PM => { " . join(", ", @prereq) . " }\n\n";
265}
266
267
268sub write_makefile {
269 my ($pack, %in) = @_;
270 $in{makefile} ||= 'Makefile';
271 open MAKE, "> $in{makefile}" or die "Cannot write $in{makefile}: $!";
272 print MAKE $pack->fake_prereqs;
273 print MAKE $pack->fake_makefile(%in);
274 close MAKE;
275}
276
2771;
278__END__
279
280
281=head1 NAME
282
283Module::Build::Compat - Compatibility with ExtUtils::MakeMaker
284
285
286=head1 SYNOPSIS
287
288 # In a Build.PL :
289 use Module::Build;
290 my $build = Module::Build->new
291 ( module_name => 'Foo::Bar',
292 license => 'perl',
293 create_makefile_pl => 'passthrough' );
294 ...
295
296
297=head1 DESCRIPTION
298
299Because ExtUtils::MakeMaker has been the standard way to distribute
300modules for a long time, many tools (CPAN.pm, or your system
301administrator) may expect to find a working Makefile.PL in every
302distribution they download from CPAN. If you want to throw them a
303bone, you can use Module::Build::Compat to automatically generate a
304Makefile.PL for you, in one of several different styles.
305
306Module::Build::Compat also provides some code that helps out the
307Makefile.PL at runtime.
308
309
310=head1 METHODS
311
312=over 4
313
314=item create_makefile_pl($style, $build)
315
316Creates a Makefile.PL in the current directory in one of several
317styles, based on the supplied Module::Build object C<$build>. This is
318typically controlled by passing the desired style as the
319C<create_makefile_pl> parameter to Module::Build's C<new()> method;
320the Makefile.PL will then be automatically created during the
321C<distdir> action.
322
323The currently supported styles are:
324
325=over 4
326
327=item small
328
329A small Makefile.PL will be created that passes all functionality
330through to the Build.PL script in the same directory. The user must
331already have Module::Build installed in order to use this, or else
332they'll get a module-not-found error.
333
334=item passthrough
335
336This is just like the C<small> option above, but if Module::Build is
337not already installed on the user's system, the script will offer to
338use C<CPAN.pm> to download it and install it before continuing with
339the build.
340
341=item traditional
342
343A Makefile.PL will be created in the "traditional" style, i.e. it will
344use C<ExtUtils::MakeMaker> and won't rely on C<Module::Build> at all.
345In order to create the Makefile.PL, we'll include the C<requires> and
346C<build_requires> dependencies as the C<PREREQ_PM> parameter.
347
348You don't want to use this style if during the C<perl Build.PL> stage
349you ask the user questions, or do some auto-sensing about the user's
350environment, or if you subclass Module::Build to do some
351customization, because the vanilla Makefile.PL won't do any of that.
352
353=back
354
355=item run_build_pl(args => \@ARGV)
356
357This method runs the Build.PL script, passing it any arguments the
358user may have supplied to the C<perl Makefile.PL> command. Because
359ExtUtils::MakeMaker and Module::Build accept different arguments, this
360method also performs some translation between the two.
361
362C<run_build_pl()> accepts the following named parameters:
363
364=over 4
365
366=item args
367
368The C<args> parameter specifies the parameters that would usually
369appear on the command line of the C<perl Makefile.PL> command -
370typically you'll just pass a reference to C<@ARGV>.
371
372=item script
373
374This is the filename of the script to run - it defaults to C<Build.PL>.
375
376=back
377
378=item write_makefile()
379
380This method writes a 'dummy' Makefile that will pass all commands
381through to the corresponding Module::Build actions.
382
383C<write_makefile()> accepts the following named parameters:
384
385=over 4
386
387=item makefile
388
389The name of the file to write - defaults to the string C<Makefile>.
390
391=back
392
393=back
394
395
396=head1 SCENARIOS
397
398So, some common scenarios are:
399
400=over 4
401
402=item 1.
403
404Just include a Build.PL script (without a Makefile.PL
405script), and give installation directions in a README or INSTALL
406document explaining how to install the module. In particular, explain
407that the user must install Module::Build before installing your
408module.
409
410Note that if you do this, you may make things easier for yourself, but
411harder for people with older versions of CPAN or CPANPLUS on their
412system, because those tools generally only understand the
413F<Makefile.PL>/C<ExtUtils::MakeMaker> way of doing things.
414
415=item 2.
416
417Include a Build.PL script and a "traditional" Makefile.PL,
418created either manually or with C<create_makefile_pl()>. Users won't
419ever have to install Module::Build if they use the Makefile.PL, but
420they won't get to take advantage of Module::Build's extra features
421either.
422
423If you go this route, make sure you explicitly set C<PL_FILES> in the
424call to C<WriteMakefile()> (probably to an empty hash reference), or
425else MakeMaker will mistakenly run the Build.PL and you'll get an
426error message about "Too early to run Build script" or something. For
427good measure, of course, test both the F<Makefile.PL> and the
428F<Build.PL> before shipping.
429
430=item 3.
431
432Include a Build.PL script and a "pass-through" Makefile.PL
433built using Module::Build::Compat. This will mean that people can
434continue to use the "old" installation commands, and they may never
435notice that it's actually doing something else behind the scenes. It
436will also mean that your installation process is compatible with older
437versions of tools like CPAN and CPANPLUS.
438
439=back
440
441
442=head1 AUTHOR
443
77e96e88 444Ken Williams <kwilliams@cpan.org>
bb4e9162
YST
445
446
447=head1 COPYRIGHT
448
77e96e88 449Copyright (c) 2001-2006 Ken Williams. All rights reserved.
bb4e9162
YST
450
451This library is free software; you can redistribute it and/or
452modify it under the same terms as Perl itself.
453
454
455=head1 SEE ALSO
456
dc8021d3 457L<Module::Build>(3), L<ExtUtils::MakeMaker>(3)
bb4e9162
YST
458
459
460=cut