reminder: update Module::CoreList when bumping version number
[p5sagit/p5-mst-13.2.git] / cpan / Module-Build / lib / Module / Build / Compat.pm
CommitLineData
bb4e9162 1package Module::Build::Compat;
2
3use strict;
4use vars qw($VERSION);
c341c67b 5$VERSION = '0.36';
bb4e9162 6
23837600 7use File::Basename ();
bb4e9162 8use File::Spec;
9use IO::File;
10use Config;
11use Module::Build;
12use Module::Build::ModuleInfo;
13use Data::Dumper;
14
738349a8 15my %convert_installdirs = (
16 PERL => 'core',
17 SITE => 'site',
18 VENDOR => 'vendor',
19);
20
53fc1c7e 21my %makefile_to_build =
bb4e9162 22 (
23 TEST_VERBOSE => 'verbose',
24 VERBINST => 'verbose',
738349a8 25 INC => sub { map {(extra_compiler_flags => $_)} Module::Build->split_like_shell(shift) },
26 POLLUTE => sub { (extra_compiler_flags => '-DPERL_POLLUTE') },
27 INSTALLDIRS => sub { (installdirs => $convert_installdirs{uc shift()}) },
28 LIB => sub {
29 my $lib = shift;
30 my %config = (
31 installprivlib => $lib,
32 installsitelib => $lib,
33 installarchlib => "$lib/$Config{archname}",
34 installsitearch => "$lib/$Config{archname}"
35 );
36 return map { (config => "$_=$config{$_}") } keys %config;
37 },
38
39 # Convert INSTALLVENDORLIB and friends.
40 (
41 map {
23837600 42 my $name = $_;
738349a8 43 $name => sub {
23837600 44 my @ret = (config => lc($name) . "=" . shift );
738349a8 45 print STDERR "# Converted to @ret\n";
46
47 return @ret;
48 }
23837600 49 } qw(
50 INSTALLARCHLIB INSTALLSITEARCH INSTALLVENDORARCH
51 INSTALLPRIVLIB INSTALLSITELIB INSTALLVENDORLIB
52 INSTALLBIN INSTALLSITEBIN INSTALLVENDORBIN
53 INSTALLSCRIPT INSTALLSITESCRIPT INSTALLVENDORSCRIPT
54 INSTALLMAN1DIR INSTALLSITEMAN1DIR INSTALLVENDORMAN1DIR
55 INSTALLMAN3DIR INSTALLSITEMAN3DIR INSTALLVENDORMAN3DIR
56 )
738349a8 57 ),
bb4e9162 58
59 # Some names they have in common
60 map {$_, lc($_)} qw(DESTDIR PREFIX INSTALL_BASE UNINST),
61 );
62
738349a8 63my %macro_to_build = %makefile_to_build;
64# "LIB=foo make" is not the same as "perl Makefile.PL LIB=foo"
65delete $macro_to_build{LIB};
bb4e9162 66
613f422f 67sub _simple_prereq {
68 return $_[0] =~ /^[0-9_]+\.?[0-9_]*$/; # crudly, a decimal literal
69}
70
71sub _merge_prereq {
72 my ($req, $breq) = @_;
73 $req ||= {};
74 $breq ||= {};
75
76 # validate formats
77 for my $p ( $req, $breq ) {
78 for my $k (keys %$p) {
79 die "Prereq '$p->{$k}' for '$k' is not supported by Module::Build::Compat\n"
80 unless _simple_prereq($p->{$k});
81 }
82 }
83 # merge
84 my $merge = { %$req };
85 for my $k ( keys %$breq ) {
86 my $v1 = $merge->{$k} || 0;
87 my $v2 = $breq->{$k};
88 $merge->{$k} = $v1 > $v2 ? $v1 : $v2;
89 }
90 return %$merge;
91}
53fc1c7e 92
93
bb4e9162 94sub create_makefile_pl {
95 my ($package, $type, $build, %args) = @_;
53fc1c7e 96
bb4e9162 97 die "Don't know how to build Makefile.PL of type '$type'"
98 unless $type =~ /^(small|passthrough|traditional)$/;
99
613f422f 100 if ($type eq 'passthrough') {
101 $build->log_warn(<<"HERE");
53fc1c7e 102
103IMPORTANT NOTE: The '$type' style of Makefile.PL is deprecated and
613f422f 104may be removed in a future version of Module::Build in favor of the
105'configure_requires' property. See Module::Build::Compat
106documentation for details.
107
108HERE
109 }
110
bb4e9162 111 my $fh;
112 if ($args{fh}) {
113 $fh = $args{fh};
114 } else {
115 $args{file} ||= 'Makefile.PL';
738349a8 116 local $build->{properties}{quiet} = 1;
117 $build->delete_filetree($args{file});
bb4e9162 118 $fh = IO::File->new("> $args{file}") or die "Can't write $args{file}: $!";
119 }
120
121 print {$fh} "# Note: this file was auto-generated by ", __PACKAGE__, " version $VERSION\n";
122
53fc1c7e 123 # Minimum perl version should be specified as "require 5.XXXXXX" in
7a827510 124 # Makefile.PL
125 my $requires = $build->requires;
126 if ( my $minimum_perl = $requires->{perl} ) {
127 print {$fh} "require $minimum_perl;\n";
128 }
129
dc8021d3 130 # If a *bundled* custom subclass is being used, make sure we add its
738349a8 131 # directory to @INC. Also, lib.pm always needs paths in Unix format.
bb4e9162 132 my $subclass_load = '';
133 if (ref($build) ne "Module::Build") {
134 my $subclass_dir = $package->subclass_dir($build);
dc8021d3 135
bb4e9162 136 if (File::Spec->file_name_is_absolute($subclass_dir)) {
137 my $base_dir = $build->base_dir;
138
139 if ($build->dir_contains($base_dir, $subclass_dir)) {
140 $subclass_dir = File::Spec->abs2rel($subclass_dir, $base_dir);
738349a8 141 $subclass_dir = $package->unixify_dir($subclass_dir);
dc8021d3 142 $subclass_load = "use lib '$subclass_dir';";
bb4e9162 143 }
738349a8 144 # Otherwise, leave it the empty string
dc8021d3 145
146 } else {
738349a8 147 $subclass_dir = $package->unixify_dir($subclass_dir);
dc8021d3 148 $subclass_load = "use lib '$subclass_dir';";
bb4e9162 149 }
bb4e9162 150 }
dc8021d3 151
bb4e9162 152 if ($type eq 'small') {
153 printf {$fh} <<'EOF', $subclass_load, ref($build), ref($build);
154 use Module::Build::Compat 0.02;
155 %s
156 Module::Build::Compat->run_build_pl(args => \@ARGV);
157 require %s;
158 Module::Build::Compat->write_makefile(build_class => '%s');
159EOF
160
161 } elsif ($type eq 'passthrough') {
162 printf {$fh} <<'EOF', $subclass_load, ref($build), ref($build);
53fc1c7e 163
bb4e9162 164 unless (eval "use Module::Build::Compat 0.02; 1" ) {
165 print "This module requires Module::Build to install itself.\n";
53fc1c7e 166
bb4e9162 167 require ExtUtils::MakeMaker;
168 my $yn = ExtUtils::MakeMaker::prompt
169 (' Install Module::Build now from CPAN?', 'y');
53fc1c7e 170
bb4e9162 171 unless ($yn =~ /^y/i) {
172 die " *** Cannot install without Module::Build. Exiting ...\n";
173 }
53fc1c7e 174
bb4e9162 175 require Cwd;
176 require File::Spec;
177 require CPAN;
53fc1c7e 178
bb4e9162 179 # Save this 'cause CPAN will chdir all over the place.
180 my $cwd = Cwd::cwd();
53fc1c7e 181
bb4e9162 182 CPAN::Shell->install('Module::Build::Compat');
47f13fd5 183 CPAN::Shell->expand("Module", "Module::Build::Compat")->uptodate
184 or die "Couldn't install Module::Build, giving up.\n";
53fc1c7e 185
bb4e9162 186 chdir $cwd or die "Cannot chdir() back to $cwd: $!";
187 }
188 eval "use Module::Build::Compat 0.02; 1" or die $@;
189 %s
190 Module::Build::Compat->run_build_pl(args => \@ARGV);
53fc1c7e 191 my $build_script = 'Build';
94410036 192 $build_script .= '.com' if $^O eq 'VMS';
193 exit(0) unless(-e $build_script); # cpantesters convention
bb4e9162 194 require %s;
195 Module::Build::Compat->write_makefile(build_class => '%s');
196EOF
53fc1c7e 197
bb4e9162 198 } elsif ($type eq 'traditional') {
199
200 my (%MM_Args, %prereq);
201 if (eval "use Tie::IxHash; 1") {
202 tie %MM_Args, 'Tie::IxHash'; # Don't care if it fails here
203 tie %prereq, 'Tie::IxHash'; # Don't care if it fails here
204 }
53fc1c7e 205
bb4e9162 206 my %name = ($build->module_name
207 ? (NAME => $build->module_name)
208 : (DISTNAME => $build->dist_name));
53fc1c7e 209
bb4e9162 210 my %version = ($build->dist_version_from
211 ? (VERSION_FROM => $build->dist_version_from)
212 : (VERSION => $build->dist_version)
213 );
214 %MM_Args = (%name, %version);
53fc1c7e 215
613f422f 216 %prereq = _merge_prereq( $build->requires, $build->build_requires );
bb4e9162 217 %prereq = map {$_, $prereq{$_}} sort keys %prereq;
53fc1c7e 218
23837600 219 delete $prereq{perl};
bb4e9162 220 $MM_Args{PREREQ_PM} = \%prereq;
53fc1c7e 221
bb4e9162 222 $MM_Args{INSTALLDIRS} = $build->installdirs eq 'core' ? 'perl' : $build->installdirs;
53fc1c7e 223
bb4e9162 224 $MM_Args{EXE_FILES} = [ sort keys %{$build->script_files} ] if $build->script_files;
53fc1c7e 225
94410036 226 $MM_Args{PL_FILES} = $build->PL_files || {};
23837600 227
228 if ($build->recursive_test_files) {
613f422f 229 $MM_Args{test} = { TESTS => join q{ }, $package->_test_globs($build) };
23837600 230 }
231
bb4e9162 232 local $Data::Dumper::Terse = 1;
233 my $args = Data::Dumper::Dumper(\%MM_Args);
234 $args =~ s/\{(.*)\}/($1)/s;
53fc1c7e 235
bb4e9162 236 print $fh <<"EOF";
237use ExtUtils::MakeMaker;
238WriteMakefile
239$args;
240EOF
241 }
242}
243
23837600 244sub _test_globs {
245 my ($self, $build) = @_;
246
247 return map { File::Spec->catfile($_, '*.t') }
248 @{$build->rscan_dir('t', sub { -d $File::Find::name })};
249}
bb4e9162 250
251sub subclass_dir {
252 my ($self, $build) = @_;
53fc1c7e 253
bb4e9162 254 return (Module::Build::ModuleInfo->find_module_dir_by_name(ref $build)
255 || File::Spec->catdir($build->config_dir, 'lib'));
256}
257
738349a8 258sub unixify_dir {
259 my ($self, $path) = @_;
260 return join '/', File::Spec->splitdir($path);
261}
262
bb4e9162 263sub makefile_to_build_args {
738349a8 264 my $class = shift;
bb4e9162 265 my @out;
266 foreach my $arg (@_) {
267 next if $arg eq '';
53fc1c7e 268
bb4e9162 269 my ($key, $val) = ($arg =~ /^(\w+)=(.+)/ ? ($1, $2) :
270 die "Malformed argument '$arg'");
271
272 # Do tilde-expansion if it looks like a tilde prefixed path
738349a8 273 ( $val ) = Module::Build->_detildefy( $val ) if $val =~ /^~/;
bb4e9162 274
275 if (exists $makefile_to_build{$key}) {
276 my $trans = $makefile_to_build{$key};
738349a8 277 push @out, $class->_argvify( ref($trans) ? $trans->($val) : ($trans => $val) );
bb4e9162 278 } elsif (exists $Config{lc($key)}) {
738349a8 279 push @out, $class->_argvify( config => lc($key) . "=$val" );
bb4e9162 280 } else {
281 # Assume M::B can handle it in lowercase form
738349a8 282 push @out, $class->_argvify("\L$key" => $val);
bb4e9162 283 }
284 }
285 return @out;
286}
287
738349a8 288sub _argvify {
289 my ($self, @pairs) = @_;
290 my @out;
291 while (@pairs) {
292 my ($k, $v) = splice @pairs, 0, 2;
293 push @out, ("--$k", $v);
294 }
295 return @out;
296}
297
bb4e9162 298sub makefile_to_build_macros {
299 my @out;
23837600 300 my %config; # must accumulate and return as a hashref
738349a8 301 while (my ($macro, $trans) = each %macro_to_build) {
bb4e9162 302 # On some platforms (e.g. Cygwin with 'make'), the mere presence
303 # of "EXPORT: FOO" in the Makefile will make $ENV{FOO} defined.
304 # Therefore we check length() too.
305 next unless exists $ENV{$macro} && length $ENV{$macro};
306 my $val = $ENV{$macro};
23837600 307 my @args = ref($trans) ? $trans->($val) : ($trans => $val);
308 while (@args) {
309 my ($k, $v) = splice(@args, 0, 2);
310 if ( $k eq 'config' ) {
311 if ( $v =~ /^([^=]+)=(.*)$/ ) {
312 $config{$1} = $2;
313 }
314 else {
315 warn "Couldn't parse config '$v'\n";
316 }
317 }
318 else {
319 push @out, ($k => $v);
320 }
321 }
bb4e9162 322 }
53fc1c7e 323 push @out, (config => \%config) if %config;
bb4e9162 324 return @out;
325}
326
327sub run_build_pl {
328 my ($pack, %in) = @_;
329 $in{script} ||= 'Build.PL';
330 my @args = $in{args} ? $pack->makefile_to_build_args(@{$in{args}}) : ();
331 print "# running $in{script} @args\n";
332 Module::Build->run_perl_script($in{script}, [], \@args) or die "Couldn't run $in{script}: $!";
333}
334
335sub fake_makefile {
336 my ($self, %args) = @_;
337 unless (exists $args{build_class}) {
338 warn "Unknown 'build_class', defaulting to 'Module::Build'\n";
339 $args{build_class} = 'Module::Build';
340 }
c1d8f74e 341 my $class = $args{build_class};
bb4e9162 342
c1d8f74e 343 my $perl = $class->find_perl_interpreter;
738349a8 344
345 # VMS MMS/MMK need to use MCR to run the Perl image.
346 $perl = 'MCR ' . $perl if $self->_is_vms_mms;
347
c1d8f74e 348 my $noop = ($class->is_windowsish ? 'rem>nul' :
738349a8 349 $self->_is_vms_mms ? 'Continue' :
bb4e9162 350 'true');
bb4e9162 351
738349a8 352 my $filetype = $class->is_vmsish ? '.COM' : '';
353
354 my $Build = 'Build' . $filetype . ' --makefile_env_macros 1';
355 my $unlink = $class->oneliner('1 while unlink $ARGV[0]', [], [$args{makefile}]);
86bddcbf 356 $unlink =~ s/\$/\$\$/g unless $class->is_vmsish;
738349a8 357
cdbde1c3 358 my $maketext = ($^O eq 'os2' ? "SHELL = sh\n\n" : '');
359
360 $maketext .= <<"EOF";
bb4e9162 361all : force_do_it
362 $perl $Build
363realclean : force_do_it
364 $perl $Build realclean
738349a8 365 $unlink
94410036 366distclean : force_do_it
367 $perl $Build distclean
368 $unlink
369
bb4e9162 370
371force_do_it :
372 @ $noop
373EOF
374
c1d8f74e 375 foreach my $action ($class->known_actions) {
94410036 376 next if $action =~ /^(all|distclean|realclean|force_do_it)$/; # Don't double-define
bb4e9162 377 $maketext .= <<"EOF";
378$action : force_do_it
379 $perl $Build $action
380EOF
381 }
53fc1c7e 382
738349a8 383 if ($self->_is_vms_mms) {
384 # Roll our own .EXPORT as MMS/MMK don't honor that directive.
53fc1c7e 385 $maketext .= "\n.FIRST\n\t\@ $noop\n";
738349a8 386 for my $macro (keys %macro_to_build) {
387 $maketext .= ".IFDEF $macro\n\tDEFINE $macro \"\$($macro)\"\n.ENDIF\n";
388 }
53fc1c7e 389 $maketext .= "\n";
738349a8 390 }
391 else {
392 $maketext .= "\n.EXPORT : " . join(' ', keys %macro_to_build) . "\n\n";
393 }
53fc1c7e 394
bb4e9162 395 return $maketext;
396}
397
398sub fake_prereqs {
399 my $file = File::Spec->catfile('_build', 'prereqs');
400 my $fh = IO::File->new("< $file") or die "Can't read $file: $!";
401 my $prereqs = eval do {local $/; <$fh>};
402 close $fh;
613f422f 403
404 my %merged = _merge_prereq( $prereqs->{requires}, $prereqs->{build_requires} );
bb4e9162 405 my @prereq;
613f422f 406 foreach (sort keys %merged) {
407 next if $_ eq 'perl';
408 push @prereq, "$_=>q[$merged{$_}]";
bb4e9162 409 }
bb4e9162 410 return unless @prereq;
411 return "# PREREQ_PM => { " . join(", ", @prereq) . " }\n\n";
412}
413
414
415sub write_makefile {
416 my ($pack, %in) = @_;
738349a8 417
418 unless (exists $in{build_class}) {
419 warn "Unknown 'build_class', defaulting to 'Module::Build'\n";
420 $in{build_class} = 'Module::Build';
421 }
422 my $class = $in{build_class};
423 $in{makefile} ||= $pack->_is_vms_mms ? 'Descrip.MMS' : 'Makefile';
424
bb4e9162 425 open MAKE, "> $in{makefile}" or die "Cannot write $in{makefile}: $!";
426 print MAKE $pack->fake_prereqs;
427 print MAKE $pack->fake_makefile(%in);
428 close MAKE;
429}
430
738349a8 431sub _is_vms_mms {
432 return Module::Build->is_vmsish && ($Config{make} =~ m/MM[SK]/i);
433}
434
bb4e9162 4351;
436__END__
437
23837600 438=for :stopwords passthrough
bb4e9162 439
440=head1 NAME
441
442Module::Build::Compat - Compatibility with ExtUtils::MakeMaker
443
444
445=head1 SYNOPSIS
446
447 # In a Build.PL :
448 use Module::Build;
449 my $build = Module::Build->new
450 ( module_name => 'Foo::Bar',
451 license => 'perl',
613f422f 452 create_makefile_pl => 'traditional' );
bb4e9162 453 ...
454
455
456=head1 DESCRIPTION
457
23837600 458Because C<ExtUtils::MakeMaker> has been the standard way to distribute
bb4e9162 459modules for a long time, many tools (CPAN.pm, or your system
23837600 460administrator) may expect to find a working F<Makefile.PL> in every
bb4e9162 461distribution they download from CPAN. If you want to throw them a
23837600 462bone, you can use C<Module::Build::Compat> to automatically generate a
463F<Makefile.PL> for you, in one of several different styles.
bb4e9162 464
23837600 465C<Module::Build::Compat> also provides some code that helps out the
466F<Makefile.PL> at runtime.
bb4e9162 467
468
469=head1 METHODS
470
471=over 4
472
473=item create_makefile_pl($style, $build)
474
23837600 475Creates a F<Makefile.PL> in the current directory in one of several
476styles, based on the supplied C<Module::Build> object C<$build>. This is
bb4e9162 477typically controlled by passing the desired style as the
23837600 478C<create_makefile_pl> parameter to C<Module::Build>'s C<new()> method;
479the F<Makefile.PL> will then be automatically created during the
bb4e9162 480C<distdir> action.
481
482The currently supported styles are:
483
484=over 4
485
613f422f 486=item traditional
487
488A F<Makefile.PL> will be created in the "traditional" style, i.e. it will
489use C<ExtUtils::MakeMaker> and won't rely on C<Module::Build> at all.
490In order to create the F<Makefile.PL>, we'll include the C<requires> and
491C<build_requires> dependencies as the C<PREREQ_PM> parameter.
492
493You don't want to use this style if during the C<perl Build.PL> stage
494you ask the user questions, or do some auto-sensing about the user's
495environment, or if you subclass C<Module::Build> to do some
496customization, because the vanilla F<Makefile.PL> won't do any of that.
497
bb4e9162 498=item small
499
23837600 500A small F<Makefile.PL> will be created that passes all functionality
501through to the F<Build.PL> script in the same directory. The user must
502already have C<Module::Build> installed in order to use this, or else
bb4e9162 503they'll get a module-not-found error.
504
613f422f 505=item passthrough (DEPRECATED)
bb4e9162 506
23837600 507This is just like the C<small> option above, but if C<Module::Build> is
bb4e9162 508not already installed on the user's system, the script will offer to
509use C<CPAN.pm> to download it and install it before continuing with
510the build.
511
613f422f 512This option has been deprecated and may be removed in a future version
513of Module::Build. Modern CPAN.pm and CPANPLUS will recognize the
514C<configure_requires> metadata property and install Module::Build before
515running Build.PL if Module::Build is listed and Module::Build now
516adds itself to configure_requires by default.
bb4e9162 517
613f422f 518Perl 5.10.1 includes C<configure_requires> support. In the future, when
519C<configure_requires> support is deemed sufficiently widespread, the
520C<passthrough> style will be removed.
bb4e9162 521
522=back
523
524=item run_build_pl(args => \@ARGV)
525
23837600 526This method runs the F<Build.PL> script, passing it any arguments the
bb4e9162 527user may have supplied to the C<perl Makefile.PL> command. Because
23837600 528C<ExtUtils::MakeMaker> and C<Module::Build> accept different arguments, this
bb4e9162 529method also performs some translation between the two.
530
531C<run_build_pl()> accepts the following named parameters:
532
533=over 4
534
535=item args
536
537The C<args> parameter specifies the parameters that would usually
538appear on the command line of the C<perl Makefile.PL> command -
539typically you'll just pass a reference to C<@ARGV>.
540
541=item script
542
543This is the filename of the script to run - it defaults to C<Build.PL>.
544
545=back
546
547=item write_makefile()
548
23837600 549This method writes a 'dummy' F<Makefile> that will pass all commands
550through to the corresponding C<Module::Build> actions.
bb4e9162 551
552C<write_makefile()> accepts the following named parameters:
553
554=over 4
555
556=item makefile
557
558The name of the file to write - defaults to the string C<Makefile>.
559
560=back
561
562=back
563
564
565=head1 SCENARIOS
566
567So, some common scenarios are:
568
569=over 4
570
571=item 1.
572
23837600 573Just include a F<Build.PL> script (without a F<Makefile.PL>
574script), and give installation directions in a F<README> or F<INSTALL>
bb4e9162 575document explaining how to install the module. In particular, explain
23837600 576that the user must install C<Module::Build> before installing your
bb4e9162 577module.
578
579Note that if you do this, you may make things easier for yourself, but
580harder for people with older versions of CPAN or CPANPLUS on their
581system, because those tools generally only understand the
582F<Makefile.PL>/C<ExtUtils::MakeMaker> way of doing things.
583
584=item 2.
585
23837600 586Include a F<Build.PL> script and a "traditional" F<Makefile.PL>,
bb4e9162 587created either manually or with C<create_makefile_pl()>. Users won't
23837600 588ever have to install C<Module::Build> if they use the F<Makefile.PL>, but
589they won't get to take advantage of C<Module::Build>'s extra features
bb4e9162 590either.
591
94410036 592For good measure, of course, test both the F<Makefile.PL> and the
bb4e9162 593F<Build.PL> before shipping.
594
595=item 3.
596
23837600 597Include a F<Build.PL> script and a "pass-through" F<Makefile.PL>
598built using C<Module::Build::Compat>. This will mean that people can
bb4e9162 599continue to use the "old" installation commands, and they may never
600notice that it's actually doing something else behind the scenes. It
601will also mean that your installation process is compatible with older
602versions of tools like CPAN and CPANPLUS.
603
604=back
605
606
607=head1 AUTHOR
608
77e96e88 609Ken Williams <kwilliams@cpan.org>
bb4e9162 610
611
612=head1 COPYRIGHT
613
77e96e88 614Copyright (c) 2001-2006 Ken Williams. All rights reserved.
bb4e9162 615
616This library is free software; you can redistribute it and/or
617modify it under the same terms as Perl itself.
618
619
620=head1 SEE ALSO
621
dc8021d3 622L<Module::Build>(3), L<ExtUtils::MakeMaker>(3)
bb4e9162 623
624
625=cut