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