Commit | Line | Data |
bb4e9162 |
1 | package Module::Build::Compat; |
2 | |
3 | use strict; |
4 | use vars qw($VERSION); |
15cb7b9d |
5 | $VERSION = '0.31012'; |
bb4e9162 |
6 | |
7 | use File::Spec; |
8 | use IO::File; |
9 | use Config; |
10 | use Module::Build; |
11 | use Module::Build::ModuleInfo; |
12 | use Data::Dumper; |
13 | |
738349a8 |
14 | my %convert_installdirs = ( |
15 | PERL => 'core', |
16 | SITE => 'site', |
17 | VENDOR => 'vendor', |
18 | ); |
19 | |
bb4e9162 |
20 | my %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 |
55 | my %macro_to_build = %makefile_to_build; |
56 | # "LIB=foo make" is not the same as "perl Makefile.PL LIB=foo" |
57 | delete $macro_to_build{LIB}; |
bb4e9162 |
58 | |
59 | |
60 | sub 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'); |
114 | EOF |
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'); |
148 | EOF |
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 | |
15cb7b9d |
178 | $MM_Args{PL_FILES} = $build->PL_files if $build->PL_files; |
bb4e9162 |
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"; |
185 | use ExtUtils::MakeMaker; |
186 | WriteMakefile |
187 | $args; |
188 | EOF |
189 | } |
190 | } |
191 | |
192 | |
193 | sub 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 |
200 | sub unixify_dir { |
201 | my ($self, $path) = @_; |
202 | return join '/', File::Spec->splitdir($path); |
203 | } |
204 | |
bb4e9162 |
205 | sub 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 |
230 | sub _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 |
240 | sub 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 | |
253 | sub 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 | |
261 | sub 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"; |
285 | all : force_do_it |
286 | $perl $Build |
287 | realclean : force_do_it |
288 | $perl $Build realclean |
738349a8 |
289 | $unlink |
bb4e9162 |
290 | |
291 | force_do_it : |
292 | @ $noop |
293 | EOF |
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 |
300 | EOF |
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 | |
318 | sub 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 | |
337 | sub 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 |
353 | sub _is_vms_mms { |
354 | return Module::Build->is_vmsish && ($Config{make} =~ m/MM[SK]/i); |
355 | } |
356 | |
bb4e9162 |
357 | 1; |
358 | __END__ |
359 | |
360 | |
361 | =head1 NAME |
362 | |
363 | Module::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 | |
379 | Because ExtUtils::MakeMaker has been the standard way to distribute |
380 | modules for a long time, many tools (CPAN.pm, or your system |
381 | administrator) may expect to find a working Makefile.PL in every |
382 | distribution they download from CPAN. If you want to throw them a |
383 | bone, you can use Module::Build::Compat to automatically generate a |
384 | Makefile.PL for you, in one of several different styles. |
385 | |
386 | Module::Build::Compat also provides some code that helps out the |
387 | Makefile.PL at runtime. |
388 | |
389 | |
390 | =head1 METHODS |
391 | |
392 | =over 4 |
393 | |
394 | =item create_makefile_pl($style, $build) |
395 | |
396 | Creates a Makefile.PL in the current directory in one of several |
397 | styles, based on the supplied Module::Build object C<$build>. This is |
398 | typically controlled by passing the desired style as the |
399 | C<create_makefile_pl> parameter to Module::Build's C<new()> method; |
400 | the Makefile.PL will then be automatically created during the |
401 | C<distdir> action. |
402 | |
403 | The currently supported styles are: |
404 | |
405 | =over 4 |
406 | |
407 | =item small |
408 | |
409 | A small Makefile.PL will be created that passes all functionality |
410 | through to the Build.PL script in the same directory. The user must |
411 | already have Module::Build installed in order to use this, or else |
412 | they'll get a module-not-found error. |
413 | |
414 | =item passthrough |
415 | |
416 | This is just like the C<small> option above, but if Module::Build is |
417 | not already installed on the user's system, the script will offer to |
418 | use C<CPAN.pm> to download it and install it before continuing with |
419 | the build. |
420 | |
421 | =item traditional |
422 | |
423 | A Makefile.PL will be created in the "traditional" style, i.e. it will |
424 | use C<ExtUtils::MakeMaker> and won't rely on C<Module::Build> at all. |
425 | In order to create the Makefile.PL, we'll include the C<requires> and |
426 | C<build_requires> dependencies as the C<PREREQ_PM> parameter. |
427 | |
428 | You don't want to use this style if during the C<perl Build.PL> stage |
429 | you ask the user questions, or do some auto-sensing about the user's |
430 | environment, or if you subclass Module::Build to do some |
431 | customization, because the vanilla Makefile.PL won't do any of that. |
432 | |
433 | =back |
434 | |
435 | =item run_build_pl(args => \@ARGV) |
436 | |
437 | This method runs the Build.PL script, passing it any arguments the |
438 | user may have supplied to the C<perl Makefile.PL> command. Because |
439 | ExtUtils::MakeMaker and Module::Build accept different arguments, this |
440 | method also performs some translation between the two. |
441 | |
442 | C<run_build_pl()> accepts the following named parameters: |
443 | |
444 | =over 4 |
445 | |
446 | =item args |
447 | |
448 | The C<args> parameter specifies the parameters that would usually |
449 | appear on the command line of the C<perl Makefile.PL> command - |
450 | typically you'll just pass a reference to C<@ARGV>. |
451 | |
452 | =item script |
453 | |
454 | This is the filename of the script to run - it defaults to C<Build.PL>. |
455 | |
456 | =back |
457 | |
458 | =item write_makefile() |
459 | |
460 | This method writes a 'dummy' Makefile that will pass all commands |
461 | through to the corresponding Module::Build actions. |
462 | |
463 | C<write_makefile()> accepts the following named parameters: |
464 | |
465 | =over 4 |
466 | |
467 | =item makefile |
468 | |
469 | The name of the file to write - defaults to the string C<Makefile>. |
470 | |
471 | =back |
472 | |
473 | =back |
474 | |
475 | |
476 | =head1 SCENARIOS |
477 | |
478 | So, some common scenarios are: |
479 | |
480 | =over 4 |
481 | |
482 | =item 1. |
483 | |
484 | Just include a Build.PL script (without a Makefile.PL |
485 | script), and give installation directions in a README or INSTALL |
486 | document explaining how to install the module. In particular, explain |
487 | that the user must install Module::Build before installing your |
488 | module. |
489 | |
490 | Note that if you do this, you may make things easier for yourself, but |
491 | harder for people with older versions of CPAN or CPANPLUS on their |
492 | system, because those tools generally only understand the |
493 | F<Makefile.PL>/C<ExtUtils::MakeMaker> way of doing things. |
494 | |
495 | =item 2. |
496 | |
497 | Include a Build.PL script and a "traditional" Makefile.PL, |
498 | created either manually or with C<create_makefile_pl()>. Users won't |
499 | ever have to install Module::Build if they use the Makefile.PL, but |
500 | they won't get to take advantage of Module::Build's extra features |
501 | either. |
502 | |
503 | If you go this route, make sure you explicitly set C<PL_FILES> in the |
504 | call to C<WriteMakefile()> (probably to an empty hash reference), or |
505 | else MakeMaker will mistakenly run the Build.PL and you'll get an |
506 | error message about "Too early to run Build script" or something. For |
507 | good measure, of course, test both the F<Makefile.PL> and the |
508 | F<Build.PL> before shipping. |
509 | |
510 | =item 3. |
511 | |
512 | Include a Build.PL script and a "pass-through" Makefile.PL |
513 | built using Module::Build::Compat. This will mean that people can |
514 | continue to use the "old" installation commands, and they may never |
515 | notice that it's actually doing something else behind the scenes. It |
516 | will also mean that your installation process is compatible with older |
517 | versions of tools like CPAN and CPANPLUS. |
518 | |
519 | =back |
520 | |
521 | |
522 | =head1 AUTHOR |
523 | |
77e96e88 |
524 | Ken Williams <kwilliams@cpan.org> |
bb4e9162 |
525 | |
526 | |
527 | =head1 COPYRIGHT |
528 | |
77e96e88 |
529 | Copyright (c) 2001-2006 Ken Williams. All rights reserved. |
bb4e9162 |
530 | |
531 | This library is free software; you can redistribute it and/or |
532 | modify it under the same terms as Perl itself. |
533 | |
534 | |
535 | =head1 SEE ALSO |
536 | |
dc8021d3 |
537 | L<Module::Build>(3), L<ExtUtils::MakeMaker>(3) |
bb4e9162 |
538 | |
539 | |
540 | =cut |